Skip to content

Commit

Permalink
Reluctantly restore compatibility of xsbti.*
Browse files Browse the repository at this point in the history
Fixes #779

As it stands, compiler-interface and compiler bridge implementation are of internal concern of Zinc implementation. We _should_ be able to remove method or change the signatures. The word "interface" here is between Scalac and Zinc internal, not to the world.

In reality, the situation is more complicated because we have Dotty compiler out there that is bound to a specific version of compiler-interface. So when I released sbt 1.4.0-M1 this resulted in NoSuchMethodErrors:

```
[error] ## Exception when compiling 1 sources to /private/tmp/hello-dotty/target/scala-0.24/classes
[error] java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
[error] xsbt.CompilerInterface.newCompiler(CompilerInterface.java:35)
....
[error] Caused by: java.lang.NoSuchMethodError: xsbti.compile.SingleOutput.getOutputDirectory()Ljava/io/File;
[error]   at xsbt.CachedCompilerImpl.<init>(CachedCompilerImpl.java:35)
```

To smooth things out, one approach we've discussed is to create a separate compiler-interface (in a different package) that is less dependent on Zinc specifics. Related to that, in #661 I've created Java interface for `CompilerInterface1`, and we can use pattern matching to see which capability the compiler bridge implementation supports. This commit brings in those Java interfaces as well.

In any case, this commit brings back the old `java.io.File`-based methods, and locally I was able to get hello world from Dotty.
  • Loading branch information
eed3si9n committed Jul 14, 2020
1 parent 95f16c8 commit b4df9a3
Show file tree
Hide file tree
Showing 38 changed files with 690 additions and 217 deletions.
18 changes: 11 additions & 7 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@ lazy val zincCompileCore = (projectMatrix in internalPath / "zinc-compile-core")
)
.settings(
name := "zinc Compile Core",
libraryDependencies ++= (scalaVersion.value match {
case v if v.startsWith("2.12.") => List(compilerPlugin(silencerPlugin))
case _ => List()
}),
libraryDependencies ++= Seq(
scalaCompiler.value % Test,
launcherInterface,
Expand Down Expand Up @@ -407,18 +411,18 @@ lazy val compilerInterface = (projectMatrix in internalPath / "compiler-interfac
mimaSettings,
mimaBinaryIssueFilters ++= Seq(
// 1.4.0 changed to VirtualFile. These should be internal to Zinc.
exclude[Problem]("xsbti.AnalysisCallback.*"),
exclude[ReversedMissingMethodProblem]("xsbti.AnalysisCallback.*"),
exclude[Problem]("xsbti.compile.PerClasspathEntryLookup.*"),
exclude[Problem]("xsbti.compile.ExternalHooks*"),
exclude[Problem]("xsbti.compile.FileHash.*"),
exclude[Problem]("xsbti.compile.Output.*"),
exclude[Problem]("xsbti.compile.OutputGroup.*"),
exclude[Problem]("xsbti.compile.SingleOutput.*"),
exclude[Problem]("xsbti.compile.MultipleOutput.*"),
exclude[Problem]("xsbti.compile.CachedCompiler.*"),
exclude[ReversedMissingMethodProblem]("xsbti.compile.Output.*"),
exclude[ReversedMissingMethodProblem]("xsbti.compile.OutputGroup.*"),
exclude[ReversedMissingMethodProblem]("xsbti.compile.SingleOutput.*"),
exclude[ReversedMissingMethodProblem]("xsbti.compile.MultipleOutput.*"),
exclude[ReversedMissingMethodProblem]("xsbti.compile.CachedCompiler.*"),
exclude[Problem]("xsbti.compile.ClassFileManager.*"),
exclude[Problem]("xsbti.compile.WrappedClassFileManager.*"),
exclude[Problem]("xsbti.compile.DependencyChanges.*"),
exclude[ReversedMissingMethodProblem]("xsbti.compile.DependencyChanges.*"),
exclude[Problem]("xsbti.compile.ScalaCompiler.*"),
exclude[Problem]("xsbti.compile.JavaTool.*"),
exclude[Problem]("xsbti.compile.JavaTool.*"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ package inc
import java.io.File
import java.net.URLClassLoader
import java.nio.file.{ Files, Path, Paths }
import java.util.Optional

import sbt.internal.inc.classpath.ClassLoaderCache
import sbt.io.IO
import sbt.io.syntax._
import xsbti.compile._
import sbt.util.Logger
import xsbti.TestCallback.ExtractedClassDependencies
import xsbti.{ TestCallback, UseScope, VirtualFile, VirtualFileRef }
import xsbti.{ ReporterUtil, TestCallback, UseScope, VirtualFile, VirtualFileRef }
import xsbti.api.ClassLike
import xsbti.api.DependencyContext._

Expand Down Expand Up @@ -199,18 +200,25 @@ trait CompilingSpecification extends BridgeProviderSpecification {
val cp = (si.allJars ++ Array(targetDir)).map(_.toPath).map(converter.toVirtualFile)
val emptyChanges: DependencyChanges = new DependencyChanges {
override val modifiedLibraries = new Array[VirtualFileRef](0)
override val modifiedBinaries = new Array[File](0)
override val modifiedClasses = new Array[String](0)
override def isEmpty = true
}
sc.apply(
val compArgs = new CompilerArguments(si, sc.classpathOptions)
val arguments = compArgs.makeArguments(Nil, cp, Nil)
val basicReporterConfig = ReporterUtil.getDefaultReporterConfig()
val reporterConfig = basicReporterConfig.withMaximumErrors(maxErrors)
val reporter = ReporterManager.getReporter(log, reporterConfig)
sc.compile(
sources = sources,
converter = converter,
changes = emptyChanges,
classpath = cp,
singleOutput = targetDir.toPath,
options = Array(),
options = arguments.toArray,
output = CompileOutput(targetDir.toPath),
callback = analysisCallback,
maximumErrors = maxErrors,
reporter = reporter,
cache = cache,
progressOpt = Optional.empty[CompileProgress],
log = log
)
srcFiles
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ sealed abstract class CallbackGlobal(

lazy val outputDirs: Iterable[Path] = {
output match {
case single: SingleOutput => List(single.getOutputDirectory)
case single: SingleOutput => List(single.getOutputDirectoryAsPath)
// Use Stream instead of List because Analyzer maps intensively over the directories
case multi: MultipleOutput => multi.getOutputGroups.toStream map (_.getOutputDirectory)
case multi: MultipleOutput => multi.getOutputGroups.toStream map (_.getOutputDirectoryAsPath)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ import scala.reflect.io.AbstractFile
import Log.debug
import java.io.File

final class CompilerInterface {
def newCompiler(
final class CompilerInterface extends CompilerInterface2 {
override def newCompiler(
options: Array[String],
output: Output,
initialLog: Logger,
initialDelegate: Reporter
): CachedCompiler =
): CachedCompiler2 =
new CachedCompiler0(options, output, new WeakLog(initialLog, initialDelegate))

def run(
override def run(
sources: Array[VirtualFile],
changes: DependencyChanges,
callback: AnalysisCallback,
Expand Down Expand Up @@ -63,7 +63,7 @@ private final class WeakLog(private[this] var log: Logger, private[this] var del
}

private final class CachedCompiler0(args: Array[String], output: Output, initialLog: WeakLog)
extends CachedCompiler
extends CachedCompiler2
with CachedCompilerCompat
with java.io.Closeable {

Expand All @@ -77,11 +77,11 @@ private final class CachedCompiler0(args: Array[String], output: Output, initial
for (out <- multi.getOutputGroups)
settings.outputDirs
.add(
out.getSourceDirectory.toAbsolutePath.toString,
out.getOutputDirectory.toAbsolutePath.toString
out.getSourceDirectoryAsPath.toAbsolutePath.toString,
out.getOutputDirectoryAsPath.toAbsolutePath.toString
)
case single: SingleOutput =>
val outputFilepath = single.getOutputDirectory.toAbsolutePath
val outputFilepath = single.getOutputDirectoryAsPath.toAbsolutePath
settings.outputDirs.setSingleOutput(outputFilepath.toString)
}

Expand Down Expand Up @@ -115,7 +115,17 @@ private final class CachedCompiler0(args: Array[String], output: Output, initial
def infoOnCachedCompiler(compilerId: String): String =
s"[zinc] Running cached compiler $compilerId for Scala compiler $versionString"

def run(
// This is kept for compatibility purpose only.
override def run(
sources: Array[File],
changes: DependencyChanges,
callback: AnalysisCallback,
log: Logger,
delegate: Reporter,
progress: CompileProgress
): Unit = ???

override def run(
sources: Array[VirtualFile],
changes: DependencyChanges,
callback: AnalysisCallback,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import xsbti.{ Logger, VirtualFile }
import scala.reflect.io.AbstractFile
import Log.debug

class ScaladocInterface {
class ScaladocInterface extends xsbti.compile.ScaladocInterface2 {
def run(sources: Array[VirtualFile], args: Array[String], log: Logger, delegate: xsbti.Reporter) =
(new Runner(sources, args, log, delegate)).run
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
import java.util.EnumSet;

public interface AnalysisCallback {

/**
* This is kept around for sbt-dotty.
* @deprecated Use @link{#startSource(VirtualFile)} instead.
*/
@Deprecated
void startSource(File source);

/**
* Set the source file mapped to a concrete {@link AnalysisCallback}.
* @param source Source file mapped to this instance of {@link AnalysisCallback}.
Expand Down Expand Up @@ -45,6 +53,17 @@ void classDependency(String onClassName,
String sourceClassName,
DependencyContext context);

/**
* This is kept around for sbt-dotty.
* @deprecated Use @link{#binaryDependency(Path, String, String, VirtualFileRef, DependencyContext)} instead.
*/
@Deprecated
void binaryDependency(File onBinaryEntry,
String onBinaryClassName,
String fromClassName,
File fromSourceFile,
DependencyContext context);

/**
* Indicate that the class <code>fromClassName</code> depends on a class
* named <code>onBinaryClassName</code> coming from class file or jar
Expand Down Expand Up @@ -77,6 +96,15 @@ void binaryDependency(Path onBinaryEntry,
VirtualFileRef fromSourceFile,
DependencyContext context);

/**
* This is kept around for sbt-dotty.
* @deprecated Use @link{#generatedNonLocalClass(VirtualFileRef, Path, String, String)} instead.
*/
@Deprecated
void generatedNonLocalClass(File source,
File classFile,
String binaryClassName,
String srcClassName);
/**
* Map the source class name (<code>srcClassName</code>) of a top-level
* Scala class coming from a given source file to a binary class name
Expand All @@ -99,6 +127,13 @@ void generatedNonLocalClass(VirtualFileRef source,
String binaryClassName,
String srcClassName);

/**
* This is kept around for sbt-dotty.
* @deprecated Use @link{#generatedLocalClass(VirtualFileRef, Path)} instead.
*/
@Deprecated
void generatedLocalClass(File source, File classFile);

/**
* Map the product relation between <code>classFile</code> and
* <code>source</code> to indicate that <code>classFile</code> is the
Expand All @@ -109,6 +144,13 @@ void generatedNonLocalClass(VirtualFileRef source,
*/
void generatedLocalClass(VirtualFileRef source, Path classFile);

/**
* This is kept around for sbt-dotty.
* @deprecated Use @link{#api(VirtualFileRef, xsbti.api.ClassLike)} instead.
*/
@Deprecated
void api(File sourceFile, xsbti.api.ClassLike classApi);

/**
* Register a public API entry coming from a given source file.
*
Expand All @@ -117,6 +159,13 @@ void generatedNonLocalClass(VirtualFileRef source,
*/
void api(VirtualFileRef sourceFile, xsbti.api.ClassLike classApi);

/**
* This is kept around for sbt-dotty.
* @deprecated Use @link{#mainClass(VirtualFileRef, String)} instead.
*/
@Deprecated
void mainClass(File sourceFile, String className);

/**
* Register a class containing an entry point coming from a given source file.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,39 @@
*
*/
public interface CachedCompiler {
/**
* Return an array of arguments that represent a command-line like
* equivalent of a call to the Scala compiler, but without the command itself.
*
* @param sources The source files that the compiler must compile.
*
* @return The array of arguments of the Scala compiler.
*/
String[] commandArguments(File[] sources);
/**
* * Return an array of arguments that represent a command-line like
* equivalent of a call to the Scala compiler, but without the command itself.
*
* @param sources The source files that the compiler must compile.
*
* @return The array of arguments of the Scala compiler.
*/
String[] commandArguments(File[] sources);

/**
* Run the cached Scala compiler with inputs of incremental compilation.
*
* @param sources The source files to be compiled.
* @param changes The changes that have occurred since last compilation.
* @param callback The callback injected by the incremental compiler.
* @param logger The logger of the incremental compilation.
* @param delegate The reporter that informs on the compiler's output.
* @param progress The compiler progress associated with a Scala compiler.
*/
void run(VirtualFile[] sources, DependencyChanges changes, AnalysisCallback callback, Logger logger, Reporter delegate, CompileProgress progress);
/**
* Run the cached Scala compiler with inputs of incremental compilation.
*
* @param sources The source files to be compiled.
* @param changes The changes that have occurred since last compilation.
* @param callback The callback injected by the incremental compiler.
* @param logger The logger of the incremental compilation.
* @param delegate The reporter that informs on the compiler's output.
* @param progress The compiler progress associated with a Scala compiler.
* @deprecated Use run with VirtualFile instead.
*/
@Deprecated
void run(File[] sources, DependencyChanges changes, AnalysisCallback callback, Logger logger, Reporter delegate, CompileProgress progress);

/**
* Run the cached Scala compiler with inputs of incremental compilation.
*
* @param sources The source files to be compiled.
* @param changes The changes that have occurred since last compilation.
* @param callback The callback injected by the incremental compiler.
* @param logger The logger of the incremental compilation.
* @param delegate The reporter that informs on the compiler's output.
* @param progress The compiler progress associated with a Scala compiler.
*/
void run(VirtualFile[] sources, DependencyChanges changes, AnalysisCallback callback, Logger logger, Reporter delegate, CompileProgress progress);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Zinc - The incremental compiler for Scala.
* Copyright Lightbend, Inc. and Mark Harrah
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package xsbti.compile;

import xsbti.AnalysisCallback;
import xsbti.Logger;
import xsbti.Reporter;
import xsbti.VirtualFile;
import java.io.File;

/**
* Define the interface of a cached Scala compiler that can be run.
*
* This cached compiler hides the implementation of a compiler by just
* defining two operations: {@link #commandArguments(File[])} and
*
*/
public interface CachedCompiler2 extends CachedCompiler {
/**
* Run the cached Scala compiler with inputs of incremental compilation.
*
* @param sources The source files to be compiled.
* @param changes The changes that have occurred since last compilation.
* @param callback The callback injected by the incremental compiler.
* @param logger The logger of the incremental compilation.
* @param delegate The reporter that informs on the compiler's output.
* @param progress The compiler progress associated with a Scala compiler.
*/
void run(VirtualFile[] sources, DependencyChanges changes, AnalysisCallback callback, Logger logger, Reporter delegate, CompileProgress progress);
}

Loading

0 comments on commit b4df9a3

Please sign in to comment.