Skip to content

Commit 013ed36

Browse files
committed
[sbt-bridge] Upgrade to CompilerInterface2
1 parent 0096b3f commit 013ed36

18 files changed

+450
-180
lines changed

compiler/src/dotty/tools/dotc/Driver.scala

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@ import core.Contexts._
99
import core.{MacroClassLoader, Mode, TypeError}
1010
import core.StdNames.nme
1111
import dotty.tools.dotc.ast.Positioned
12-
import dotty.tools.io.File
12+
import dotty.tools.io.{File, AbstractFile}
1313
import reporting._
1414
import core.Decorators._
1515
import config.Feature
16+
import util.SourceFile
1617

1718
import scala.util.control.NonFatal
1819
import fromtasty.{TASTYCompiler, TastyFileUtil}
@@ -31,35 +32,48 @@ class Driver {
3132

3233
protected def emptyReporter: Reporter = new StoreReporter(null)
3334

34-
protected def doCompile(compiler: Compiler, fileNames: List[String])(using Context): Reporter =
35-
if (fileNames.nonEmpty)
35+
protected def doCompile(compiler: Compiler, fileNames: List[String])(using ctx: Context): Reporter =
36+
if fileNames.nonEmpty then
3637
try
3738
val run = compiler.newRun
3839
run.compile(fileNames)
39-
40-
def finish(run: Run)(using Context): Unit =
41-
run.printSummary()
42-
if !ctx.reporter.errorsReported && run.suspendedUnits.nonEmpty then
43-
val suspendedUnits = run.suspendedUnits.toList
44-
if (ctx.settings.XprintSuspension.value)
45-
report.echo(i"compiling suspended $suspendedUnits%, %")
46-
val run1 = compiler.newRun
47-
for unit <- suspendedUnits do unit.suspended = false
48-
run1.compileUnits(suspendedUnits)
49-
finish(run1)(using MacroClassLoader.init(ctx.fresh))
50-
51-
finish(run)
40+
finish(compiler, run)
5241
catch
53-
case ex: FatalError =>
42+
case ex: FatalError =>
5443
report.error(ex.getMessage) // signals that we should fail compilation.
5544
case ex: TypeError =>
5645
println(s"${ex.toMessage} while compiling ${fileNames.mkString(", ")}")
57-
throw ex
5846
case ex: Throwable =>
5947
println(s"$ex while compiling ${fileNames.mkString(", ")}")
6048
throw ex
6149
ctx.reporter
62-
end doCompile
50+
51+
protected def doCompileFiles(compiler: Compiler, files: List[AbstractFile])(using Context): Reporter =
52+
if files.nonEmpty then
53+
try
54+
val run = compiler.newRun
55+
run.compileFiles(files)
56+
finish(compiler, run)
57+
catch
58+
case ex: FatalError =>
59+
report.error(ex.getMessage) // signals that we should fail compilation.
60+
case ex: TypeError =>
61+
println(s"${ex.toMessage} while compiling ${files.map(_.path).mkString(", ")}")
62+
case ex: Throwable =>
63+
println(s"$ex while compiling ${files.map(_.path).mkString(", ")}")
64+
throw ex
65+
ctx.reporter
66+
67+
protected def finish(compiler: Compiler, run: Run)(using Context): Unit =
68+
run.printSummary()
69+
if !ctx.reporter.errorsReported && run.suspendedUnits.nonEmpty then
70+
val suspendedUnits = run.suspendedUnits.toList
71+
if (ctx.settings.XprintSuspension.value)
72+
report.echo(i"compiling suspended $suspendedUnits%, %")
73+
val run1 = compiler.newRun
74+
for unit <- suspendedUnits do unit.suspended = false
75+
run1.compileUnits(suspendedUnits)
76+
finish(compiler, run1)(using MacroClassLoader.init(ctx.fresh))
6377

6478
protected def initCtx: Context = (new ContextBase).initialCtx
6579

compiler/src/dotty/tools/dotc/Run.scala

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,13 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
124124
/** Actions that need to be performed at the end of the current compilation run */
125125
private var finalizeActions = mutable.ListBuffer[() => Unit]()
126126

127-
def compile(fileNames: List[String]): Unit = try {
127+
def compile(fileNames: List[String]): Unit =
128128
val sources = fileNames.map(runContext.getSource(_))
129129
compileSources(sources)
130-
}
131-
catch {
132-
case NonFatal(ex) =>
133-
if units != null then report.echo(i"exception occurred while compiling $units%, %")
134-
else report.echo(s"exception occurred while compiling ${fileNames.mkString(", ")}")
135-
throw ex
136-
}
130+
131+
def compileFiles(files: List[AbstractFile]): Unit =
132+
val sources = files.map(runContext.getSource(_))
133+
compileSources(sources)
137134

138135
/** TODO: There's a fundamental design problem here: We assemble phases using `fusePhases`
139136
* when we first build the compiler. But we modify them with -Yskip, -Ystop
@@ -142,10 +139,15 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
142139
* account. I think the latter would be preferable.
143140
*/
144141
def compileSources(sources: List[SourceFile]): Unit =
145-
if (sources forall (_.exists)) {
146-
units = sources.map(CompilationUnit(_))
147-
compileUnits()
148-
}
142+
try
143+
if sources forall (_.exists) then
144+
units = sources.map(CompilationUnit(_))
145+
compileUnits()
146+
catch
147+
case NonFatal(ex) =>
148+
if units != null then report.echo(i"exception occurred while compiling $units%, %")
149+
else report.echo(s"exception occurred while compiling ${sources.map(_.name).mkString(", ")}")
150+
throw ex
149151

150152
def compileUnits(us: List[CompilationUnit]): Unit = {
151153
units = us

compiler/src/dotty/tools/dotc/config/CompilerCommand.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ object CompilerCommand {
3333

3434
def versionMsg: String = s"Scala compiler $versionString -- $copyrightString"
3535

36+
def shouldStopWithInfo(using ctx: Context) = {
37+
val settings = ctx.settings
38+
import settings._
39+
Set(help, Xhelp, Yhelp, showPlugins, XshowPhases) exists (_.value)
40+
}
41+
3642
/** Distill arguments into summary detailing settings, errors and files to compiler */
3743
def distill(args: Array[String])(using Context): ArgsSummary = {
3844
/**
@@ -110,11 +116,6 @@ object CompilerCommand {
110116
def xusageMessage = createUsageMsg("Possible advanced", shouldExplain = true, isAdvanced)
111117
def yusageMessage = createUsageMsg("Possible private", shouldExplain = true, isPrivate)
112118

113-
def shouldStopWithInfo = {
114-
import settings._
115-
Set(help, Xhelp, Yhelp, showPlugins, XshowPhases) exists (_.value)
116-
}
117-
118119
def phasesMessage: String = {
119120
(new Compiler()).phases.map {
120121
case List(single) => single.phaseName

project/Build.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ object Build {
490490
// get libraries onboard
491491
libraryDependencies ++= Seq(
492492
"org.scala-lang.modules" % "scala-asm" % "7.3.1-scala-1", // used by the backend
493-
Dependencies.`compiler-interface`,
493+
Dependencies.oldCompilerInterface, // we stick to the old version to avoid deprecation warnings
494494
"org.jline" % "jline-reader" % "3.15.0", // used by the REPL
495495
"org.jline" % "jline-terminal" % "3.15.0",
496496
"org.jline" % "jline-terminal-jna" % "3.15.0" // needed for Windows
@@ -947,12 +947,14 @@ object Build {
947947
sources in Test := Seq(),
948948
scalaSource in Compile := baseDirectory.value,
949949
javaSource in Compile := baseDirectory.value,
950+
resourceDirectory in Compile := baseDirectory.value.getParentFile / "resources",
950951

951952
// Referring to the other project using a string avoids an infinite loop
952953
// when sbt reads the settings.
953954
test in Test := (test in (LocalProject("scala3-sbt-bridge-tests"), Test)).value,
954955

955-
libraryDependencies += Dependencies.`compiler-interface` % Provided
956+
// The `newCompilerInterface` is backward compatible with the `oldCompilerInterface`
957+
libraryDependencies += Dependencies.newCompilerInterface % Provided
956958
)
957959

958960
// We use a separate project for the bridge tests since they can only be run
@@ -967,8 +969,7 @@ object Build {
967969

968970
// Tests disabled until zinc-api-info cross-compiles with 2.13,
969971
// alternatively we could just copy in sources the part of zinc-api-info we need.
970-
sources in Test := Seq(),
971-
// libraryDependencies += (Dependencies.`zinc-api-info` % Test).withDottyCompat(scalaVersion.value)
972+
sources in Test := Seq()
972973
)
973974

974975
lazy val `scala3-language-server` = project.in(file("language-server")).
@@ -1233,7 +1234,7 @@ object Build {
12331234
// Keep in sync with inject-sbt-dotty.sbt
12341235
libraryDependencies ++= Seq(
12351236
Dependencies.`jackson-databind`,
1236-
Dependencies.`compiler-interface`
1237+
Dependencies.newCompilerInterface
12371238
),
12381239
unmanagedSourceDirectories in Compile +=
12391240
baseDirectory.value / "../language-server/src/dotty/tools/languageserver/config",

project/Dependencies.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ object Dependencies {
1010
val `jackson-dataformat-yaml` =
1111
"com.fasterxml.jackson.dataformat" % "jackson-dataformat-yaml" % jacksonVersion
1212

13-
private val zincVersion = "1.2.5"
14-
val `compiler-interface` = "org.scala-sbt" % "compiler-interface" % zincVersion
15-
val `zinc-api-info` = "org.scala-sbt" %% "zinc-apiinfo" % zincVersion
13+
val newCompilerInterface = "org.scala-sbt" % "compiler-interface" % "1.4.3"
14+
val oldCompilerInterface = "org.scala-sbt" % "compiler-interface" % "1.3.5"
1615
}

project/build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ unmanagedSourceDirectories in Compile += baseDirectory.value / "../sbt-dotty/src
1010
// Keep in sync with `sbt-dotty` config in Build.scala
1111
libraryDependencies ++= Seq(
1212
Dependencies.`jackson-databind`,
13-
Dependencies.`compiler-interface`
13+
Dependencies.newCompilerInterface
1414
)
1515
unmanagedSourceDirectories in Compile +=
1616
baseDirectory.value / "../language-server/src/dotty/tools/languageserver/config"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
xsbt.CompilerBridge
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Zinc - The incremental compiler for Scala.
3+
* Copyright Lightbend, Inc. and Mark Harrah
4+
*/
5+
6+
package xsbt;
7+
8+
import dotty.tools.io.AbstractFile;
9+
import xsbti.PathBasedFile;
10+
import xsbti.VirtualFile;
11+
12+
import java.io.IOException;
13+
14+
interface AbstractZincFile {
15+
String id();
16+
17+
static AbstractFile of(VirtualFile virtualFile) {
18+
if (virtualFile instanceof PathBasedFile)
19+
return new ZincPlainFile((PathBasedFile) virtualFile);
20+
21+
try {
22+
return new ZincVirtualFile(virtualFile);
23+
} catch (IOException e) {
24+
throw new IllegalArgumentException("invalid file " + virtualFile.name(), e);
25+
}
26+
}
27+
}

sbt-bridge/src/xsbt/CachedCompilerImpl.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,28 @@
33
*/
44
package xsbt;
55

6-
import xsbti.AnalysisCallback;
7-
import xsbti.Logger;
8-
import xsbti.Reporter;
9-
import xsbti.Severity;
6+
import xsbti.*;
107
import xsbti.compile.*;
118

129
import java.io.File;
1310

1411
import dotty.tools.dotc.core.Contexts.Context;
1512
import dotty.tools.dotc.core.Contexts.ContextBase;
1613
import dotty.tools.dotc.Main;
17-
import dotty.tools.dotc.interfaces.*;
18-
19-
import java.net.URLClassLoader;
2014

2115
public class CachedCompilerImpl implements CachedCompiler {
2216
private final String[] args;
23-
private final Output output;
2417
private final String[] outputArgs;
2518

2619
public CachedCompilerImpl(String[] args, Output output) {
2720
super();
2821
this.args = args;
29-
this.output = output;
3022

3123
if (!(output instanceof SingleOutput))
3224
throw new IllegalArgumentException("output should be a SingleOutput, was a " + output.getClass().getName());
3325

3426
this.outputArgs =
35-
new String[] { "-d", ((SingleOutput) output).getOutputDirectory().getAbsolutePath().toString() };
27+
new String[] { "-d", ((SingleOutput) output).getOutputDirectory().getAbsolutePath() };
3628
}
3729

3830
public String[] commandArguments(File[] sources) {
@@ -54,7 +46,8 @@ public String[] commandArguments(File[] sources) {
5446
return result;
5547
}
5648

57-
synchronized public void run(File[] sources, DependencyChanges changes, AnalysisCallback callback, Logger log, Reporter delegate, CompileProgress progress) {
49+
synchronized public void run(File[] sources, DependencyChanges changes, AnalysisCallback callback, Logger log,
50+
Reporter delegate, CompileProgress progress) {
5851
log.debug(() -> {
5952
String msg = "Calling Dotty compiler with arguments (CompilerInterface):";
6053
for (String arg : args)
@@ -68,7 +61,7 @@ synchronized public void run(File[] sources, DependencyChanges changes, Analysis
6861

6962
dotty.tools.dotc.reporting.Reporter reporter = Main.process(commandArguments(sources), ctx);
7063
if (reporter.hasErrors()) {
71-
throw new InterfaceCompileFailed(args, new Problem[0]);
64+
throw new InterfaceCompileFailed(args, new Problem[0], "Compilation failed");
7265
}
7366
}
7467
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Zinc - The incremental compiler for Scala.
3+
* Copyright Lightbend, Inc. and Mark Harrah
4+
*/
5+
6+
package xsbt;
7+
8+
import dotty.tools.dotc.Driver;
9+
import xsbti.AnalysisCallback;
10+
import xsbti.Logger;
11+
import xsbti.Reporter;
12+
import xsbti.VirtualFile;
13+
import xsbti.compile.CompileProgress;
14+
import xsbti.compile.CompilerInterface2;
15+
import xsbti.compile.DependencyChanges;
16+
import xsbti.compile.Output;
17+
18+
public final class CompilerBridge extends Driver implements CompilerInterface2 {
19+
@Override
20+
public void run(VirtualFile[] sources, DependencyChanges changes, String[] options, Output output,
21+
AnalysisCallback callback, Reporter delegate, CompileProgress progress, Logger log) {
22+
CompilerBridgeDriver driver = new CompilerBridgeDriver(options, output);
23+
driver.run(sources, callback, log, delegate);
24+
}
25+
}

0 commit comments

Comments
 (0)