From 1e2617a8074a5810adef4bccfba6f521b96508cb Mon Sep 17 00:00:00 2001 From: David Perez Date: Tue, 1 Sep 2015 14:16:41 +0200 Subject: [PATCH 1/6] More robustness when using the tasks and settings command --- main/src/main/scala/sbt/Main.scala | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index f2fe6ff6b..e66b0cc1f 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -16,6 +16,7 @@ import StandardMain._ import java.io.File import java.net.URI import java.util.Locale +import scala.util.control.NonFatal /** This class is the entry point for sbt.*/ final class xMain extends xsbti.AppMain { @@ -177,7 +178,15 @@ object BuiltinCommands { val extracted = Project.extract(s) import extracted._ val index = structure.index - index.keyIndex.keys(Some(currentRef)).toSeq.map(index.keyMap).distinct + index.keyIndex.keys(Some(currentRef)).toSeq.map { key => + try + Some(index.keyMap(key)) + catch { + case NonFatal(ex) => + s.log error ex.getMessage + None + } + }.collect { case Some(s) => s }.distinct } def sortByLabel(keys: Seq[AttributeKey[_]]): Seq[AttributeKey[_]] = keys.sortBy(_.label) From dcad8a552709ff477c5db05c18f89a21cf0d937b Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Fri, 4 Sep 2015 11:17:27 +0200 Subject: [PATCH 2/6] Specify the compiler bridge module in a setting In order to restore reproducibility of builds, we no longer cascade over the possibly available versions of the compiler bridge sources (a specific version of the bridge sources may not be available one day, but exist on the next day), but rather let the build definition configure which module to use. Fixes sbt/sbt#2196 --- .../sbt/compiler/ComponentCompiler.scala | 71 +++++++------------ ivy/src/main/scala/sbt/ComponentManager.scala | 3 - .../actions/src/main/scala/sbt/Compiler.scala | 8 +-- main/src/main/scala/sbt/Defaults.scala | 5 +- main/src/main/scala/sbt/Keys.scala | 1 + 5 files changed, 33 insertions(+), 55 deletions(-) diff --git a/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala b/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala index ba478ea61..a93f91deb 100644 --- a/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala +++ b/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala @@ -26,13 +26,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() } } } @@ -80,12 +80,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 sbtOrg = xsbti.ArtifactInfo.SbtOrganization @@ -94,11 +94,11 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com private val ivySbt: IvySbt = new IvySbt(ivyConfiguration) private val sbtVersion = ComponentManager.version private val buffered = new BufferedLogger(FullLogger(log)) - private val retrieveDirectory = new File(s"$bootDirectory/scala-${compiler.scalaInstance.version}/$sbtOrg/sbt/$sbtVersion/compiler-interface-srcs") + private val retrieveDirectory = new File(s"$bootDirectory/scala-${compiler.scalaInstance.version}/$sbtOrg/sbt/$sbtVersion/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 = { @@ -106,53 +106,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` % `sbtVersion`. + * 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, sbtVersion, Some("component")) - val moduleID = ModuleID(sbtOrg, id, sbtVersion, 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)) } diff --git a/ivy/src/main/scala/sbt/ComponentManager.scala b/ivy/src/main/scala/sbt/ComponentManager.scala index bdf78b9ec..f546295a9 100644 --- a/ivy/src/main/scala/sbt/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/ComponentManager.scala @@ -39,8 +39,6 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr d() if (d.cache) cache(id) getOrElse(notFound) - case f: IfMissing.Fallback => - f() } lockLocalCache { getOrElse(fromGlobal) } @@ -75,7 +73,6 @@ sealed trait IfMissing extends NotNull object IfMissing { object Fail extends IfMissing final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define } - final class Fallback(f: => Iterable[File]) extends IfMissing { def apply() = f } } object ComponentManager { lazy val (version, timestamp) = diff --git a/main/actions/src/main/scala/sbt/Compiler.scala b/main/actions/src/main/scala/sbt/Compiler.scala index 5953c2a54..41c9214b7 100644 --- a/main/actions/src/main/scala/sbt/Compiler.scala +++ b/main/actions/src/main/scala/sbt/Compiler.scala @@ -69,7 +69,7 @@ object Compiler { } compilers(instance, cpOptions, CheaterJavaTool(javac2, javac)) } - def compilers(instance: ScalaInstance, cpOptions: ClasspathOptions, javaHome: Option[File], ivyConfiguration: IvyConfiguration)(implicit app: AppConfiguration, log: Logger): Compilers = + def compilers(instance: ScalaInstance, cpOptions: ClasspathOptions, javaHome: Option[File], ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID)(implicit app: AppConfiguration, log: Logger): Compilers = { val javac = AggressiveCompile.directOrFork(instance, cpOptions, javaHome) @@ -81,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, ivyConfiguration) + 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") @@ -104,12 +104,12 @@ object Compiler { val provider = ComponentCompiler.interfaceProvider(componentManager) new AnalyzingCompiler(instance, provider, cpOptions) } - def scalaCompiler(instance: ScalaInstance, cpOptions: ClasspathOptions, ivyConfiguration: IvyConfiguration)(implicit app: AppConfiguration, log: Logger): AnalyzingCompiler = + def scalaCompiler(instance: ScalaInstance, cpOptions: ClasspathOptions, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID)(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 bootDirectory = launcher.bootDirectory - val provider = ComponentCompiler.interfaceProvider(componentManager, ivyConfiguration, bootDirectory) + val provider = ComponentCompiler.interfaceProvider(componentManager, ivyConfiguration, sourcesModule, bootDirectory) new AnalyzingCompiler(instance, provider, cpOptions) } diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 9904ee22e..844f8719b 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -232,7 +232,8 @@ object Defaults extends BuildCommon { clean := { val _ = clean.value IvyActions.cleanCachedResolutionCache(ivyModule.value, streams.value.log) - } + }, + 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( @@ -261,7 +262,7 @@ object Defaults extends BuildCommon { if (plugin) scalaBase / ("sbt-" + sbtv) else scalaBase } - def compilersSetting = compilers := Compiler.compilers(scalaInstance.value, classpathOptions.value, javaHome.value, ivyConfiguration.value)(appConfiguration.value, streams.value.log) + def compilersSetting = compilers := Compiler.compilers(scalaInstance.value, classpathOptions.value, javaHome.value, ivyConfiguration.value, scalaCompilerBridgeSource.value)(appConfiguration.value, streams.value.log) lazy val configTasks = docTaskSettings(doc) ++ inTask(compile)(compileInputsSettings) ++ configGlobal ++ compileAnalysisSettings ++ Seq( compile <<= compileTask, diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index b5f1d96de..42fa4f659 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -137,6 +137,7 @@ object Keys { val sbtPlugin = SettingKey[Boolean]("sbt-plugin", "If true, enables adding sbt as a dependency and auto-generation of the plugin descriptor file.", BMinusSetting) 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 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) From 1c4a900ff5c8bdc49bd21d622a0eb526b0a4eb25 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Fri, 4 Sep 2015 12:00:44 +0200 Subject: [PATCH 3/6] Retrieve compiler bridge sources in temp directory Note that they won't be downloaded again, because the component compiler will look for a previously-compiled version of the compiler bridge before trying to fetch the sources again. If they've already been downlaoded, then they have been compiled and a compiled version of the compiler bridge already exists. --- .../sbt/compiler/ComponentCompiler.scala | 25 +++++++++++-------- .../actions/src/main/scala/sbt/Compiler.scala | 3 +-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala b/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala index a93f91deb..de0c9d692 100644 --- a/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala +++ b/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala @@ -26,11 +26,11 @@ object ComponentCompiler { } } - def interfaceProvider(manager: ComponentManager, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID, bootDirectory: File): CompilerInterfaceProvider = new CompilerInterfaceProvider { + def interfaceProvider(manager: ComponentManager, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID): 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, sourcesModule, bootDirectory, log) + 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() } @@ -85,7 +85,7 @@ class ComponentCompiler(compiler: RawCompiler, manager: ComponentManager) { * 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, sourcesModule: ModuleID, bootDirectory: File, log: Logger) { +private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: ComponentManager, ivyConfiguration: IvyConfiguration, sourcesModule: ModuleID, log: Logger) { import ComponentCompiler._ private val sbtOrg = xsbti.ArtifactInfo.SbtOrganization @@ -94,7 +94,6 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com private val ivySbt: IvySbt = new IvySbt(ivyConfiguration) private val sbtVersion = ComponentManager.version private val buffered = new BufferedLogger(FullLogger(log)) - private val retrieveDirectory = new File(s"$bootDirectory/scala-${compiler.scalaInstance.version}/$sbtOrg/sbt/$sbtVersion/compiler-interface-srcs/${sourcesModule.name}/${sourcesModule.revision}") def apply(): File = { val binID = binaryID(sourcesModule.name) @@ -113,14 +112,18 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com val xsbtiJars = manager.files(xsbtiID)(IfMissing.Fail) 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") + IO.withTemporaryDirectory { retrieveDirectory => + (update(getModule(sourcesModule), retrieveDirectory)(_.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") + } } + } } @@ -158,7 +161,7 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com s"unknown" } - private def update(module: ivySbt.Module)(predicate: File => Boolean): Option[Seq[File]] = { + private def update(module: ivySbt.Module, retrieveDirectory: File)(predicate: File => Boolean): Option[Seq[File]] = { val retrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, Resolver.defaultRetrievePattern, false) val updateConfiguration = new UpdateConfiguration(Some(retrieveConfiguration), true, UpdateLogging.DownloadOnly) diff --git a/main/actions/src/main/scala/sbt/Compiler.scala b/main/actions/src/main/scala/sbt/Compiler.scala index 41c9214b7..9349e422a 100644 --- a/main/actions/src/main/scala/sbt/Compiler.scala +++ b/main/actions/src/main/scala/sbt/Compiler.scala @@ -108,8 +108,7 @@ object Compiler { { val launcher = app.provider.scalaProvider.launcher val componentManager = new ComponentManager(launcher.globalLock, app.provider.components, Option(launcher.ivyHome), log) - val bootDirectory = launcher.bootDirectory - val provider = ComponentCompiler.interfaceProvider(componentManager, ivyConfiguration, sourcesModule, bootDirectory) + val provider = ComponentCompiler.interfaceProvider(componentManager, ivyConfiguration, sourcesModule) new AnalyzingCompiler(instance, provider, cpOptions) } From 152b040fe3ee3ecda9de3caf8388eb31b7a5dd17 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Fri, 4 Sep 2015 12:10:16 +0200 Subject: [PATCH 4/6] Rename binary form of compiler bridge This will avoid all clashes between modules that may have the same name as other components of sbt, or two different compiler bridges that would happen to have the same name. --- .../ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala b/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala index de0c9d692..5ce39e289 100644 --- a/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala +++ b/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala @@ -96,7 +96,8 @@ private[compiler] class IvyComponentCompiler(compiler: RawCompiler, manager: Com private val buffered = new BufferedLogger(FullLogger(log)) def apply(): File = { - val binID = binaryID(sourcesModule.name) + // binID is of the form "org.example-compilerbridge-1.0.0-bin_2.11.7__50.0" + val binID = binaryID(s"${sourcesModule.organization}-${sourcesModule.name}-${sourcesModule.revision}") manager.file(binID)(new IfMissing.Define(true, compileAndInstall(binID))) } From 92ea782d9449db523ec374028edb7070496ce7ea Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Fri, 4 Sep 2015 12:25:59 +0200 Subject: [PATCH 5/6] Fix deprecation messages --- .../ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala | 2 +- main/actions/src/main/scala/sbt/Compiler.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala b/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala index 5ce39e289..fa1d57f2d 100644 --- a/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala +++ b/compile/ivy/src/main/scala/sbt/compiler/ComponentCompiler.scala @@ -15,7 +15,7 @@ object ComponentCompiler { val compilerInterfaceSrcID = compilerInterfaceID + srcExtension val javaVersion = System.getProperty("java.class.version") - @deprecated("Use `interfaceProvider(ComponentManager, IvyConfiguration, File)`.", "0.13.10") + @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 = { diff --git a/main/actions/src/main/scala/sbt/Compiler.scala b/main/actions/src/main/scala/sbt/Compiler.scala index 9349e422a..062b11696 100644 --- a/main/actions/src/main/scala/sbt/Compiler.scala +++ b/main/actions/src/main/scala/sbt/Compiler.scala @@ -54,7 +54,7 @@ object Compiler { def compilers(instance: ScalaInstance, cpOptions: ClasspathOptions)(implicit app: AppConfiguration, log: Logger): Compilers = compilers(instance, cpOptions, None) - @deprecated("Use `compilers(ScalaInstance, ClasspathOptions, Option[File], IvyConfiguration)`.", "0.13.10") + @deprecated("Use `compilers(ScalaInstance, ClasspathOptions, Option[File], IvyConfiguration, ModuleID)`.", "0.13.10") def compilers(instance: ScalaInstance, cpOptions: ClasspathOptions, javaHome: Option[File])(implicit app: AppConfiguration, log: Logger): Compilers = { val javac = @@ -96,7 +96,7 @@ object Compiler { val scalac = scalaCompiler(instance, cpOptions) new Compilers(scalac, javac) } - @deprecated("Use `scalaCompiler(ScalaInstance, ClasspathOptions, IvyConfiguration)`.", "0.13.10") + @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 From cf8d7fbdff562f7c365c90ceab9cd0bf38100909 Mon Sep 17 00:00:00 2001 From: fkorotkov Date: Thu, 10 Sep 2015 16:35:09 -0700 Subject: [PATCH 6/6] Use getPosition method to get an offset position instead of using line number --- .../scala/sbt/compiler/javac/DiagnosticsReporter.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compile/src/main/scala/sbt/compiler/javac/DiagnosticsReporter.scala b/compile/src/main/scala/sbt/compiler/javac/DiagnosticsReporter.scala index 49c3fb54a..bb1b144e6 100644 --- a/compile/src/main/scala/sbt/compiler/javac/DiagnosticsReporter.scala +++ b/compile/src/main/scala/sbt/compiler/javac/DiagnosticsReporter.scala @@ -76,11 +76,12 @@ final class DiagnosticsReporter(reporter: Reporter) extends DiagnosticListener[J val diagnostic = d.getClass.getField("d").get(d) // See com.sun.tools.javac.util.JCDiagnostic#getDiagnosticSource val getDiagnosticSourceMethod = diagnostic.getClass.getDeclaredMethod("getDiagnosticSource") - Option(getDiagnosticSourceMethod.invoke(diagnostic)) match { - case Some(diagnosticSource) => + val getPositionMethod = diagnostic.getClass.getDeclaredMethod("getPosition") + (Option(getDiagnosticSourceMethod.invoke(diagnostic)), Option(getPositionMethod.invoke(diagnostic))) match { + case (Some(diagnosticSource), Some(position: java.lang.Long)) => // See com.sun.tools.javac.util.DiagnosticSource val getLineMethod = diagnosticSource.getClass.getMethod("getLine", Integer.TYPE) - Option(getLineMethod.invoke(diagnosticSource, line.get())).map(_.toString) + Option(getLineMethod.invoke(diagnosticSource, new Integer(position.intValue()))).map(_.toString) case _ => None } } catch {