Skip to content

Add a dotty-interfaces package #1125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 28, 2016
Merged

Conversation

smarter
Copy link
Member

@smarter smarter commented Feb 24, 2016

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).

Review by @sjrd
/cc @niktrop

- Rename Diagnostic#msg to message, this is nicer for a public API
- Rename SourceFile#lineContents and SourcePosition#lineContents
  to lineContent, the former is not grammatically correct.
- Add some convenience methods to SourcePosition.

/** 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JavaDoc style is different than Scaladoc. See http://www.oracle.com/technetwork/articles/java/index-137868.html#format
It should therefore be:

/**
 * Set of callbacks ...
 *
 * You should ...
 * ...
 */

(same everywhere there are JavaDocs, obviously.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not against changing it, but isn't it nicer to keep the style consistent across Dotty? javadoc seems to interpret this style correctly so I don't see any downside.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have any strong feelings either way. We can keep it like this.

@sjrd
Copy link
Member

sjrd commented Feb 25, 2016

What command tests InterfaceEntryPointTest and OtherEntryPointsTest?

@sjrd
Copy link
Member

sjrd commented Feb 25, 2016

That's all.

@@ -0,0 +1,19 @@
package dotty.tools.dotc.interfaces;

import java.io.File;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import is unused.

@smarter
Copy link
Member Author

smarter commented Feb 25, 2016

What command tests InterfaceEntryPointTest and OtherEntryPointsTest?

It will be run by partest (as well as test), you can run just one of these test classes with
test-only test.InterfaceEntryPointTest (you can run a single test method with
test-only -- --tests=runCompilerWithContext)

@sjrd
Copy link
Member

sjrd commented Feb 25, 2016

It will be run by partest (as well as test)

OK.

@niktrop
Copy link
Contributor

niktrop commented Feb 25, 2016

I run dotty compiler from IDEA with this version of dotty interface. We can make a build of scala plugin with Dotty compiler as soon as you merge this PR and publish jars.

@smarter
Copy link
Member Author

smarter commented Feb 25, 2016

@niktrop : Cool! Note that since this is very experimental we might have to break the ABI, I think that's okay until we have a real release of Dotty.

@smarter
Copy link
Member Author

smarter commented Feb 25, 2016

@sjrd: what do you think of adding an AbstractFile interface?

public interface AbstractFile {
  String name();
  String path();
  Optional<File> file();
}

and we would change the SourceFile interface to inherit from that:

public interface SourceFile extends AbstractFile {
  /** The content of this file as seen by the compiler. */
  char[] content();
}

Then we could have:

default void onClassGenerated(SourceFile source, AbstractFile generatedClass, String className) {};

@sjrd
Copy link
Member

sjrd commented Feb 25, 2016

Yes, good idea.

@smarter
Copy link
Member Author

smarter commented Feb 26, 2016

Hmm, but I can't do that without changing the definition of scala.reflect.io.AbstractFile to inherit from that interface, we could do this in our scalac fork but that doesn't seem like a good idea. Alternatively I could wrap a scala.reflect.io.AbstractFile into a dotty.tools.dotc.interfaces.AbstractFile everytime we call a callback method:

def wrapAbstractFile(absfile: AbstractFile) = new interfaces.AbstractFile {
  def name = absfile.name
  def path = absfile.path
  def file = if (absfile.file != null) Optional.of(absfile.file) else Optional.none
}

What do you think?

@sjrd
Copy link
Member

sjrd commented Feb 27, 2016

Yes, you'll probably have to wrap. You'll lose identity, though, which should be documented (like "Do not rely on the identity of AbstractFiles")

@odersky
Copy link
Contributor

odersky commented Feb 27, 2016

We already use an AbstractFile abstraction, the one reflect.io. SourceFile
contains an AbstractFile rather than inheriting from it (either way works
OK IMO. I believe we should make a new one only if we are sure that we
cannot use the reflect.io one for some reason.

  • Martin

On Thu, Feb 25, 2016 at 6:42 PM, Guillaume Martres <[email protected]

wrote:

@sjrd https://github.com/sjrd: what do you think of adding an
AbstractFile interface?

public interface AbstractFile {
String name();
String path();
Optional file();
}

and we would change the SourceFile interface to inherit from that:

public interface SourceFile extends AbstractFile {
/** The content of this file as seen by the compiler. */
char[] content();
}

Then we could have:

default void onClassGenerated(SourceFile source, AbstractFile generatedClass, String className) {};


Reply to this email directly or view it on GitHub
#1125 (comment).

Martin Odersky
EPFL

@sjrd
Copy link
Member

sjrd commented Feb 27, 2016

if we are sure that we cannot use the reflect.io one for some reason.

The reflect.io one is tight to a Scala binary version. This interfaces package is pure-Java, so that it is not affected by any binary compatibility issue.

@odersky
Copy link
Contributor

odersky commented Feb 27, 2016

Ah, yes, that is a good enough reason, I think.

On Sat, Feb 27, 2016 at 2:24 PM, Sébastien Doeraene <
[email protected]> wrote:

if we are sure that we cannot use the reflect.io one for some reason.

The reflect.io one is tight to a Scala binary version. This interfaces
package is pure-Java, so that it is not affected by any binary
compatibility issue.


Reply to this email directly or view it on GitHub
#1125 (comment).

Martin Odersky
EPFL

@smarter
Copy link
Member Author

smarter commented Feb 28, 2016

@sjrd AbstractFile interfaces added, I find CompilerCallback clearer than CompilerListener so I'm not motivated to rename it :).

@sjrd
Copy link
Member

sjrd commented Feb 28, 2016

LGTM

I find CompilerCallback clearer than CompilerListener so I'm not motivated to rename it :).

Fair enough.

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 scala#1011).
smarter added a commit that referenced this pull request Feb 28, 2016
@smarter smarter merged commit ba67e55 into scala:master Feb 28, 2016
@allanrenucci allanrenucci deleted the add/interface branch December 14, 2017 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants