Remove `CompilerBridgeProvider` and `ResourceBridgeProvider`

It turns out that we can leverage the`FakeResolver` that has been
implemented to use with the static launcher, and resolve a "fake
compiler bridge" using it, rather than copying it from the resources.

This also has the advantage of not requiring to change the build
definition.
This commit is contained in:
Martin Duhem 2016-04-15 08:35:27 +02:00
parent 1d44420c91
commit 175ece4238
6 changed files with 16 additions and 103 deletions

View File

@ -1,20 +0,0 @@
package sbt
package compiler
/**
* Base trait for the different means of retrieving the compiler bridge sources
*/
sealed trait CompilerBridgeProvider
/**
* Indicates that the compiler bridge should be retrieved using Ivy.
* @param ivyConfiguration The `sbt.IvyConfiguration` to use to retrieve the sources.
* @param module The module that contains the sources of the compiler bridge.
*/
final case class IvyBridgeProvider(ivyConfiguration: IvyConfiguration, module: ModuleID) extends CompilerBridgeProvider
/**
* Indicates that the compiler bridge sould be retrieved from the resources on classpath.
* @param sourceJarName The name of the JAR containing the bridge sources, to find in the resources.
*/
final case class ResourceBridgeProvider(sourceJarName: String) extends CompilerBridgeProvider

View File

