diff options
author | Guillaume Martres <smarter@ubuntu.com> | 2016-02-24 23:53:35 +0100 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2016-02-28 20:08:59 +0100 |
commit | 7e7ee820df7647680d9aaf1ca991fe9718159097 (patch) | |
tree | 26095cec3a83fc12984e745e459dcb3d0996d045 /interfaces/src/main/java/dotty/tools/dotc/interfaces | |
parent | 94b41d5c491878543288af1bedb4daf57226ca07 (diff) | |
download | dotty-7e7ee820df7647680d9aaf1ca991fe9718159097.tar.gz dotty-7e7ee820df7647680d9aaf1ca991fe9718159097.tar.bz2 dotty-7e7ee820df7647680d9aaf1ca991fe9718159097.zip |
Add a `dotty-interfaces` package
We introduce a new entry point for the compiler in
`dotty.tools.dotc.Driver`:
```
def process(args: Array[String], simple: interfaces.SimpleReporter,
callback: interfaces.CompilerCallback): interfaces.ReporterResult
```
Except for `args` which is just an array, the argument types and return
type of this method are Java interfaces defined in a new package called
`dotty-interfaces` which has a stable ABI. This means that you can
programmatically run a compiler with a custom reporter and callbacks
without having to recompile it against every version of dotty: you only
need to have `dotty-interfaces` present at compile-time and call the
`process` method using Java reflection.
See `test/test/InterfaceEntryPointTest.scala` for a concrete example.
This design is based on discussions with the IntelliJ IDEA Scala plugin
team. Thanks to Nikolay Tropin for the discussions and his PR
proposal (see #1011).
Diffstat (limited to 'interfaces/src/main/java/dotty/tools/dotc/interfaces')
7 files changed, 166 insertions, 0 deletions
diff --git a/interfaces/src/main/java/dotty/tools/dotc/interfaces/AbstractFile.java b/interfaces/src/main/java/dotty/tools/dotc/interfaces/AbstractFile.java new file mode 100644 index 000000000..a1b9cc5c7 --- /dev/null +++ b/interfaces/src/main/java/dotty/tools/dotc/interfaces/AbstractFile.java @@ -0,0 +1,24 @@ +package dotty.tools.dotc.interfaces; + +import java.io.File; +import java.util.Optional; + +/** An abstract file may either be a file on disk or a virtual file. + * + * Do not rely on the identity of instances of this class. + * + * User code should not implement this interface, but it may have to + * manipulate objects of this type. + */ +public interface AbstractFile { + /** The name of this file, note that two files may have the same name. */ + String name(); + + /** The path of this file, this might be a virtual path of an unspecified format. */ + String path(); + + /** If this is a real file on disk, a `java.io.File` that corresponds to this file. + * Otherwise, an empty `Optional`. + */ + Optional<File> jfile(); +} diff --git a/interfaces/src/main/java/dotty/tools/dotc/interfaces/CompilerCallback.java b/interfaces/src/main/java/dotty/tools/dotc/interfaces/CompilerCallback.java new file mode 100644 index 000000000..17d2f6bbd --- /dev/null +++ b/interfaces/src/main/java/dotty/tools/dotc/interfaces/CompilerCallback.java @@ -0,0 +1,28 @@ +package dotty.tools.dotc.interfaces; + +/** Set of callbacks called in response to events during the compilation process. + * + * You should implement this interface if you want to react to one or more of + * these events. + * + * @see the method `process` of `dotty.tools.dotc.Driver` for more information. + */ +public interface CompilerCallback { + /** Called when a class has been generated. + * + * @param source The source file corresponding to this class. + * Example: ./src/library/scala/collection/Seq.scala + * @param generatedClass The generated classfile for this class. + * Example: ./scala/collection/Seq$.class + * @param className The name of this class. + * Example: scala.collection.Seq$ + */ + default void onClassGenerated(SourceFile source, AbstractFile generatedClass, String className) {}; + + /** Called when every class for this file has been generated. + * + * @param source The source file. + * Example: ./src/library/scala/collection/Seq.scala + */ + default void onSourceCompiled(SourceFile source) {}; +} diff --git a/interfaces/src/main/java/dotty/tools/dotc/interfaces/Diagnostic.java b/interfaces/src/main/java/dotty/tools/dotc/interfaces/Diagnostic.java new file mode 100644 index 000000000..436f9f8ea --- /dev/null +++ b/interfaces/src/main/java/dotty/tools/dotc/interfaces/Diagnostic.java @@ -0,0 +1,26 @@ +package dotty.tools.dotc.interfaces; + +import java.util.Optional; + +/** A diagnostic is a message emitted during the compilation process. + * + * It can either be an error, a warning or an information. + * + * User code should not implement this interface, but it may have to + * manipulate objects of this type. + */ +public interface Diagnostic { + public static final int ERROR = 2; + public static final int WARNING = 1; + public static final int INFO = 0; + + /** The message to report */ + String message(); + + /** Level of the diagnostic, can be either ERROR, WARNING or INFO */ + int level(); + + /** The position in a source file of the code that caused this diagnostic + * to be emitted. */ + Optional<SourcePosition> position(); +} diff --git a/interfaces/src/main/java/dotty/tools/dotc/interfaces/ReporterResult.java b/interfaces/src/main/java/dotty/tools/dotc/interfaces/ReporterResult.java new file mode 100644 index 000000000..63c5104df --- /dev/null +++ b/interfaces/src/main/java/dotty/tools/dotc/interfaces/ReporterResult.java @@ -0,0 +1,18 @@ +package dotty.tools.dotc.interfaces; + +/** Summary of the diagnostics emitted by a Reporter. + * + * User code should not implement this interface, but it may have to + * manipulate objects of this type. + */ +public interface ReporterResult { + /** Have we emitted any error ? */ + boolean hasErrors(); + /** Number of errors that have been emitted */ + int errorCount(); + + /** Have we emitted any warning ? */ + boolean hasWarnings(); + /** Number of warnings that have been emitted */ + int warningCount(); +} diff --git a/interfaces/src/main/java/dotty/tools/dotc/interfaces/SimpleReporter.java b/interfaces/src/main/java/dotty/tools/dotc/interfaces/SimpleReporter.java new file mode 100644 index 000000000..e52537096 --- /dev/null +++ b/interfaces/src/main/java/dotty/tools/dotc/interfaces/SimpleReporter.java @@ -0,0 +1,13 @@ +package dotty.tools.dotc.interfaces; + +/** Report errors, warnings and info messages during the compilation process + * + * You should implement this interface if you want to handle the diagnostics + * returned by the compiler yourself. + * + * @see the method `process` of `dotty.tools.dotc.Driver` for more information. + */ +public interface SimpleReporter { + /** Report a diagnostic. */ + void report(Diagnostic diag); +} diff --git a/interfaces/src/main/java/dotty/tools/dotc/interfaces/SourceFile.java b/interfaces/src/main/java/dotty/tools/dotc/interfaces/SourceFile.java new file mode 100644 index 000000000..5611d3885 --- /dev/null +++ b/interfaces/src/main/java/dotty/tools/dotc/interfaces/SourceFile.java @@ -0,0 +1,13 @@ +package dotty.tools.dotc.interfaces; + +import java.io.File; + +/** A source file. + * + * User code should not implement this interface, but it may have to + * manipulate objects of this type. + */ +public interface SourceFile extends AbstractFile { + /** The content of this file as seen by the compiler. */ + char[] content(); +} diff --git a/interfaces/src/main/java/dotty/tools/dotc/interfaces/SourcePosition.java b/interfaces/src/main/java/dotty/tools/dotc/interfaces/SourcePosition.java new file mode 100644 index 000000000..c9b42d4ad --- /dev/null +++ b/interfaces/src/main/java/dotty/tools/dotc/interfaces/SourcePosition.java @@ -0,0 +1,44 @@ +package dotty.tools.dotc.interfaces; + +/** A position in a source file. + * + * A position is a range between a start offset and an end offset, as well as a + * point inside this range. + * + * As a convenience, we also provide methods that return the line and the column + * corresponding to each offset. + * + * User code should not implement this interface, but it may have to + * manipulate objects of this type. + */ +public interface SourcePosition { + /** Content of the line which contains the point */ + String lineContent(); + + /** Offset to the point */ + int point(); + /** Line number of the point, starting at 0 */ + int line(); + /** Column number of the point, starting at 0 */ + int column(); + + /** Offset to the range start */ + int start(); + /** Line number of the range start, starting at 0 */ + int startLine(); + /** Column number of the range start, starting at 0 */ + int startColumn(); + + /** Offset to the range end */ + int end(); + /** Line number of the range end, starting at 0 */ + int endLine(); + /** Column number of the range end, starting at 0 */ + int endColumn(); + + /** The source file corresponding to this position. + * The values returned by `point()`, `start()` and `end()` + * are indices in the array returned by `source().content()`. + */ + SourceFile source(); +} |