diff --git a/internal/compile-ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala b/internal/compile-ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala index a2dced311..057da6bd9 100644 --- a/internal/compile-ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala +++ b/internal/compile-ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala @@ -31,13 +31,13 @@ object ComponentCompiler { } } - def interfaceProvider(manager: ComponentManager, ivyConfiguration: IvyConfiguration, bootDirectory: File): CompilerInterfaceProvider = new CompilerInterfaceProvider { + def interfaceProvider(manager: ComponentManager, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID, bootDirectory: File): CompilerInterfaceProvider = new CompilerInterfaceProvider { def apply(scalaInstance: xsbti.compile.ScalaInstance, log: Logger): File = { // this is the instance used to compile the interface component - val componentCompiler = new IvyComponentCompiler(new RawCompiler(scalaInstance, ClasspathOptions.auto, log), manager, ivyConfiguration, bootDirectory, log) - log.debug("Getting " + compilerInterfaceID + " from component compiler for Scala " + scalaInstance.version) - componentCompiler(compilerInterfaceID) + val componentCompiler = new IvyComponentCompiler(new RawCompiler(scalaInstance, ClasspathOptions.auto, log), manager, ivyConfiguration, sourcesModule, bootDirectory, log) + log.debug("Getting " + sourcesModule + " from component compiler for Scala " + scalaInstance.version) + componentCompiler() } } @@ -92,12 +92,12 @@ class ComponentCompiler(compiler: RawCompiler, manager: ComponentManager) { } /** - * Component compiler which is able to find the most specific version available of - * the compiler interface sources using Ivy. + * Component compiler which is able to to retrieve the compiler bridge sources + * `sourceModule` using Ivy. * The compiled classes are cached using the provided component manager according * to the actualVersion field of the RawCompiler. */ -private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: ComponentManager, ivyConfiguration: IvyConfiguration, bootDirectory: File, log: Logger) { +private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: ComponentManager, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID, bootDirectory: File, log: Logger) { import ComponentCompiler._ private val incrementalCompilerOrg = xsbti.ArtifactInfo.SbtOrganization + ".incrementalcompiler" @@ -105,11 +105,11 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com private val modulePrefixTemp = "temp-module-" private val ivySbt: IvySbt = new IvySbt(ivyConfiguration) private val buffered = new BufferedLogger(FullLogger(log)) - private val retrieveDirectory = new File(s"$bootDirectory/scala-${compiler.scalaInstance.version}/$incrementalCompilerOrg/sbt/$incrementalVersion/compiler-interface-srcs") + private val retrieveDirectory = new File(s"$bootDirectory/scala-${compiler.scalaInstance.version}/$incrementalCompilerOrg/sbt/$incrementalVersion/compiler-interface-srcs/${sourcesModule.name}/${sourcesModule.revision}") - def apply(id: String): File = { - val binID = binaryID(id) - manager.file(binID)(new IfMissing.Define(true, compileAndInstall(id, binID))) + def apply(): File = { + val binID = binaryID(sourcesModule.name) + manager.file(binID)(new IfMissing.Define(true, compileAndInstall(binID))) } private def binaryID(id: String): String = { @@ -117,53 +117,32 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com base + "__" + javaVersion } - private def compileAndInstall(id: String, binID: String): Unit = { - def interfaceSources(moduleVersions: Vector[VersionNumber]): Iterable[File] = - moduleVersions match { - case Vector() => - def getAndDefineDefaultSources() = - update(getModule(id))(_.getName endsWith "-sources.jar") map { sourcesJar => - manager.define(id, sourcesJar) - sourcesJar - } getOrElse (throw new InvalidComponent(s"Couldn't retrieve default sources: module '$id'")) - - buffered.debug(s"Fetching default sources: module '$id'") - manager.files(id)(new IfMissing.Fallback(getAndDefineDefaultSources())) - - case version +: rest => - val moduleName = s"${id}_$version" - def getAndDefineVersionSpecificSources() = - update(getModule(moduleName))(_.getName endsWith "-sources.jar") map { sourcesJar => - manager.define(moduleName, sourcesJar) - sourcesJar - } getOrElse interfaceSources(rest) - - buffered.debug(s"Fetching version-specific sources: module '$moduleName'") - manager.files(moduleName)(new IfMissing.Fallback(getAndDefineVersionSpecificSources())) - } + private def compileAndInstall(binID: String): Unit = IO.withTemporaryDirectory { binaryDirectory => val targetJar = new File(binaryDirectory, s"$binID.jar") val xsbtiJars = manager.files(xsbtiID)(IfMissing.Fail) - val sourceModuleVersions = VersionNumber(compiler.scalaInstance.actualVersion).cascadingVersions - val sources = buffered bufferQuietly interfaceSources(sourceModuleVersions) - AnalyzingCompiler.compileSources(sources, targetJar, xsbtiJars, id, compiler, log) - - manager.define(binID, Seq(targetJar)) + buffered bufferQuietly { + (update(getModule(sourcesModule))(_.getName endsWith "-sources.jar")) match { + case Some(sources) => + AnalyzingCompiler.compileSources(sources, targetJar, xsbtiJars, sourcesModule.name, compiler, log) + manager.define(binID, Seq(targetJar)) + case None => + throw new InvalidComponent(s"Couldn't retrieve source module: $sourcesModule") + } + } } - } /** - * Returns a dummy module that depends on "org.scala-sbt" % `id` % `incrementalVersion`. + * Returns a dummy module that depends on `moduleID`. * Note: Sbt's implementation of Ivy requires us to do this, because only the dependencies * of the specified module will be downloaded. */ - private def getModule(id: String): ivySbt.Module = { - val sha1 = Hash.toHex(Hash(id)) - val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, incrementalVersion, Some("component")) - val moduleID = ModuleID(xsbti.ArtifactInfo.SbtOrganization + ".incrementalcompiler", id, incrementalVersion, Some("component")).sources() + private def getModule(moduleID: ModuleID): ivySbt.Module = { + val sha1 = Hash.toHex(Hash(moduleID.name)) + val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, moduleID.revision, moduleID.configurations) getModule(dummyID, Seq(moduleID)) }