@ -15,7 +15,7 @@ object ComponentCompiler {
val compilerInterfaceSrcID = compilerInterfaceID + srcExtension
val javaVersion = System.getProperty("java.class.version")
@deprecated("Use `interfaceProvider(ComponentManager, CompilerBridgeProvider)`.", "0.13.12")
@deprecated("Use `interfaceProvider(ComponentManager, IvyConfiguration, ModuleID)`.", "0.13.10")
def interfaceProvider(manager: ComponentManager): CompilerInterfaceProvider = new CompilerInterfaceProvider {
def apply(scalaInstance: xsbti.compile.ScalaInstance, log: Logger): File =
{
@ -26,21 +26,13 @@ object ComponentCompiler {
}
}
@deprecated("Use `interfaceProvider(ComponentManager, CompilerBridgeProvider)`", "0.13.12")
def interfaceProvider(manager: ComponentManager, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID): CompilerInterfaceProvider =
interfaceProvider(manager, IvyBridgeProvider(ivyConfiguration, sourcesModule))
def interfaceProvider(manager: ComponentManager, compilerBridgeProvider: CompilerBridgeProvider): CompilerInterfaceProvider = new CompilerInterfaceProvider {
def interfaceProvider(manager: ComponentManager, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID): CompilerInterfaceProvider = new CompilerInterfaceProvider {
def apply(scalaInstance: xsbti.compile.ScalaInstance, log: Logger): File =
compilerBridgeProvider match {
case IvyBridgeProvider(ivyConfiguration, sourcesModule) =>
val componentCompiler = new IvyComponentCompiler(new RawCompiler(scalaInstance, ClasspathOptions.auto, log), manager, ivyConfiguration, sourcesModule, log)
log.debug("Getting " + sourcesModule + " from component compiler for Scala " + scalaInstance.version)
componentCompiler()
case ResourceBridgeProvider(sourceJarName) =>
val componentCompiler = new ResourceComponentCompiler(new RawCompiler(scalaInstance, ClasspathOptions.auto, log), manager, sourceJarName, log)
log.debug("Compiling bridge source from resources for Scala " + scalaInstance.version)
componentCompiler()
{
// this is the instance used to compile the interface component
val componentCompiler = new IvyComponentCompiler(new RawCompiler(scalaInstance, ClasspathOptions.auto, log), manager, ivyConfiguration, sourcesModule, log)
log.debug("Getting " + sourcesModule + " from component compiler for Scala " + scalaInstance.version)
componentCompiler()
}
}
}
@ -49,7 +41,7 @@ object ComponentCompiler {
* The compiled classes are cached using the provided component manager according
* to the actualVersion field of the RawCompiler.
*/
@deprecated("Replaced by IvyComponentCompiler and ResourceComponentCompiler.", "0.13.12")
@deprecated("Replaced by IvyComponentCompiler.", "0.13.10")
class ComponentCompiler(compiler: RawCompiler, manager: ComponentManager) {
import ComponentCompiler._
def apply(id: String): File =
@ -87,53 +79,6 @@ class ComponentCompiler(compiler: RawCompiler, manager: ComponentManager) {
}
}
/**
* Compiles the compiler bridge using the source extracted from the resources on classpath.
*/
private[compiler] class ResourceComponentCompiler(compiler: RawCompiler, manager: ComponentManager, sourceJarName: String, log: Logger) {
import ComponentCompiler._
def apply(): File = {
val binID = "bridge-from-resource" + binSeparator + compiler.scalaInstance.actualVersion + "__" + javaVersion
manager.file(binID)(new IfMissing.Define(true, compileAndInstall(binID)))
}
private def copyFromResources(destinationDirectory: File, fileName: String): File = {
Option(getClass.getClassLoader.getResourceAsStream(sourceJarName)) match {
case Some(stream) =>
val copiedFile = new File(destinationDirectory, fileName)
val out = new java.io.FileOutputStream(copiedFile)
var read = 0
val content = new Array[Byte](1024)
while ({ read = stream.read(content); read != -1 }) {
out.write(content, 0, read)
}
copiedFile
case None =>
throw new InvalidComponent(s"Could not find '$fileName' on resources path.")
}
}
private def compileAndInstall(binID: String): Unit =
IO.withTemporaryDirectory { binaryDirectory =>
val targetJar = new File(binaryDirectory, s"$binID.jar")
val xsbtiJars = manager.files(xsbtiID)(IfMissing.Fail)
IO.withTemporaryDirectory { tempDirectory =>
val sourceJar = copyFromResources(tempDirectory, sourceJarName)
AnalyzingCompiler.compileSources(Seq(sourceJar), targetJar, xsbtiJars, "bridge-from-resources", compiler, log)
manager.define(binID, Seq(targetJar))
}
}
}
/**
* Component compiler which is able to to retrieve the compiler bridge sources
* `sourceModule` using Ivy.

View File

@ -69,11 +69,7 @@ object Compiler {
}
compilers(instance, cpOptions, CheaterJavaTool(javac2, javac))
}
@deprecated("Use `compilers(ScalaInstance, ClasspathOptions, Option[File], CompilerBridgeProvider)`.", "0.13.12")
def compilers(instance: ScalaInstance, cpOptions: ClasspathOptions, javaHome: Option[File], ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID)(implicit app: AppConfiguration, log: Logger): Compilers =
compilers(instance, cpOptions, javaHome, sbt.compiler.IvyBridgeProvider(ivyConfiguration, sourcesModule))(app, log)
def compilers(instance: ScalaInstance, cpOptions: ClasspathOptions, javaHome: Option[File], compilerBridgeProvider: CompilerBridgeProvider)(implicit app: AppConfiguration, log: Logger): Compilers =
{
val javac =
AggressiveCompile.directOrFork(instance, cpOptions, javaHome)
@ -85,7 +81,7 @@ object Compiler {
javac.compile(contract, sources, classpath, outputDirectory, options)(log)
def onArgs(f: Seq[String] => Unit): JavaTool = CheaterJavaTool(newJavac, delegate.onArgs(f))
}
val scalac = scalaCompiler(instance, cpOptions, compilerBridgeProvider)
val scalac = scalaCompiler(instance, cpOptions, ivyConfiguration, sourcesModule)
new Compilers(scalac, CheaterJavaTool(javac2, javac))
}
@deprecated("Deprecated in favor of new sbt.compiler.javac package.", "0.13.8")
@ -100,7 +96,7 @@ object Compiler {
val scalac = scalaCompiler(instance, cpOptions)
new Compilers(scalac, javac)
}
@deprecated("Use `scalaCompiler(ScalaInstance, ClasspathOptions, CompilerBridgeProvider)`.", "0.13.12")
@deprecated("Use `scalaCompiler(ScalaInstance, ClasspathOptions, IvyConfiguration, ModuleID)`.", "0.13.10")
def scalaCompiler(instance: ScalaInstance, cpOptions: ClasspathOptions)(implicit app: AppConfiguration, log: Logger): AnalyzingCompiler =
{
val launcher = app.provider.scalaProvider.launcher
@ -108,15 +104,11 @@ object Compiler {
val provider = ComponentCompiler.interfaceProvider(componentManager)
new AnalyzingCompiler(instance, provider, cpOptions)
}
@deprecated("Use `scalaCompiler(ScalaInstance, ClasspathOptions, CompilerBridgeProvider)`.", "0.13.12")
def scalaCompiler(instance: ScalaInstance, cpOptions: ClasspathOptions, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID)(implicit app: AppConfiguration, log: Logger): AnalyzingCompiler =
scalaCompiler(instance, cpOptions, sbt.compiler.IvyBridgeProvider(ivyConfiguration, sourcesModule))(app, log)
def scalaCompiler(instance: ScalaInstance, cpOptions: ClasspathOptions, compilerBridgeProvider: CompilerBridgeProvider)(implicit app: AppConfiguration, log: Logger): AnalyzingCompiler =
{
val launcher = app.provider.scalaProvider.launcher
val componentManager = new ComponentManager(launcher.globalLock, app.provider.components, Option(launcher.ivyHome), log)
val provider = ComponentCompiler.interfaceProvider(componentManager, compilerBridgeProvider)
val provider = ComponentCompiler.interfaceProvider(componentManager, ivyConfiguration, sourcesModule)
new AnalyzingCompiler(instance, provider, cpOptions)
}

View File

@ -16,8 +16,8 @@ object ConsoleProject {
val scalaProvider = state.configuration.provider.scalaProvider
ScalaInstance(scalaProvider.version, scalaProvider.launcher)
}
val (_, sourcesModule) = extracted.runTask(Keys.compilerBridgeProvider, state)
val compiler = Compiler.scalaCompiler(scalaInstance, ClasspathOptions.repl, sourcesModule)(state.configuration, log)
val sourcesModule = extracted.get(Keys.scalaCompilerBridgeSource)
val compiler = Compiler.scalaCompiler(scalaInstance, ClasspathOptions.repl, ivyConf, sourcesModule)(state.configuration, log)
val imports = BuildUtil.getImports(unit.unit) ++ BuildUtil.importAll(bindings.map(_._1))
val importString = imports.mkString("", ";\n", ";\n\n")
val initCommands = importString + extra

View File

@ -18,7 +18,7 @@ import CrossVersion.{ binarySbtVersion, binaryScalaVersion, partialVersion }
import complete._
import std.TaskExtra._
import sbt.inc.{ Analysis, FileValueCache, IncOptions, Locate }
import sbt.compiler.{ MixedAnalyzingCompiler, AggressiveCompile, IvyBridgeProvider }
import sbt.compiler.{ MixedAnalyzingCompiler, AggressiveCompile }
import testing.{ Framework, Runner, AnnotatedFingerprint, SubclassFingerprint }
import sys.error
@ -235,8 +235,7 @@ object Defaults extends BuildCommon {
val _ = clean.value
IvyActions.cleanCachedResolutionCache(ivyModule.value, streams.value.log)
},
scalaCompilerBridgeSource := ModuleID(xsbti.ArtifactInfo.SbtOrganization, "compiler-interface", sbtVersion.value, Some("component")).sources(),
compilerBridgeProvider := IvyBridgeProvider(bootIvyConfiguration.value, scalaCompilerBridgeSource.value)
scalaCompilerBridgeSource := ModuleID(xsbti.ArtifactInfo.SbtOrganization, "compiler-interface", sbtVersion.value, Some("component")).sources()
)
// must be a val: duplication detected by object identity
private[this] lazy val compileBaseGlobal: Seq[Setting[_]] = globalDefaults(Seq(
@ -266,7 +265,7 @@ object Defaults extends BuildCommon {
}
def compilersSetting = compilers := Compiler.compilers(scalaInstance.value, classpathOptions.value, javaHome.value,
compilerBridgeProvider.value)(appConfiguration.value, streams.value.log)
bootIvyConfiguration.value, scalaCompilerBridgeSource.value)(appConfiguration.value, streams.value.log)
lazy val configTasks = docTaskSettings(doc) ++ inTask(compile)(compileInputsSettings) ++ configGlobal ++ compileAnalysisSettings ++ Seq(
compile <<= compileTask,

View File

@ -21,8 +21,6 @@ import Configurations.CompilerPlugin
import Types.Id
import KeyRanks._
import sbt.compiler.CompilerBridgeProvider
object Keys {
val TraceValues = "-1 to disable, 0 for up to the first sbt frame, or a positive number to set the maximum number of frames shown."
@ -140,7 +138,6 @@ object Keys {
val printWarnings = TaskKey[Unit]("print-warnings", "Shows warnings from compilation, including ones that weren't printed initially.", BPlusTask)
val fileInputOptions = SettingKey[Seq[String]]("file-input-options", "Options that take file input, which may invalidate the cache.", CSetting)
val scalaCompilerBridgeSource = SettingKey[ModuleID]("scala-compiler-bridge-source", "Configures the module ID of the sources of the compiler bridge.", CSetting)
val compilerBridgeProvider = TaskKey[CompilerBridgeProvider]("compiler-bridge-provider", "Configures how sbt will retrieve the compiler bridge.", CTask)
val clean = TaskKey[Unit]("clean", "Deletes files produced by the build, such as generated sources, compiled classes, and task caches.", APlusTask)
val console = TaskKey[Unit]("console", "Starts the Scala interpreter with the project classes on the classpath.", APlusTask)