Skip to content

Commit 3c62b96

Browse files
authored
Merge pull request #5596 from dotty-staging/sbt-bridge-in-java
Translate the sbt-bridge to Java.
2 parents af9264d + 6da66c2 commit 3c62b96

20 files changed

+653
-464
lines changed

build.sbt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ val `dotty-compiler-bootstrapped` = Build.`dotty-compiler-bootstrapped`
88
val `dotty-library` = Build.`dotty-library`
99
val `dotty-library-bootstrapped` = Build.`dotty-library-bootstrapped`
1010
val `dotty-sbt-bridge` = Build.`dotty-sbt-bridge`
11-
val `dotty-sbt-bridge-bootstrapped` = Build.`dotty-sbt-bridge-bootstrapped`
1211
val `dotty-language-server` = Build.`dotty-language-server`
1312
val `dotty-bench` = Build.`dotty-bench`
1413
val `dotty-bench-bootstrapped` = Build.`dotty-bench-bootstrapped`
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package dotty.tools
2+
package dotc
3+
package reporting
4+
5+
/**
6+
* This class mixes in a few standard traits, so that it is easier to extend from Java.
7+
*/
8+
abstract class AbstractReporter extends Reporter with UniqueMessagePositions with HideNonSensicalMessages with MessageRendering

