From af6e535a6cc937f91f4959d9b5e1116182ddc8de Mon Sep 17 00:00:00 2001 From: Jens Grassel Date: Thu, 26 Oct 2017 16:33:36 +0200 Subject: [PATCH 1/3] "sbt '++ 2.13.0-M2!' compile" does not work with sbt 1.0.0 * add new compiler bridge --- .../scala_2.13+/xsbt/ConsoleInterface.scala | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 internal/compiler-bridge/src/main/scala_2.13+/xsbt/ConsoleInterface.scala diff --git a/internal/compiler-bridge/src/main/scala_2.13+/xsbt/ConsoleInterface.scala b/internal/compiler-bridge/src/main/scala_2.13+/xsbt/ConsoleInterface.scala new file mode 100644 index 0000000000..a091d3e3cd --- /dev/null +++ b/internal/compiler-bridge/src/main/scala_2.13+/xsbt/ConsoleInterface.scala @@ -0,0 +1,105 @@ +/* + * Zinc - The incremental compiler for Scala. + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * This software is released under the terms written in LICENSE. + */ + +package xsbt + +import xsbti.Logger +import scala.tools.nsc.interpreter.shell.{ ILoop, IMain, InteractiveReader } +import scala.tools.nsc.reporters.Reporter +import scala.tools.nsc.{ GenericRunnerCommand, Settings } + +class ConsoleInterface { + def commandArguments( + args: Array[String], + bootClasspathString: String, + classpathString: String, + log: Logger + ): Array[String] = + MakeSettings.sync(args, bootClasspathString, classpathString, log).recreateArgs.toArray[String] + + def run( + args: Array[String], + bootClasspathString: String, + classpathString: String, + initialCommands: String, + cleanupCommands: String, + loader: ClassLoader, + bindNames: Array[String], + bindValues: Array[Any], + log: Logger + ): Unit = { + lazy val interpreterSettings = MakeSettings.sync(args.toList, log) + val compilerSettings = MakeSettings.sync(args, bootClasspathString, classpathString, log) + + log.info(Message("Starting scala interpreter...")) + log.info(Message("")) + + val loop = new ILoop { + override def createInterpreter() = { + if (loader ne null) { + in = InteractiveReader.apply() + intp = new IMain(settings) { + override protected def parentClassLoader = + if (loader eq null) super.parentClassLoader else loader + + override protected def newCompiler(settings: Settings, reporter: Reporter) = + super.newCompiler(compilerSettings, reporter) + } + intp.setContextClassLoader() + } else + super.createInterpreter() + + for ((id, value) <- bindNames zip bindValues) + intp.beQuietDuring(intp.bind(id, value.asInstanceOf[AnyRef].getClass.getName, value)) + + if (!initialCommands.isEmpty) + intp.interpret(initialCommands) + + () + } + + override def closeInterpreter(): Unit = { + if (!cleanupCommands.isEmpty) + intp.interpret(cleanupCommands) + super.closeInterpreter() + } + } + + loop.process(if (loader eq null) compilerSettings else interpreterSettings) + + () + } +} + +object MakeSettings { + def apply(args: List[String], log: Logger): Settings = { + val command = new GenericRunnerCommand(args, message => log.error(Message(message))) + if (command.ok) + command.settings + else + throw new InterfaceCompileFailed(Array(), Array(), command.usageMsg) + } + + def sync( + args: Array[String], + bootClasspathString: String, + classpathString: String, + log: Logger + ): Settings = { + val compilerSettings = sync(args.toList, log) + if (!bootClasspathString.isEmpty) + compilerSettings.bootclasspath.value = bootClasspathString + compilerSettings.classpath.value = classpathString + compilerSettings + } + + def sync(options: List[String], log: Logger): Settings = { + val settings = apply(options, log) + settings.Yreplsync.value = true + settings + } +} From c60ff2371fa953fd8f07b5aec3a6157612796811 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 15 Nov 2017 23:36:25 -0500 Subject: [PATCH 2/3] Implement compiler bridge for 2.13.0-M2 Fixes #395, sbt/sbt#3427 In https://github.com/scala/scala/pull/5903 Scala compiler's REPL-related classes went through some changes, including move to a different package. This implements a new compiler bridge tracking the changes. To verify that the new bridge compiles under 2.13, we need to compile it using sbt 1.0.3, which in turn requires a bridge compatible with Scala 2.13.0-M2. To work around this chicken-egg, I've manually created a bridge and published it to Maven Central as "org.scala-sbt" % "compiler-bridge_2.13.0-M2" % "1.1.0-M1-bootstrap2". --- bin/bridge213.sh | 43 ++++++++ {script => bin}/deltag.sh | 0 build.sbt | 13 ++- .../scala/xsbt/InteractiveConsoleHelper.scala | 10 +- .../xsbt/InteractiveConsoleInterface.scala | 8 +- .../src/main/scala_2.10/xsbt/Compat.scala | 7 ++ .../xsbt/ConsoleInterface.scala | 0 .../xsbt/Compat.scala | 9 +- .../xsbt/ConsoleInterface.scala | 4 +- .../src/main/scala_2.13/xsbt/Compat.scala | 33 ++++++ .../scala_2.13/xsbt/ConsoleInterface.scala | 102 ++++++++++++++++++ project/Dependencies.scala | 1 + 12 files changed, 217 insertions(+), 13 deletions(-) create mode 100755 bin/bridge213.sh rename {script => bin}/deltag.sh (100%) rename internal/compiler-bridge/src/main/{scala => scala_2.10}/xsbt/ConsoleInterface.scala (100%) rename internal/compiler-bridge/src/main/{scala_2.11+ => scala_2.11-12}/xsbt/Compat.scala (73%) rename internal/compiler-bridge/src/main/{scala_2.13+ => scala_2.11-12}/xsbt/ConsoleInterface.scala (94%) create mode 100644 internal/compiler-bridge/src/main/scala_2.13/xsbt/Compat.scala create mode 100644 internal/compiler-bridge/src/main/scala_2.13/xsbt/ConsoleInterface.scala diff --git a/bin/bridge213.sh b/bin/bridge213.sh new file mode 100755 index 0000000000..9673d0d521 --- /dev/null +++ b/bin/bridge213.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# This is a hack to validate the compilation of 2.13 compiler bridge without using sbt, +# which was used for bootstrapping the initial compiler bridge. +# In the future when Scala compiler breaks source compatibility, this script might come in handy. + +# $ export SCALA_X_HOME=/usr/local/Cellar/scala@2.13/2.13.0-M2 + +if [[ -z "$SCALA_X_HOME" ]]; then + echo "SCALA_X_HOME is not set!" 1>&2 + echo "Run 'export SCALA_X_HOME=/usr/local/Cellar/scala@2.13/2.13.0-M2' or equivalent." + exit 1 +fi + +mkdir -p target/compiler-bridge/ + +"$SCALA_X_HOME/bin/scalac" \ +-nowarn \ +-classpath $HOME/.ivy2/cache/org.scala-sbt/compiler-interface/jars/compiler-interface-1.0.3.jar:$HOME/.ivy2/cache/org.scala-sbt/util-interface/jars/util-interface-1.0.2.jar \ +-d target/compiler-bridge/ \ +internal/compiler-bridge/src/main/scala/xsbt/API.scala \ +internal/compiler-bridge/src/main/scala/xsbt/DelegatingReporter.scala \ +internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleInterface.scala \ +internal/compiler-bridge/src/main/scala/xsbt/ScaladocInterface.scala \ +internal/compiler-bridge/src/main/scala/xsbt/Analyzer.scala \ +internal/compiler-bridge/src/main/scala/xsbt/Dependency.scala \ +internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleResponse.scala \ +internal/compiler-bridge/src/main/scala/xsbt/CallbackGlobal.scala \ +internal/compiler-bridge/src/main/scala/xsbt/ExtractAPI.scala \ +internal/compiler-bridge/src/main/scala/xsbt/JavaUtils.scala \ +internal/compiler-bridge/src/main/scala/xsbt/ClassName.scala \ +internal/compiler-bridge/src/main/scala/xsbt/ExtractUsedNames.scala \ +internal/compiler-bridge/src/main/scala/xsbt/LocalToNonLocalClass.scala \ +internal/compiler-bridge/src/main/scala/xsbt/Command.scala \ +internal/compiler-bridge/src/main/scala/xsbt/GlobalHelpers.scala \ +internal/compiler-bridge/src/main/scala/xsbt/LocateClassFile.scala \ +internal/compiler-bridge/src/main/scala/xsbt/CompilerInterface.scala \ +internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleFactory.scala \ +internal/compiler-bridge/src/main/scala/xsbt/Log.scala \ +internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleHelper.scala \ +internal/compiler-bridge/src/main/scala/xsbt/Message.scala \ +internal/compiler-bridge/src/main/scala_2.13/xsbt/Compat.scala \ +internal/compiler-bridge/src/main/scala_2.13/xsbt/ConsoleInterface.scala diff --git a/script/deltag.sh b/bin/deltag.sh similarity index 100% rename from script/deltag.sh rename to bin/deltag.sh diff --git a/build.sbt b/build.sbt index 9082141426..d669e1b698 100644 --- a/build.sbt +++ b/build.sbt @@ -351,9 +351,18 @@ lazy val compilerBridge: Project = (project in internalPath / "compiler-bridge") // compiler instances that are memory hungry javaOptions in Test += "-Xmx1G", inBoth(unmanagedSourceDirectories ++= scalaPartialVersion.value.collect { - case (2, y) if y == 10 => new File(scalaSource.value.getPath + "_2.10") - case (2, y) if y >= 11 => new File(scalaSource.value.getPath + "_2.11+") + case (2, y) if y == 10 => new File(scalaSource.value.getPath + "_2.10") + case (2, y) if y == 11 || y == 12 => new File(scalaSource.value.getPath + "_2.11-12") + case (2, y) if y >= 13 => new File(scalaSource.value.getPath + "_2.13") }.toList), + // Use a bootstrap compiler bridge to compile the compiler bridge. + scalaCompilerBridgeSource := { + val old = scalaCompilerBridgeSource.value + scalaVersion.value match { + case x if x startsWith "2.13." => ("org.scala-sbt" % "compiler-bridge_2.13.0-M2" % "1.1.0-M1-bootstrap2" % Compile).sources() + case _ => old + } + }, cleanSbtBridge := { val sbtV = sbtVersion.value val sbtOrg = "org.scala-sbt" diff --git a/internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleHelper.scala b/internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleHelper.scala index 42f571db27..01dd182e5e 100644 --- a/internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleHelper.scala +++ b/internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleHelper.scala @@ -7,14 +7,14 @@ package xsbt -import scala.tools.nsc.interpreter.IR +import Compat._ import xsbti.InteractiveConsoleResult object InteractiveConsoleHelper { - implicit def toConsoleResult(ir: IR.Result): InteractiveConsoleResult = + implicit def toConsoleResult(ir: Results.Result): InteractiveConsoleResult = ir match { - case IR.Success => InteractiveConsoleResult.Success - case IR.Incomplete => InteractiveConsoleResult.Incomplete - case IR.Error => InteractiveConsoleResult.Error + case Results.Success => InteractiveConsoleResult.Success + case Results.Incomplete => InteractiveConsoleResult.Incomplete + case Results.Error => InteractiveConsoleResult.Error } } diff --git a/internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleInterface.scala b/internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleInterface.scala index 2aa9f5f483..24e6171722 100644 --- a/internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleInterface.scala +++ b/internal/compiler-bridge/src/main/scala/xsbt/InteractiveConsoleInterface.scala @@ -14,6 +14,7 @@ import scala.tools.nsc.{ GenericRunnerCommand, Settings } import xsbti.Logger +import Compat._ import InteractiveConsoleHelper._ class InteractiveConsoleInterface( @@ -38,9 +39,10 @@ class InteractiveConsoleInterface( val outWriter: StringWriter = new StringWriter val poutWriter: PrintWriter = new PrintWriter(outWriter) - val interpreter: IMain = new IMain(compilerSettings, new PrintWriter(outWriter)) { - def lastReq: Request = prevRequestList.last - } + val interpreter: IMain = + new IMain(compilerSettings, replReporter(compilerSettings, new PrintWriter(outWriter))) { + def lastReq: Request = prevRequestList.last + } def interpret(line: String, synthetic: Boolean): InteractiveConsoleResponse = { clearBuffer() diff --git a/internal/compiler-bridge/src/main/scala_2.10/xsbt/Compat.scala b/internal/compiler-bridge/src/main/scala_2.10/xsbt/Compat.scala index 752ac20d6b..c34db28ae4 100644 --- a/internal/compiler-bridge/src/main/scala_2.10/xsbt/Compat.scala +++ b/internal/compiler-bridge/src/main/scala_2.10/xsbt/Compat.scala @@ -1,5 +1,6 @@ package xsbt +import java.io.PrintWriter import xsbti.compile.Output import scala.reflect.{ internal => sri } import scala.reflect.internal.{ util => sriu } @@ -150,6 +151,12 @@ trait ZincGlobalCompat { } object Compat { + // IR is renamed to Results + val Results = scala.tools.nsc.interpreter.IR + + // IMain in 2.13 accepts ReplReporter + def replReporter(settings: Settings, writer: PrintWriter) = writer + implicit final class TreeOps(val tree: sri.Trees#Tree) extends AnyVal { // Introduced in 2.11 @inline final def hasSymbolField: Boolean = tree.hasSymbol diff --git a/internal/compiler-bridge/src/main/scala/xsbt/ConsoleInterface.scala b/internal/compiler-bridge/src/main/scala_2.10/xsbt/ConsoleInterface.scala similarity index 100% rename from internal/compiler-bridge/src/main/scala/xsbt/ConsoleInterface.scala rename to internal/compiler-bridge/src/main/scala_2.10/xsbt/ConsoleInterface.scala diff --git a/internal/compiler-bridge/src/main/scala_2.11+/xsbt/Compat.scala b/internal/compiler-bridge/src/main/scala_2.11-12/xsbt/Compat.scala similarity index 73% rename from internal/compiler-bridge/src/main/scala_2.11+/xsbt/Compat.scala rename to internal/compiler-bridge/src/main/scala_2.11-12/xsbt/Compat.scala index 56a05d9d5c..790ff4e83b 100644 --- a/internal/compiler-bridge/src/main/scala_2.11+/xsbt/Compat.scala +++ b/internal/compiler-bridge/src/main/scala_2.11-12/xsbt/Compat.scala @@ -7,12 +7,19 @@ package xsbt +import java.io.PrintWriter import xsbti.compile.Output import scala.tools.nsc.Settings abstract class Compat -object Compat +object Compat { + // IR is renamed to Results + val Results = scala.tools.nsc.interpreter.IR + + // IMain in 2.13 accepts ReplReporter + def replReporter(settings: Settings, writer: PrintWriter) = writer +} /** Defines compatibility utils for [[ZincCompiler]]. */ trait ZincGlobalCompat { diff --git a/internal/compiler-bridge/src/main/scala_2.13+/xsbt/ConsoleInterface.scala b/internal/compiler-bridge/src/main/scala_2.11-12/xsbt/ConsoleInterface.scala similarity index 94% rename from internal/compiler-bridge/src/main/scala_2.13+/xsbt/ConsoleInterface.scala rename to internal/compiler-bridge/src/main/scala_2.11-12/xsbt/ConsoleInterface.scala index a091d3e3cd..531891ab2e 100644 --- a/internal/compiler-bridge/src/main/scala_2.13+/xsbt/ConsoleInterface.scala +++ b/internal/compiler-bridge/src/main/scala_2.11-12/xsbt/ConsoleInterface.scala @@ -8,7 +8,7 @@ package xsbt import xsbti.Logger -import scala.tools.nsc.interpreter.shell.{ ILoop, IMain, InteractiveReader } +import scala.tools.nsc.interpreter.{ ILoop, IMain, InteractiveReader, NamedParam } import scala.tools.nsc.reporters.Reporter import scala.tools.nsc.{ GenericRunnerCommand, Settings } @@ -54,7 +54,7 @@ class ConsoleInterface { super.createInterpreter() for ((id, value) <- bindNames zip bindValues) - intp.beQuietDuring(intp.bind(id, value.asInstanceOf[AnyRef].getClass.getName, value)) + intp.quietBind(NamedParam.clazz(id, value)) if (!initialCommands.isEmpty) intp.interpret(initialCommands) diff --git a/internal/compiler-bridge/src/main/scala_2.13/xsbt/Compat.scala b/internal/compiler-bridge/src/main/scala_2.13/xsbt/Compat.scala new file mode 100644 index 0000000000..19ca44cd9d --- /dev/null +++ b/internal/compiler-bridge/src/main/scala_2.13/xsbt/Compat.scala @@ -0,0 +1,33 @@ +/* + * Zinc - The incremental compiler for Scala. + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * This software is released under the terms written in LICENSE. + */ + +package xsbt + +import java.io.PrintWriter +import xsbti.compile.Output +import scala.tools.nsc.Settings +import scala.tools.nsc.interpreter.shell.ReplReporterImpl + +abstract class Compat +object Compat { + // IR is renanmed to Results + val Results = scala.tools.nsc.interpreter.Results + + // IMain in 2.13 accepts ReplReporter + def replReporter(settings: Settings, writer: PrintWriter) = + new ReplReporterImpl(settings, writer) +} + +/** Defines compatibility utils for [[ZincCompiler]]. */ +trait ZincGlobalCompat { + protected def superDropRun(): Unit = () +} + +private trait CachedCompilerCompat { self: CachedCompiler0 => + def newCompiler(settings: Settings, reporter: DelegatingReporter, output: Output): ZincCompiler = + new ZincCompiler(settings, reporter, output) +} diff --git a/internal/compiler-bridge/src/main/scala_2.13/xsbt/ConsoleInterface.scala b/internal/compiler-bridge/src/main/scala_2.13/xsbt/ConsoleInterface.scala new file mode 100644 index 0000000000..2081ce0c78 --- /dev/null +++ b/internal/compiler-bridge/src/main/scala_2.13/xsbt/ConsoleInterface.scala @@ -0,0 +1,102 @@ +/* + * Zinc - The incremental compiler for Scala. + * Copyright 2011 - 2017, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * This software is released under the terms written in LICENSE. + */ + +package xsbt + +import xsbti.Logger +import scala.tools.nsc.interpreter.IMain +import scala.tools.nsc.interpreter.shell.{ ILoop, ShellConfig, ReplReporterImpl } +import scala.tools.nsc.reporters.Reporter +import scala.tools.nsc.{ GenericRunnerCommand, Settings } + +class ConsoleInterface { + def commandArguments( + args: Array[String], + bootClasspathString: String, + classpathString: String, + log: Logger + ): Array[String] = + MakeSettings.sync(args, bootClasspathString, classpathString, log).recreateArgs.toArray[String] + + def run( + args: Array[String], + bootClasspathString: String, + classpathString: String, + initialCommands: String, + cleanupCommands: String, + loader: ClassLoader, + bindNames: Array[String], + bindValues: Array[Any], + log: Logger + ): Unit = { + lazy val interpreterSettings = MakeSettings.sync(args.toList, log) + val compilerSettings = MakeSettings.sync(args, bootClasspathString, classpathString, log) + + log.info(Message("Starting scala interpreter...")) + log.info(Message("")) + + val loop = new ILoop(ShellConfig(interpreterSettings)) { + override def createInterpreter(interpreterSettings: Settings) = { + if (loader ne null) { + val reporter = new ReplReporterImpl(interpreterSettings) + intp = new IMain(interpreterSettings, reporter) { + override protected def parentClassLoader = + if (loader eq null) super.parentClassLoader + else loader + } + intp.setContextClassLoader() + } else + super.createInterpreter(interpreterSettings) + + for ((id, value) <- bindNames zip bindValues) + intp.beQuietDuring(intp.bind(id, value.asInstanceOf[AnyRef].getClass.getName, value)) + + if (!initialCommands.isEmpty) + intp.interpret(initialCommands) + + () + } + + override def closeInterpreter(): Unit = { + if (!cleanupCommands.isEmpty) + intp.interpret(cleanupCommands) + super.closeInterpreter() + } + } + + loop.run(compilerSettings) + } +} + +object MakeSettings { + def apply(args: List[String], log: Logger): Settings = { + val command = new GenericRunnerCommand(args, message => log.error(Message(message))) + if (command.ok) + command.settings + else + throw new InterfaceCompileFailed(Array(), Array(), command.usageMsg) + } + + def sync( + args: Array[String], + bootClasspathString: String, + classpathString: String, + log: Logger + ): Settings = { + val compilerSettings = sync(args.toList, log) + if (!bootClasspathString.isEmpty) + compilerSettings.bootclasspath.value = bootClasspathString + compilerSettings.classpath.value = classpathString + compilerSettings + } + + def sync(options: List[String], log: Logger): Settings = { + val settings = apply(options, log) + settings.Yreplsync.value = true + settings + } +} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 729bca6115..6bca5b05a2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,6 +5,7 @@ object Dependencies { val scala210 = "2.10.6" val scala211 = "2.11.11" val scala212 = "2.12.3" + val scala213 = "2.13.0-M2" private val ioVersion = "1.0.0" private val utilVersion = "1.0.0" From 91cb5324336bb7fe802a1ff16724f0e3a8bcd09a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 15 Nov 2017 23:37:09 -0500 Subject: [PATCH 3/3] Split compiler bridge tests to another subproject Splitting compiler bridge tests to another subproject because while the bridge itself can be compiled with just compiler-interface, util-interface, and Scala Compiler as dependencies, the testing introduces more (such as IO). This creates problem for new Scala versions where IO or test libraries do not exist yet (e.g. Scala 2.13.0-M2). This also removes the Mima test due to the lack of 2.13 bridge for Zinc 1.0.0. Compiler bridge just needs to compile itself against the interface and Scala compiler, so there's no need to run Mima test. --- build.sbt | 60 +++++++++++++------ .../ExtractUsedNamesPerformance.scala.source | 0 .../scala/xsbt/ClassNameSpecification.scala | 0 .../scala/xsbt/DependencySpecification.scala | 0 .../scala/xsbt/ExtractAPISpecification.scala | 0 ...actUsedNamesPerformanceSpecification.scala | 0 .../xsbt/ExtractUsedNamesSpecification.scala | 0 ...ractiveConsoleInterfaceSpecification.scala | 0 .../xsbt/ScalaCompilerForUnitTesting.scala | 0 .../internal/inc/ZincComponentCompiler.scala | 9 ++- .../inc/ZincComponentCompilerSpec.scala | 5 ++ project/build.properties | 2 +- .../bridgecheck_210/app/Hello.scala | 0 .../bridgecheck_210/build.json | 0 .../bridgecheck_210/test | 0 .../bridgecheck_211/app/Hello.scala | 0 .../bridgecheck_211/build.json | 0 .../bridgecheck_211/test | 0 .../bridgecheck_212/app/Hello.scala | 0 .../bridgecheck_212/build.json | 0 .../bridgecheck_212/test | 0 .../bridgecheck_213/app/Hello.scala | 5 ++ .../bridge-check/bridgecheck_213/build.json | 8 +++ .../bridge-check/bridgecheck_213/test | 1 + 24 files changed, 67 insertions(+), 23 deletions(-) rename internal/{compiler-bridge => compiler-bridge-test}/src/test/resources/ExtractUsedNamesPerformance.scala.source (100%) rename internal/{compiler-bridge => compiler-bridge-test}/src/test/scala/xsbt/ClassNameSpecification.scala (100%) rename internal/{compiler-bridge => compiler-bridge-test}/src/test/scala/xsbt/DependencySpecification.scala (100%) rename internal/{compiler-bridge => compiler-bridge-test}/src/test/scala/xsbt/ExtractAPISpecification.scala (100%) rename internal/{compiler-bridge => compiler-bridge-test}/src/test/scala/xsbt/ExtractUsedNamesPerformanceSpecification.scala (100%) rename internal/{compiler-bridge => compiler-bridge-test}/src/test/scala/xsbt/ExtractUsedNamesSpecification.scala (100%) rename internal/{compiler-bridge => compiler-bridge-test}/src/test/scala/xsbt/InteractiveConsoleInterfaceSpecification.scala (100%) rename internal/{compiler-bridge => compiler-bridge-test}/src/test/scala/xsbt/ScalaCompilerForUnitTesting.scala (100%) rename zinc/src/sbt-test/{source-dependencies => bridge-check}/bridgecheck_210/app/Hello.scala (100%) rename zinc/src/sbt-test/{source-dependencies => bridge-check}/bridgecheck_210/build.json (100%) rename zinc/src/sbt-test/{source-dependencies => bridge-check}/bridgecheck_210/test (100%) rename zinc/src/sbt-test/{source-dependencies => bridge-check}/bridgecheck_211/app/Hello.scala (100%) rename zinc/src/sbt-test/{source-dependencies => bridge-check}/bridgecheck_211/build.json (100%) rename zinc/src/sbt-test/{source-dependencies => bridge-check}/bridgecheck_211/test (100%) rename zinc/src/sbt-test/{source-dependencies => bridge-check}/bridgecheck_212/app/Hello.scala (100%) rename zinc/src/sbt-test/{source-dependencies => bridge-check}/bridgecheck_212/build.json (100%) rename zinc/src/sbt-test/{source-dependencies => bridge-check}/bridgecheck_212/test (100%) create mode 100644 zinc/src/sbt-test/bridge-check/bridgecheck_213/app/Hello.scala create mode 100644 zinc/src/sbt-test/bridge-check/bridgecheck_213/build.json create mode 100644 zinc/src/sbt-test/bridge-check/bridgecheck_213/test diff --git a/build.sbt b/build.sbt index d669e1b698..1f57e24690 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,8 @@ import Scripted._ def baseVersion = "1.1.0-SNAPSHOT" def internalPath = file("internal") -lazy val compilerBridgeScalaVersions = List(scala212, scala211, scala210) +lazy val compilerBridgeScalaVersions = List(scala212, scala213, scala211, scala210) +lazy val compilerBridgeTestScalaVersions = List(scala212, scala211, scala210) def mimaSettings: Seq[Setting[_]] = Seq( mimaPreviousArtifacts := Set( @@ -330,10 +331,17 @@ def wrapIn(color: String, content: String): String = { else color + content + scala.Console.RESET } -// Compiler-side interface to compiler that is compiled against the compiler being used either in advance or on the fly. -// Includes API and Analyzer phases that extract source API and relationships. +/** + * Compiler-side interface to compiler that is compiled against the compiler being used either in advance or on the fly. + * Includes API and Analyzer phases that extract source API and relationships. + * As this is essentially implementations of the compiler-interface (per Scala compiler), + * the code here should not be consumed without going through the classloader trick and the interface. + * Due to the hermetic nature of the bridge, there's no necessity to keep binary compatibility across Zinc versions, + * and therefore there's no `mimaSettings` added. + * For the case of Scala 2.13 bridge, we didn't even have the bridge to compare against when Zinc 1.0.0 came out. + */ lazy val compilerBridge: Project = (project in internalPath / "compiler-bridge") - .dependsOn(compilerInterface % "compile;test->test", zincApiInfo % "test->test") + .dependsOn(compilerInterface) .settings( baseSettings, crossScalaVersions := compilerBridgeScalaVersions, @@ -343,13 +351,6 @@ lazy val compilerBridge: Project = (project in internalPath / "compiler-bridge") // precompiledSettings, name := "Compiler Bridge", exportJars := true, - // we need to fork because in unit tests we set usejavacp = true which means - // we are expecting all of our dependencies to be on classpath so Scala compiler - // can use them while constructing its own classpath for compilation - fork in Test := true, - // needed because we fork tests and tests are ran in parallel so we have multiple Scala - // compiler instances that are memory hungry - javaOptions in Test += "-Xmx1G", inBoth(unmanagedSourceDirectories ++= scalaPartialVersion.value.collect { case (2, y) if y == 10 => new File(scalaSource.value.getPath + "_2.10") case (2, y) if y == 11 || y == 12 => new File(scalaSource.value.getPath + "_2.11-12") @@ -394,7 +395,30 @@ lazy val compilerBridge: Project = (project in internalPath / "compiler-bridge") }, publishLocal := publishLocal.dependsOn(cleanSbtBridge).value, altPublishSettings, - mimaSettings, + ) + +/** + * Tests for the compiler bridge. + * This is split into a separate subproject because testing introduces more dependencies + * (Zinc API Info, which transitively depends on IO). + */ +lazy val compilerBridgeTest = (project in internalPath / "compiler-bridge-test") + .dependsOn(compilerBridge, compilerInterface % "test->test", zincApiInfo % "test->test") + .settings( + name := "Compiler Bridge Test", + baseSettings, + relaxNon212, + // we need to fork because in unit tests we set usejavacp = true which means + // we are expecting all of our dependencies to be on classpath so Scala compiler + // can use them while constructing its own classpath for compilation + fork in Test := true, + // needed because we fork tests and tests are ran in parallel so we have multiple Scala + // compiler instances that are memory hungry + javaOptions in Test += "-Xmx1G", + crossScalaVersions := compilerBridgeTestScalaVersions, + libraryDependencies += scalaCompiler.value, + altPublishSettings, + skip in publish := true, ) val scalaPartialVersion = Def setting (CrossVersion partialVersion scalaVersion.value) @@ -408,7 +432,7 @@ lazy val zincApiInfo = (project in internalPath / "zinc-apiinfo") .configure(addBaseSettingsAndTestDeps) .settings( name := "zinc ApiInfo", - crossScalaVersions := compilerBridgeScalaVersions, + crossScalaVersions := compilerBridgeTestScalaVersions, relaxNon212, mimaSettings, ) @@ -419,7 +443,7 @@ lazy val zincClasspath = (project in internalPath / "zinc-classpath") .configure(addBaseSettingsAndTestDeps) .settings( name := "zinc Classpath", - crossScalaVersions := compilerBridgeScalaVersions, + crossScalaVersions := compilerBridgeTestScalaVersions, relaxNon212, libraryDependencies ++= Seq(scalaCompiler.value, launcherInterface), mimaSettings, @@ -432,7 +456,7 @@ lazy val zincClassfile = (project in internalPath / "zinc-classfile") .configure(addBaseSettingsAndTestDeps) .settings( name := "zinc Classfile", - crossScalaVersions := compilerBridgeScalaVersions, + crossScalaVersions := compilerBridgeTestScalaVersions, relaxNon212, mimaSettings, ) @@ -450,10 +474,10 @@ lazy val zincScripted = (project in internalPath / "zinc-scripted") lazy val crossTestBridges = { Command.command("crossTestBridges") { state => - (compilerBridgeScalaVersions.flatMap { (bridgeVersion: String) => + (compilerBridgeTestScalaVersions.flatMap { (bridgeVersion: String) => // Note the ! here. You need this so compilerInterface gets forced to the scalaVersion s"++ $bridgeVersion!" :: - s"${compilerBridge.id}/test" :: + s"${compilerBridgeTest.id}/test" :: Nil }) ::: (s"++ $scala212!" :: @@ -468,7 +492,6 @@ lazy val publishBridgesAndSet = { s"${compilerInterface.id}/publishLocal" :: compilerBridgeScalaVersions.flatMap { (bridgeVersion: String) => s"++ $bridgeVersion!" :: - s"${zincApiInfo.id}/publishLocal" :: s"${compilerBridge.id}/publishLocal" :: Nil } ::: s"++ $userScalaVersion!" :: @@ -484,7 +507,6 @@ lazy val publishBridgesAndTest = Command.args("publishBridgesAndTest", " s"++ $bridgeVersion" :: - s"${zincApiInfo.id}/publishLocal" :: s"${compilerBridge.id}/publishLocal" :: Nil }) ::: s"++ $version" :: diff --git a/internal/compiler-bridge/src/test/resources/ExtractUsedNamesPerformance.scala.source b/internal/compiler-bridge-test/src/test/resources/ExtractUsedNamesPerformance.scala.source similarity index 100% rename from internal/compiler-bridge/src/test/resources/ExtractUsedNamesPerformance.scala.source rename to internal/compiler-bridge-test/src/test/resources/ExtractUsedNamesPerformance.scala.source diff --git a/internal/compiler-bridge/src/test/scala/xsbt/ClassNameSpecification.scala b/internal/compiler-bridge-test/src/test/scala/xsbt/ClassNameSpecification.scala similarity index 100% rename from internal/compiler-bridge/src/test/scala/xsbt/ClassNameSpecification.scala rename to internal/compiler-bridge-test/src/test/scala/xsbt/ClassNameSpecification.scala diff --git a/internal/compiler-bridge/src/test/scala/xsbt/DependencySpecification.scala b/internal/compiler-bridge-test/src/test/scala/xsbt/DependencySpecification.scala similarity index 100% rename from internal/compiler-bridge/src/test/scala/xsbt/DependencySpecification.scala rename to internal/compiler-bridge-test/src/test/scala/xsbt/DependencySpecification.scala diff --git a/internal/compiler-bridge/src/test/scala/xsbt/ExtractAPISpecification.scala b/internal/compiler-bridge-test/src/test/scala/xsbt/ExtractAPISpecification.scala similarity index 100% rename from internal/compiler-bridge/src/test/scala/xsbt/ExtractAPISpecification.scala rename to internal/compiler-bridge-test/src/test/scala/xsbt/ExtractAPISpecification.scala diff --git a/internal/compiler-bridge/src/test/scala/xsbt/ExtractUsedNamesPerformanceSpecification.scala b/internal/compiler-bridge-test/src/test/scala/xsbt/ExtractUsedNamesPerformanceSpecification.scala similarity index 100% rename from internal/compiler-bridge/src/test/scala/xsbt/ExtractUsedNamesPerformanceSpecification.scala rename to internal/compiler-bridge-test/src/test/scala/xsbt/ExtractUsedNamesPerformanceSpecification.scala diff --git a/internal/compiler-bridge/src/test/scala/xsbt/ExtractUsedNamesSpecification.scala b/internal/compiler-bridge-test/src/test/scala/xsbt/ExtractUsedNamesSpecification.scala similarity index 100% rename from internal/compiler-bridge/src/test/scala/xsbt/ExtractUsedNamesSpecification.scala rename to internal/compiler-bridge-test/src/test/scala/xsbt/ExtractUsedNamesSpecification.scala diff --git a/internal/compiler-bridge/src/test/scala/xsbt/InteractiveConsoleInterfaceSpecification.scala b/internal/compiler-bridge-test/src/test/scala/xsbt/InteractiveConsoleInterfaceSpecification.scala similarity index 100% rename from internal/compiler-bridge/src/test/scala/xsbt/InteractiveConsoleInterfaceSpecification.scala rename to internal/compiler-bridge-test/src/test/scala/xsbt/InteractiveConsoleInterfaceSpecification.scala diff --git a/internal/compiler-bridge/src/test/scala/xsbt/ScalaCompilerForUnitTesting.scala b/internal/compiler-bridge-test/src/test/scala/xsbt/ScalaCompilerForUnitTesting.scala similarity index 100% rename from internal/compiler-bridge/src/test/scala/xsbt/ScalaCompilerForUnitTesting.scala rename to internal/compiler-bridge-test/src/test/scala/xsbt/ScalaCompilerForUnitTesting.scala diff --git a/internal/zinc-ivy-integration/src/main/scala/sbt/internal/inc/ZincComponentCompiler.scala b/internal/zinc-ivy-integration/src/main/scala/sbt/internal/inc/ZincComponentCompiler.scala index e14e591dee..f64360a5ff 100644 --- a/internal/zinc-ivy-integration/src/main/scala/sbt/internal/inc/ZincComponentCompiler.scala +++ b/internal/zinc-ivy-integration/src/main/scala/sbt/internal/inc/ZincComponentCompiler.scala @@ -42,9 +42,12 @@ private[sbt] object ZincComponentCompiler { def compilerBridgeId(scalaVersion: String) = { // Defaults to bridge for 2.12 for Scala versions bigger than 2.12.x scalaVersion match { - case sc if (sc startsWith "2.10.") => "compiler-bridge_2.10" - case sc if (sc startsWith "2.11.") => "compiler-bridge_2.11" - case _ => "compiler-bridge_2.12" + case sc if (sc startsWith "2.10.") => "compiler-bridge_2.10" + case sc if (sc startsWith "2.11.") => "compiler-bridge_2.11" + case sc if (sc startsWith "2.12.") => "compiler-bridge_2.12" + case sc if (sc startsWith "2.13.0-M") => "compiler-bridge_2.13.0-M2" + case sc if (sc startsWith "2.13.0-RC") => "compiler-bridge_2.13.0-M2" + case _ => "compiler-bridge_2.13" } } import xsbti.ArtifactInfo.SbtOrganization diff --git a/internal/zinc-ivy-integration/src/test/scala/sbt/internal/inc/ZincComponentCompilerSpec.scala b/internal/zinc-ivy-integration/src/test/scala/sbt/internal/inc/ZincComponentCompilerSpec.scala index 3fbd1a24f6..f3245c1ea4 100644 --- a/internal/zinc-ivy-integration/src/test/scala/sbt/internal/inc/ZincComponentCompilerSpec.scala +++ b/internal/zinc-ivy-integration/src/test/scala/sbt/internal/inc/ZincComponentCompilerSpec.scala @@ -11,6 +11,7 @@ class ZincComponentCompilerSpec extends BridgeProviderSpecification { val scala2121 = "2.12.1" val scala2122 = "2.12.2" val scala2123 = "2.12.3" + val scala2130M2 = "2.13.0-M2" val logger = ConsoleLogger() it should "compile the bridge for Scala 2.10.5 and 2.10.6" in { @@ -28,4 +29,8 @@ class ZincComponentCompilerSpec extends BridgeProviderSpecification { IO.withTemporaryDirectory(t => getCompilerBridge(t, logger, scala2122) should exist) IO.withTemporaryDirectory(t => getCompilerBridge(t, logger, scala2123) should exist) } + + it should "compile the bridge for Scala 2.13.0-M2" in { + IO.withTemporaryDirectory(t => getCompilerBridge(t, logger, scala2130M2) should exist) + } } diff --git a/project/build.properties b/project/build.properties index b7dd3cb2ae..9abea1294a 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.2 +sbt.version=1.0.3 diff --git a/zinc/src/sbt-test/source-dependencies/bridgecheck_210/app/Hello.scala b/zinc/src/sbt-test/bridge-check/bridgecheck_210/app/Hello.scala similarity index 100% rename from zinc/src/sbt-test/source-dependencies/bridgecheck_210/app/Hello.scala rename to zinc/src/sbt-test/bridge-check/bridgecheck_210/app/Hello.scala diff --git a/zinc/src/sbt-test/source-dependencies/bridgecheck_210/build.json b/zinc/src/sbt-test/bridge-check/bridgecheck_210/build.json similarity index 100% rename from zinc/src/sbt-test/source-dependencies/bridgecheck_210/build.json rename to zinc/src/sbt-test/bridge-check/bridgecheck_210/build.json diff --git a/zinc/src/sbt-test/source-dependencies/bridgecheck_210/test b/zinc/src/sbt-test/bridge-check/bridgecheck_210/test similarity index 100% rename from zinc/src/sbt-test/source-dependencies/bridgecheck_210/test rename to zinc/src/sbt-test/bridge-check/bridgecheck_210/test diff --git a/zinc/src/sbt-test/source-dependencies/bridgecheck_211/app/Hello.scala b/zinc/src/sbt-test/bridge-check/bridgecheck_211/app/Hello.scala similarity index 100% rename from zinc/src/sbt-test/source-dependencies/bridgecheck_211/app/Hello.scala rename to zinc/src/sbt-test/bridge-check/bridgecheck_211/app/Hello.scala diff --git a/zinc/src/sbt-test/source-dependencies/bridgecheck_211/build.json b/zinc/src/sbt-test/bridge-check/bridgecheck_211/build.json similarity index 100% rename from zinc/src/sbt-test/source-dependencies/bridgecheck_211/build.json rename to zinc/src/sbt-test/bridge-check/bridgecheck_211/build.json diff --git a/zinc/src/sbt-test/source-dependencies/bridgecheck_211/test b/zinc/src/sbt-test/bridge-check/bridgecheck_211/test similarity index 100% rename from zinc/src/sbt-test/source-dependencies/bridgecheck_211/test rename to zinc/src/sbt-test/bridge-check/bridgecheck_211/test diff --git a/zinc/src/sbt-test/source-dependencies/bridgecheck_212/app/Hello.scala b/zinc/src/sbt-test/bridge-check/bridgecheck_212/app/Hello.scala similarity index 100% rename from zinc/src/sbt-test/source-dependencies/bridgecheck_212/app/Hello.scala rename to zinc/src/sbt-test/bridge-check/bridgecheck_212/app/Hello.scala diff --git a/zinc/src/sbt-test/source-dependencies/bridgecheck_212/build.json b/zinc/src/sbt-test/bridge-check/bridgecheck_212/build.json similarity index 100% rename from zinc/src/sbt-test/source-dependencies/bridgecheck_212/build.json rename to zinc/src/sbt-test/bridge-check/bridgecheck_212/build.json diff --git a/zinc/src/sbt-test/source-dependencies/bridgecheck_212/test b/zinc/src/sbt-test/bridge-check/bridgecheck_212/test similarity index 100% rename from zinc/src/sbt-test/source-dependencies/bridgecheck_212/test rename to zinc/src/sbt-test/bridge-check/bridgecheck_212/test diff --git a/zinc/src/sbt-test/bridge-check/bridgecheck_213/app/Hello.scala b/zinc/src/sbt-test/bridge-check/bridgecheck_213/app/Hello.scala new file mode 100644 index 0000000000..1fab48bfb0 --- /dev/null +++ b/zinc/src/sbt-test/bridge-check/bridgecheck_213/app/Hello.scala @@ -0,0 +1,5 @@ +package example + +object Hello extends App { + println("hello") +} diff --git a/zinc/src/sbt-test/bridge-check/bridgecheck_213/build.json b/zinc/src/sbt-test/bridge-check/bridgecheck_213/build.json new file mode 100644 index 0000000000..573c72232c --- /dev/null +++ b/zinc/src/sbt-test/bridge-check/bridgecheck_213/build.json @@ -0,0 +1,8 @@ +{ + "projects": [ + { + "name": "app", + "scalaVersion": "2.13.0-M2" + } + ] +} diff --git a/zinc/src/sbt-test/bridge-check/bridgecheck_213/test b/zinc/src/sbt-test/bridge-check/bridgecheck_213/test new file mode 100644 index 0000000000..19aca297fd --- /dev/null +++ b/zinc/src/sbt-test/bridge-check/bridgecheck_213/test @@ -0,0 +1 @@ +> app/compile