diff --git a/sbt-bridge/src/dotty/tools/xsbt/CompilerBridgeDriver.java b/sbt-bridge/src/dotty/tools/xsbt/CompilerBridgeDriver.java index 8a7f3ae2d22e..6c622063a141 100644 --- a/sbt-bridge/src/dotty/tools/xsbt/CompilerBridgeDriver.java +++ b/sbt-bridge/src/dotty/tools/xsbt/CompilerBridgeDriver.java @@ -29,13 +29,13 @@ public CompilerBridgeDriver(String[] scalacOptions, Output output) { super(); this.scalacOptions = scalacOptions; - if (!output.getSingleOutput().isPresent()) + if (!output.getSingleOutputAsPath().isPresent()) throw new IllegalArgumentException("output should be a SingleOutput, was a " + output.getClass().getName()); this.args = new String[scalacOptions.length + 2]; System.arraycopy(scalacOptions, 0, args, 0, scalacOptions.length); args[scalacOptions.length] = "-d"; - args[scalacOptions.length + 1] = output.getSingleOutput().get().getAbsolutePath(); + args[scalacOptions.length + 1] = output.getSingleOutputAsPath().get().toAbsolutePath().toString(); } private static final String StopInfoError = diff --git a/sbt-bridge/src/xsbt/CachedCompilerImpl.java b/sbt-bridge/src/xsbt/CachedCompilerImpl.java index 8ade3bf4b994..0b876475e51e 100644 --- a/sbt-bridge/src/xsbt/CachedCompilerImpl.java +++ b/sbt-bridge/src/xsbt/CachedCompilerImpl.java @@ -14,6 +14,9 @@ import dotty.tools.xsbt.InterfaceCompileFailed; import dotty.tools.xsbt.DelegatingReporter; +// deprecation warnings are suppressed because scala3-sbt-bridge must stay compatible with Zinc 1.3 +// see https://github.com/lampepfl/dotty/issues/10816 +@SuppressWarnings("deprecation") public class CachedCompilerImpl implements CachedCompiler { private final String[] args; private final String[] outputArgs; diff --git a/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/build.sbt b/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/build.sbt new file mode 100644 index 000000000000..72977c705b71 --- /dev/null +++ b/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/build.sbt @@ -0,0 +1,75 @@ +scalaVersion := "2.12.13" + +val Scala3Compiler = config("scala3-compiler") +val Scala3Bridge = config("scala3-bridge") + +val scala3Version = sys.props("plugin.scalaVersion") + +lazy val root = project.in(file(".")) + .configs(Scala3Compiler, Scala3Bridge) + .settings( + inConfig(Scala3Compiler)(Defaults.configSettings), + inConfig(Scala3Bridge)(Defaults.configSettings), + libraryDependencies ++= Seq( + "org.scala-sbt" %% "zinc" % "1.3.5", + "org.scala-lang" % "scala3-compiler_3" % scala3Version % Scala3Compiler, + "org.scala-lang" % "scala3-sbt-bridge" % scala3Version % Scala3Bridge + ), + autoScalaLibrary := false, + run / fork := true, + Compile / sourceGenerators += Def.task { + val scala3File = (Compile / sourceManaged).value / "Scala3.scala" + val inputFile = (Compile / sourceManaged).value / "Input.scala" + + val allJars = (Scala3Compiler / managedClasspath).value.seq.map(_.data) + val compilerJar = allJars + .find(jar => jar.name.contains("scala3-compiler")) + .get.getAbsolutePath.toString + val libraryJars = allJars + .filter(jar => jar.name.contains("library")) + .map(_.getAbsolutePath.toString) + + val bridgeJars = (Scala3Bridge / managedClasspath).value.seq.map(_.data) + val bridgeJar = bridgeJars + .find(att => att.name.contains("scala3-sbt-bridge")) + .get.getAbsolutePath.toString + + IO.write( + scala3File, + s"""| + |import java.io.File + | + |object Scala3 { + | val version = "$scala3Version" + | val allJars = Array( + | ${allJars.map(jar => s"""new File("${jar.getAbsolutePath}")""").mkString(",\n ")} + | ) + | val compilerJar = new File("$compilerJar") + | val libraryJars = Array( + | ${libraryJars.map(jar => s"""new File("$jar")""").mkString(",\n ")} + | ) + | val bridgeJar = new File("$bridgeJar") + |} + |""".stripMargin + ) + + val output = target.value / "test-output" + IO.createDirectory(output) + + val sourceFile = baseDirectory.value / "tests" / "Hello.scala" + + IO.write( + inputFile, + s"""| + |import java.io.File + | + |object Input { + | val outputFile = new File("${output.getAbsolutePath}") + | val sources = Array(new File("${sourceFile.getAbsolutePath}")) + |} + |""".stripMargin + ) + + Seq(scala3File, inputFile) + } + ) diff --git a/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/src/main/scala/Main.scala b/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/src/main/scala/Main.scala new file mode 100644 index 000000000000..01dabb25d9d4 --- /dev/null +++ b/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/src/main/scala/Main.scala @@ -0,0 +1,69 @@ + +import java.net.URLClassLoader +import java.io.File +import java.util.{EnumSet, Set, HashSet} + +import org.apache.logging.log4j.LogManager + +import xsbti._ +import xsbti.api.ClassLike +import xsbti.api.DependencyContext +import xsbti.compile.DependencyChanges + +import sbt.internal.util.ManagedLogger +import sbt.internal.inc.FreshCompilerCache +import sbt.internal.inc.ZincUtil +import sbt.internal.inc.ScalaInstance + +object Main extends App { + val loaderLibraryOnly = new URLClassLoader(Scala3.libraryJars.map(_.toURI.toURL), null) + val loader = new URLClassLoader(Scala3.allJars.map(_.toURI.toURL), loaderLibraryOnly) + val instance = new ScalaInstance( + Scala3.version, + loader, + loaderLibraryOnly, + Scala3.libraryJars, + Scala3.compilerJar, + Scala3.allJars, + Some(Scala3.version) + ) + val compiler = ZincUtil.scalaCompiler(instance, Scala3.bridgeJar) + + val noChanges = new DependencyChanges { + val modifiedBinaries = Array.empty[File] + val modifiedClasses = Array.empty[String] + def isEmpty(): Boolean = true + } + val noCallback = new AnalysisCallback { + override def startSource(x$1: File): Unit = () + override def classDependency(x$1: String, x$2: String, x$3: DependencyContext): Unit = () + override def binaryDependency(x$1: File, x$2: String, x$3: String, x$4: File, x$5: DependencyContext): Unit = () + override def generatedNonLocalClass(x$1: File, x$2: File, x$3: String, x$4: String): Unit = () + override def generatedLocalClass(x$1: File, x$2: File): Unit = () + override def api(x$1: File, x$2: ClassLike): Unit = () + override def mainClass(x$1: File, x$2: String): Unit = () + override def usedName(x$1: String, x$2: String, x$3: EnumSet[UseScope]): Unit = () + override def problem(x$1: String, x$2: Position, x$3: String, x$4: Severity, x$5: Boolean): Unit = () + override def dependencyPhaseCompleted(): Unit = () + override def apiPhaseCompleted(): Unit = () + override def enabled(): Boolean = false + override def classesInOutputJar(): Set[String] = new HashSet[String]() + } + val cache = new FreshCompilerCache() + val log = new ManagedLogger("default", None, None, LogManager.getLogger()) + + compiler.apply( + Input.sources, + noChanges, + Scala3.libraryJars, + Input.outputFile, + options = Array(), + noCallback, + maximumErrors = 10, + cache, + log + ) +} + + + diff --git a/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/test b/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/test new file mode 100644 index 000000000000..f7b3295e155c --- /dev/null +++ b/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/test @@ -0,0 +1,3 @@ +# this little app test that scala3-sbt-bridge is compatible with Zinc 1.3 +# this is necessary to maintain the compatibility with Bloop (see https://github.com/lampepfl/dotty/issues/10816) +> run diff --git a/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/tests/Hello.scala b/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/tests/Hello.scala new file mode 100644 index 000000000000..92d8e2befc76 --- /dev/null +++ b/sbt-dotty/sbt-test/sbt-bridge/zinc-13-compat/tests/Hello.scala @@ -0,0 +1 @@ +@main def hello = println("Hello, World!")