compiler/src/dotty/tools/dotc/reporting/ConsoleReporter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import diagnostic.messages.{ Error, ConditionalWarning }
1313
class ConsoleReporter(
1414
reader: BufferedReader = Console.in,
1515
writer: PrintWriter = new PrintWriter(Console.err, true)
16-
) extends Reporter with UniqueMessagePositions with HideNonSensicalMessages with MessageRendering {
16+
) extends AbstractReporter {
1717

1818
import MessageContainer._
1919

project/Build.scala

Lines changed: 26 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ object Build {
134134
"-language:existentials,higherKinds,implicitConversions"
135135
),
136136

137-
javacOptions ++= Seq("-Xlint:unchecked", "-Xlint:deprecation"),
137+
javacOptions in (Compile, compile) ++= Seq("-Xlint:unchecked", "-Xlint:deprecation"),
138138

139139
// Change this to true if you want to bootstrap using a published non-bootstrapped compiler
140140
bootstrapFromPublishedJars := false,
@@ -209,10 +209,14 @@ object Build {
209209
testOptions in Test += Tests.Argument(TestFrameworks.JUnit, "-a", "-v")
210210
)
211211

212-
// Settings used for projects compiled only with Scala 2
213-
lazy val commonScala2Settings = commonSettings ++ Seq(
212+
// Settings used for projects compiled only with Java
213+
lazy val commonJavaSettings = commonSettings ++ Seq(
214214
version := dottyVersion,
215-
scalaVersion := scalacVersion
215+
scalaVersion := scalacVersion,
216+
// Do not append Scala versions to the generated artifacts
217+
crossPaths := false,
218+
// Do not depend on the Scala library
219+
autoScalaLibrary := false
216220
)
217221

218222
// Settings used when compiling dotty using Scala 2
@@ -226,17 +230,9 @@ object Build {
226230
version := dottyVersion,
227231
scalaVersion := dottyNonBootstrappedVersion,
228232

229-
// Avoid having to run `dotty-sbt-bridge/publishLocal` before compiling a bootstrapped project
230-
scalaCompilerBridgeSource :=
231-
(dottyOrganization %% "dotty-sbt-bridge" % dottyVersion)
232-
.artifacts(Artifact.sources("dotty-sbt-bridge").withUrl(
233-
// We cannot use the `packageSrc` task because a setting cannot depend
234-
// on a task. Instead, we make `compile` below depend on the bridge `packageSrc`
235-
Some((artifactPath in (`dotty-sbt-bridge`, Compile, packageSrc)).value.toURI.toURL))),
236-
compile in Compile := (compile in Compile)
237-
.dependsOn(packageSrc in (`dotty-sbt-bridge`, Compile))
238-
.dependsOn(compile in (`dotty-sbt-bridge`, Compile))
239-
.value,
233+
scalaCompilerBridgeBinaryJar := {
234+
Some((packageBin in (`dotty-sbt-bridge`, Compile)).value)
235+
},
240236

241237
// Use the same name as the non-bootstrapped projects for the artifacts
242238
moduleName ~= { _.stripSuffix("-bootstrapped") },
@@ -359,13 +355,6 @@ object Build {
359355
// currently refers to dotty in its scripted task and "aggregate" does not take by-name
360356
// parameters: https://github.com/sbt/sbt/issues/2200
361357
lazy val dottySbtBridgeRef = LocalProject("dotty-sbt-bridge")
362-
// Same thing for the bootstrapped version
363-
lazy val dottySbtBridgeBootstrappedRef = LocalProject("dotty-sbt-bridge-bootstrapped")
364-
365-
def dottySbtBridgeReference(implicit mode: Mode): LocalProject = mode match {
366-
case NonBootstrapped => dottySbtBridgeRef
367-
case _ => dottySbtBridgeBootstrappedRef
368-
}
369358

370359
// The root project:
371360
// - aggregates other projects so that "compile", "test", etc are run on all projects at once.
@@ -375,15 +364,7 @@ object Build {
375364
lazy val `dotty-bootstrapped` = project.asDottyRoot(Bootstrapped)
376365

377366
lazy val `dotty-interfaces` = project.in(file("interfaces")).
378-
settings(commonScala2Settings). // Java-only project, so this is fine
379-
settings(
380-
// Do not append Scala versions to the generated artifacts
381-
crossPaths := false,
382-
// Do not depend on the Scala library
383-
autoScalaLibrary := false,
384-
//Remove javac invalid options in Compile doc
385-
javacOptions in (Compile, doc) --= Seq("-Xlint:unchecked", "-Xlint:deprecation")
386-
)
367+
settings(commonJavaSettings)
387368

388369
private lazy val dottydocClasspath = Def.task {
389370
val jars = (packageAll in `dotty-compiler`).value
@@ -798,67 +779,19 @@ object Build {
798779
case Bootstrapped => `dotty-library-bootstrapped`
799780
}
800781

801-
// until sbt/sbt#2402 is fixed (https://github.com/sbt/sbt/issues/2402)
802-
lazy val cleanSbtBridge = TaskKey[Unit]("cleanSbtBridge", "delete dotty-sbt-bridge cache")
803-
804-
def cleanSbtBridgeImpl(): Unit = {
805-
val home = System.getProperty("user.home")
806-
val sbtOrg = "org.scala-sbt"
807-
val bridgePattern = s"*dotty-sbt-bridge*$dottyVersion*"
808-
809-
IO.delete((file(home) / ".sbt" / "1.0" / "zinc" / sbtOrg * bridgePattern).get)
810-
IO.delete((file(home) / ".sbt" / "boot" * "scala-*" / sbtOrg / "sbt" * "*" * bridgePattern).get)
811-
}
812-
813-
lazy val dottySbtBridgeSettings = Seq(
814-
cleanSbtBridge := {
815-
cleanSbtBridgeImpl()
816-
},
817-
compile in Compile := {
818-
val log = streams.value.log
819-
val prev = (previousCompile in Compile).value.analysis.orElse(null)
820-
val cur = (compile in Compile).value
821-
if (prev != cur) {
822-
log.info("Cleaning the dotty-sbt-bridge cache because it was recompiled.")
823-
cleanSbtBridgeImpl()
824-
}
825-
cur
826-
},
827-
description := "sbt compiler bridge for Dotty",
828-
resolvers += Resolver.typesafeIvyRepo("releases"), // For org.scala-sbt:api
829-
libraryDependencies ++= Seq(
830-
Dependencies.`compiler-interface` % Provided,
831-
(Dependencies.`zinc-api-info` % Test).withDottyCompat(scalaVersion.value)
832-
),
833-
// The sources should be published with crossPaths := false since they
834-
// need to be compiled by the project using the bridge.
835-
crossPaths := false,
836-
837-
// Don't publish any binaries for the bridge because of the above
838-
publishArtifact in (Compile, packageBin) := false,
839-
840-
fork in Test := true,
841-
parallelExecution in Test := false
842-
)
782+
lazy val `dotty-sbt-bridge` = project.in(file("sbt-bridge")).
783+
dependsOn(dottyCompiler(NonBootstrapped) % Provided).
784+
dependsOn(dottyDoc(NonBootstrapped) % Provided).
785+
settings(commonJavaSettings).
786+
settings(
787+
description := "sbt compiler bridge for Dotty",
788+
libraryDependencies ++= Seq(
789+
Dependencies.`compiler-interface` % Provided,
790+
(Dependencies.`zinc-api-info` % Test).withDottyCompat(scalaVersion.value)
791+
),
843792

844-
lazy val `dotty-sbt-bridge` = project.in(file("sbt-bridge")).asDottySbtBridge(NonBootstrapped)
845-
lazy val `dotty-sbt-bridge-bootstrapped` = project.in(file("sbt-bridge")).asDottySbtBridge(Bootstrapped)
846-
.settings(
847-
// Tweak -Yscala2-unpickler to allow some sbt dependencies used in tests
848-
/*
849-
scalacOptions in Test := {
850-
val oldOptions = (scalacOptions in Test).value
851-
val i = oldOptions.indexOf("-Yscala2-unpickler")
852-
assert(i != -1)
853-
val oldValue = oldOptions(i + 1)
854-
855-
val attList = (dependencyClasspath in Test).value
856-
val sbtIo = findLib(attList, "org.scala-sbt/io")
857-
val zincApiInfo = findLib(attList, "zinc-apiinfo")
858-
859-
oldOptions.updated(i + 1, s"$sbtIo:$zincApiInfo:$oldValue")
860-
}
861-
*/
793+
fork in Test := true,
794+
parallelExecution in Test := false
862795
)
863796

864797
lazy val `dotty-language-server` = project.in(file("language-server")).
@@ -1017,7 +950,7 @@ object Build {
1017950
scriptedLaunchOpts ++= ivyPaths.value.ivyHome.map("-Dsbt.ivy.home=" + _.getAbsolutePath).toList,
1018951
scriptedBufferLog := true,
1019952
scripted := scripted.dependsOn(
1020-
publishLocal in `dotty-sbt-bridge-bootstrapped`,
953+
publishLocal in `dotty-sbt-bridge`,
1021954
publishLocal in `dotty-interfaces`,
1022955
publishLocal in `dotty-compiler-bootstrapped`,
1023956
publishLocal in `dotty-library-bootstrapped`,
@@ -1285,7 +1218,7 @@ object Build {
12851218

12861219
// FIXME: we do not aggregate `bin` because its tests delete jars, thus breaking other tests
12871220
def asDottyRoot(implicit mode: Mode): Project = project.withCommonSettings.
1288-
aggregate(`dotty-interfaces`, dottyLibrary, dottyCompiler, dottyDoc, dottySbtBridgeReference).
1221+
aggregate(`dotty-interfaces`, dottyLibrary, dottyCompiler, dottyDoc, `dotty-sbt-bridge`).
12891222
bootstrappedAggregate(`scala-library`, `scala-compiler`, `scala-reflect`, scalap, `dotty-language-server`).
12901223
dependsOn(dottyCompiler).
12911224
dependsOn(dottyLibrary).
@@ -1309,11 +1242,6 @@ object Build {
13091242
dependsOn(dottyCompiler, dottyCompiler % "test->test").
13101243
settings(dottyDocSettings)
13111244

1312-
def asDottySbtBridge(implicit mode: Mode): Project = project.withCommonSettings.
1313-
dependsOn(dottyCompiler % Provided).
1314-
dependsOn(dottyDoc % Provided).
1315-
settings(dottySbtBridgeSettings)
1316-
13171245
def asDottyBench(implicit mode: Mode): Project = project.withCommonSettings.
13181246
dependsOn(dottyCompiler).
13191247
settings(commonBenchmarkSettings).
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/* sbt -- Simple Build Tool
2+
* Copyright 2008, 2009 Mark Harrah
3+
*/
4+
package xsbt;
5+
6+
import xsbti.AnalysisCallback;
7+
import xsbti.Logger;
8+
import xsbti.Reporter;
9+
import xsbti.Severity;
10+
import xsbti.compile.*;
11+
12+
import java.io.File;
13+
14+
import dotty.tools.dotc.core.Contexts.Context;
15+
import dotty.tools.dotc.core.Contexts.ContextBase;
16+
import dotty.tools.dotc.Main;
17+
import dotty.tools.dotc.interfaces.*;
18+
19+
import java.net.URLClassLoader;
20+
21+
public class CachedCompilerImpl implements CachedCompiler {
22+
private final String[] args;
23+
private final Output output;
24+
private final String[] outputArgs;
25+
26+
public CachedCompilerImpl(String[] args, Output output) {
27+
super();
28+
this.args = args;
29+
this.output = output;
30+
31+
if (!(output instanceof SingleOutput))
32+
throw new IllegalArgumentException("output should be a SingleOutput, was a " + output.getClass().getName());
33+
34+
this.outputArgs =
35+
new String[] { "-d", ((SingleOutput) output).getOutputDirectory().getAbsolutePath().toString() };
36+
}
37+
38+
public String[] commandArguments(File[] sources) {
39+
String[] sortedSourcesAbsolute = new String[sources.length];
40+
for (int i = 0; i < sources.length; i++)
41+
sortedSourcesAbsolute[i] = sources[i].getAbsolutePath();
42+
java.util.Arrays.sort(sortedSourcesAbsolute);
43+
44+
// Concatenate outputArgs, args and sortedSourcesAbsolute
45+
String[] result = new String[outputArgs.length + args.length + sortedSourcesAbsolute.length];
46+
int j = 0;
47+
for (int i = 0; i < outputArgs.length; i++, j++)
48+
result[j] = outputArgs[i];
49+
for (int i = 0; i < args.length; i++, j++)
50+
result[j] = args[i];
51+
for (int i = 0; i < sortedSourcesAbsolute.length; i++, j++)
52+
result[j] = sortedSourcesAbsolute[i];
53+
54+
return result;
55+
}
56+
57+
synchronized public void run(File[] sources, DependencyChanges changes, AnalysisCallback callback, Logger log, Reporter delegate, CompileProgress progress) {
58+
log.debug(() -> {
59+
String msg = "Calling Dotty compiler with arguments (CompilerInterface):";
60+
for (String arg : args)
61+
msg = msg + "\n\t" + arg;
62+
return msg;
63+
});
64+
65+
Context ctx = new ContextBase().initialCtx().fresh()
66+
.setSbtCallback(callback)
67+
.setReporter(new DelegatingReporter(delegate));
68+
69+
dotty.tools.dotc.reporting.Reporter reporter = Main.process(commandArguments(sources), ctx);
70+
if (reporter.hasErrors()) {
71+
throw new InterfaceCompileFailed(args, new Problem[0]);
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)