mirror of https://github.com/sbt/sbt.git
Resolve Scala version for projects in the normal `update` task.
1. Scala jars won't be copied to the boot directory, except for those needed to run sbt. 2. Scala SNAPSHOTs behave like normal SNAPSHOTs. In particular, running `update` will properly re-resolve the dynamic revision. 3. Scala jars are resolved using the same repositories and configuration as other dependencies. 4. Classloaders (currently, Scala classloaders) are cached by the timestamps of entries instead of Scala class loaders being cached by version. TODO: Support external dependency configuration
This commit is contained in:
parent
4cc5bece70
commit
e47a357ab7
|
|
@ -347,7 +347,7 @@ object Configurations
|
||||||
def default: Seq[Configuration] = defaultMavenConfigurations
|
def default: Seq[Configuration] = defaultMavenConfigurations
|
||||||
def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional)
|
def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional)
|
||||||
def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal)
|
def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal)
|
||||||
def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom)
|
def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom, ScalaTool)
|
||||||
def names(cs: Seq[Configuration]) = cs.map(_.name)
|
def names(cs: Seq[Configuration]) = cs.map(_.name)
|
||||||
|
|
||||||
lazy val RuntimeInternal = optionalInternal(Runtime)
|
lazy val RuntimeInternal = optionalInternal(Runtime)
|
||||||
|
|
@ -379,6 +379,7 @@ object Configurations
|
||||||
lazy val Optional = config("optional")
|
lazy val Optional = config("optional")
|
||||||
lazy val Pom = config("pom")
|
lazy val Pom = config("pom")
|
||||||
|
|
||||||
|
lazy val ScalaTool = config("scala-tool") hide
|
||||||
lazy val CompilerPlugin = config("plugin") hide
|
lazy val CompilerPlugin = config("plugin") hide
|
||||||
|
|
||||||
private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true)
|
private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true)
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,16 @@ object Defaults extends BuildCommon
|
||||||
{
|
{
|
||||||
final val CacheDirectoryName = "cache"
|
final val CacheDirectoryName = "cache"
|
||||||
|
|
||||||
|
private[sbt] def scalaToolDependencies(org: String, version: String): Seq[ModuleID] = Seq(
|
||||||
|
scalaToolDependency(org, ScalaArtifacts.CompilerID, version),
|
||||||
|
scalaToolDependency(org, ScalaArtifacts.LibraryID, version)
|
||||||
|
)
|
||||||
|
private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID =
|
||||||
|
ModuleID(org, id, version, Some(Configurations.ScalaTool.name + "->default,optional(default)") )
|
||||||
|
|
||||||
def configSrcSub(key: SettingKey[File]): Initialize[File] = (key in ThisScope.copy(config = Global), configuration) { (src, conf) => src / nameForSrc(conf.name) }
|
def configSrcSub(key: SettingKey[File]): Initialize[File] = (key in ThisScope.copy(config = Global), configuration) { (src, conf) => src / nameForSrc(conf.name) }
|
||||||
def nameForSrc(config: String) = if(config == "compile") "main" else config
|
def nameForSrc(config: String) = if(config == Configurations.Compile.name) "main" else config
|
||||||
def prefix(config: String) = if(config == "compile") "" else config + "-"
|
def prefix(config: String) = if(config == Configurations.Compile.name) "" else config + "-"
|
||||||
|
|
||||||
def lock(app: xsbti.AppConfiguration): xsbti.GlobalLock = app.provider.scalaProvider.launcher.globalLock
|
def lock(app: xsbti.AppConfiguration): xsbti.GlobalLock = app.provider.scalaProvider.launcher.globalLock
|
||||||
|
|
||||||
|
|
@ -199,7 +206,7 @@ object Defaults extends BuildCommon
|
||||||
compilersSetting,
|
compilersSetting,
|
||||||
javacOptions in GlobalScope :== Nil,
|
javacOptions in GlobalScope :== Nil,
|
||||||
scalacOptions in GlobalScope :== Nil,
|
scalacOptions in GlobalScope :== Nil,
|
||||||
scalaInstance <<= scalaInstanceSetting,
|
scalaInstance <<= scalaInstanceTask,
|
||||||
scalaVersion in GlobalScope := appConfiguration.value.provider.scalaProvider.version,
|
scalaVersion in GlobalScope := appConfiguration.value.provider.scalaProvider.version,
|
||||||
scalaBinaryVersion in GlobalScope := binaryScalaVersion(scalaVersion.value),
|
scalaBinaryVersion in GlobalScope := binaryScalaVersion(scalaVersion.value),
|
||||||
crossVersion := (if(crossPaths.value) CrossVersion.binary else CrossVersion.Disabled),
|
crossVersion := (if(crossPaths.value) CrossVersion.binary else CrossVersion.Disabled),
|
||||||
|
|
@ -270,13 +277,37 @@ object Defaults extends BuildCommon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def scalaInstanceSetting = (appConfiguration, scalaOrganization, scalaVersion, scalaHome) map { (app, org, version, home) =>
|
@deprecated("Use scalaInstanceTask.", "0.13.0")
|
||||||
val launcher = app.provider.scalaProvider.launcher
|
def scalaInstanceSetting = scalaInstanceTask
|
||||||
home match {
|
def scalaInstanceTask: Initialize[Task[ScalaInstance]] = Def.taskDyn {
|
||||||
case None => ScalaInstance(org, version, launcher)
|
scalaHome.value match {
|
||||||
case Some(h) => ScalaInstance(h, launcher)
|
case Some(h) => scalaInstanceFromHome(h)
|
||||||
|
case None =>
|
||||||
|
val scalaProvider = appConfiguration.value.provider.scalaProvider
|
||||||
|
val version = scalaVersion.value
|
||||||
|
if(version == scalaProvider.version) // use the same class loader as the Scala classes used by sbt
|
||||||
|
Def.task( ScalaInstance(version, scalaProvider) )
|
||||||
|
else
|
||||||
|
scalaInstanceFromUpdate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
def scalaInstanceFromUpdate: Initialize[Task[ScalaInstance]] = Def.task {
|
||||||
|
val toolReport = update.value.configuration(Configurations.ScalaTool.name) getOrElse error("Missing Scala tool configuration.")
|
||||||
|
def files(id: String) =
|
||||||
|
for { m <- toolReport.modules if m.module.name == id;
|
||||||
|
(art, file) <- m.artifacts if art.`type` == Artifact.DefaultType }
|
||||||
|
yield file
|
||||||
|
def file(id: String) = files(id).headOption getOrElse error(s"Missing ${id}.jar")
|
||||||
|
val allFiles = toolReport.modules.flatMap(_.artifacts.map(_._2))
|
||||||
|
val libraryJar = file(ScalaArtifacts.LibraryID)
|
||||||
|
val compilerJar = file(ScalaArtifacts.CompilerID)
|
||||||
|
val otherJars = allFiles.filterNot(x => x == libraryJar || x == compilerJar)
|
||||||
|
ScalaInstance(scalaVersion.value, libraryJar, compilerJar, otherJars : _*)(makeClassLoader(state.value))
|
||||||
|
}
|
||||||
|
def scalaInstanceFromHome(dir: File): Initialize[Task[ScalaInstance]] = Def.task {
|
||||||
|
ScalaInstance(dir)(makeClassLoader(state.value))
|
||||||
|
}
|
||||||
|
private[this] def makeClassLoader(state: State) = state.classLoaderCache.apply _
|
||||||
|
|
||||||
lazy val testTasks: Seq[Setting[_]] = testTaskOptions(test) ++ testTaskOptions(testOnly) ++ testTaskOptions(testQuick) ++ Seq(
|
lazy val testTasks: Seq[Setting[_]] = testTaskOptions(test) ++ testTaskOptions(testOnly) ++ testTaskOptions(testQuick) ++ Seq(
|
||||||
testLoader := TestFramework.createTestLoader(data(fullClasspath.value), scalaInstance.value, IO.createUniqueDirectory(taskTemporaryDirectory.value)),
|
testLoader := TestFramework.createTestLoader(data(fullClasspath.value), scalaInstance.value, IO.createUniqueDirectory(taskTemporaryDirectory.value)),
|
||||||
|
|
@ -807,16 +838,20 @@ object Classpaths
|
||||||
projectDependencies <<= projectDependenciesTask,
|
projectDependencies <<= projectDependenciesTask,
|
||||||
dependencyOverrides in GlobalScope :== Set.empty,
|
dependencyOverrides in GlobalScope :== Set.empty,
|
||||||
libraryDependencies in GlobalScope :== Nil,
|
libraryDependencies in GlobalScope :== Nil,
|
||||||
libraryDependencies <++= (autoScalaLibrary, sbtPlugin, scalaVersion) apply autoLibraryDependency,
|
libraryDependencies <++= (autoScalaLibrary, sbtPlugin, scalaOrganization, scalaVersion) apply autoLibraryDependency,
|
||||||
allDependencies <<= (projectDependencies,libraryDependencies,sbtPlugin,sbtDependency) map { (projDeps, libDeps, isPlugin, sbtDep) =>
|
allDependencies := {
|
||||||
val base = projDeps ++ libDeps
|
val base = projectDependencies.value ++ libraryDependencies.value
|
||||||
if(isPlugin) sbtDep.copy(configurations = Some(Provided.name)) +: base else base
|
val pluginAdjust = if(sbtPlugin.value) sbtDependency.value.copy(configurations = Some(Provided.name)) +: base else base
|
||||||
|
if(scalaHome.value.isDefined)
|
||||||
|
pluginAdjust
|
||||||
|
else
|
||||||
|
Defaults.scalaToolDependencies(scalaOrganization.value, scalaVersion.value) ++ pluginAdjust
|
||||||
},
|
},
|
||||||
ivyLoggingLevel in GlobalScope :== UpdateLogging.DownloadOnly,
|
ivyLoggingLevel in GlobalScope :== UpdateLogging.DownloadOnly,
|
||||||
ivyXML in GlobalScope :== NodeSeq.Empty,
|
ivyXML in GlobalScope :== NodeSeq.Empty,
|
||||||
ivyValidate in GlobalScope :== false,
|
ivyValidate in GlobalScope :== false,
|
||||||
ivyScala <<= ivyScala or (scalaHome, scalaVersion in update, scalaBinaryVersion in update) { (sh,fv,bv) =>
|
ivyScala <<= ivyScala or (scalaHome, scalaVersion in update, scalaBinaryVersion in update) { (sh,fv,bv) =>
|
||||||
Some(new IvyScala(fv, bv, Nil, filterImplicit = true, checkExplicit = true, overrideScalaVersion = sh.isEmpty))
|
Some(new IvyScala(fv, bv, Nil, filterImplicit = false, checkExplicit = true, overrideScalaVersion = sh.isEmpty))
|
||||||
},
|
},
|
||||||
moduleConfigurations in GlobalScope :== Nil,
|
moduleConfigurations in GlobalScope :== Nil,
|
||||||
publishTo in GlobalScope :== None,
|
publishTo in GlobalScope :== None,
|
||||||
|
|
@ -852,11 +887,11 @@ object Classpaths
|
||||||
ivySbt <<= ivySbt0,
|
ivySbt <<= ivySbt0,
|
||||||
ivyModule <<= (ivySbt, moduleSettings) map { (ivySbt, settings) => new ivySbt.Module(settings) },
|
ivyModule <<= (ivySbt, moduleSettings) map { (ivySbt, settings) => new ivySbt.Module(settings) },
|
||||||
transitiveUpdate <<= transitiveUpdateTask,
|
transitiveUpdate <<= transitiveUpdateTask,
|
||||||
update <<= (ivyModule, thisProjectRef, updateConfiguration, cacheDirectory, scalaInstance, transitiveUpdate, executionRoots, resolvedScoped, skip in update, streams) map {
|
update <<= (ivyModule, thisProjectRef, updateConfiguration, cacheDirectory, transitiveUpdate, executionRoots, resolvedScoped, skip in update, streams) map {
|
||||||
(module, ref, config, cacheDirectory, si, reports, roots, resolved, skip, s) =>
|
(module, ref, config, cacheDirectory, reports, roots, resolved, skip, s) =>
|
||||||
val depsUpdated = reports.exists(!_.stats.cached)
|
val depsUpdated = reports.exists(!_.stats.cached)
|
||||||
val isRoot = roots contains resolved
|
val isRoot = roots contains resolved
|
||||||
cachedUpdate(cacheDirectory / "update", Reference.display(ref), module, config, Some(si), skip = skip, force = isRoot, depsUpdated = depsUpdated, log = s.log)
|
cachedUpdate(cacheDirectory / "update", Reference.display(ref), module, config, None, skip = skip, force = isRoot, depsUpdated = depsUpdated, log = s.log)
|
||||||
} tag(Tags.Update, Tags.Network),
|
} tag(Tags.Update, Tags.Network),
|
||||||
update <<= (conflictWarning, update, streams) map { (config, report, s) => ConflictWarning(config, report, s.log); report },
|
update <<= (conflictWarning, update, streams) map { (config, report, s) => ConflictWarning(config, report, s.log); report },
|
||||||
transitiveClassifiers in GlobalScope :== Seq(SourceClassifier, DocClassifier),
|
transitiveClassifiers in GlobalScope :== Seq(SourceClassifier, DocClassifier),
|
||||||
|
|
@ -1155,11 +1190,18 @@ object Classpaths
|
||||||
|
|
||||||
def modifyForPlugin(plugin: Boolean, dep: ModuleID): ModuleID =
|
def modifyForPlugin(plugin: Boolean, dep: ModuleID): ModuleID =
|
||||||
if(plugin) dep.copy(configurations = Some(Provided.name)) else dep
|
if(plugin) dep.copy(configurations = Some(Provided.name)) else dep
|
||||||
|
|
||||||
|
@deprecated("Explicitly specify the organization using the other variant.", "0.13.0")
|
||||||
def autoLibraryDependency(auto: Boolean, plugin: Boolean, version: String): Seq[ModuleID] =
|
def autoLibraryDependency(auto: Boolean, plugin: Boolean, version: String): Seq[ModuleID] =
|
||||||
if(auto)
|
if(auto)
|
||||||
modifyForPlugin(plugin, ScalaArtifacts.libraryDependency(version)) :: Nil
|
modifyForPlugin(plugin, ScalaArtifacts.libraryDependency(version)) :: Nil
|
||||||
else
|
else
|
||||||
Nil
|
Nil
|
||||||
|
def autoLibraryDependency(auto: Boolean, plugin: Boolean, org: String, version: String): Seq[ModuleID] =
|
||||||
|
if(auto)
|
||||||
|
modifyForPlugin(plugin, ModuleID(org, ScalaArtifacts.LibraryID, version)) :: Nil
|
||||||
|
else
|
||||||
|
Nil
|
||||||
|
|
||||||
import DependencyFilter._
|
import DependencyFilter._
|
||||||
def managedJars(config: Configuration, jarTypes: Set[String], up: UpdateReport): Classpath =
|
def managedJars(config: Configuration, jarTypes: Set[String], up: UpdateReport): Classpath =
|
||||||
|
|
@ -1183,6 +1225,7 @@ object Classpaths
|
||||||
if(autoCompilerPlugins.value) options ++ autoPlugins(update.value) else options
|
if(autoCompilerPlugins.value) options ++ autoPlugins(update.value) else options
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@deprecated("Doesn't properly handle non-standard Scala organizations.", "0.13.0")
|
||||||
def substituteScalaFiles(scalaInstance: ScalaInstance, report: UpdateReport): UpdateReport =
|
def substituteScalaFiles(scalaInstance: ScalaInstance, report: UpdateReport): UpdateReport =
|
||||||
report.substitute { (configuration, module, arts) =>
|
report.substitute { (configuration, module, arts) =>
|
||||||
import ScalaArtifacts._
|
import ScalaArtifacts._
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,9 @@ object StandardMain
|
||||||
def initialState(configuration: xsbti.AppConfiguration, initialDefinitions: Seq[Command], preCommands: Seq[String]): State =
|
def initialState(configuration: xsbti.AppConfiguration, initialDefinitions: Seq[Command], preCommands: Seq[String]): State =
|
||||||
{
|
{
|
||||||
val commands = preCommands ++ configuration.arguments.map(_.trim)
|
val commands = preCommands ++ configuration.arguments.map(_.trim)
|
||||||
State( configuration, initialDefinitions, Set.empty, None, commands, State.newHistory, BuiltinCommands.initialAttributes, initialGlobalLogging, State.Continue )
|
val initAttrs = BuiltinCommands.initialAttributes
|
||||||
|
val s = State( configuration, initialDefinitions, Set.empty, None, commands, State.newHistory, initAttrs, initialGlobalLogging, State.Continue )
|
||||||
|
s.initializeClassLoaderCache
|
||||||
}
|
}
|
||||||
def initialGlobalLogging: GlobalLogging =
|
def initialGlobalLogging: GlobalLogging =
|
||||||
GlobalLogging.initial((pw, glb) => MainLogging.globalDefault(pw,glb,console), File.createTempFile("sbt",".log"), console)
|
GlobalLogging.initial((pw, glb) => MainLogging.globalDefault(pw,glb,console), File.createTempFile("sbt",".log"), console)
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,5 @@ object BasicKeys
|
||||||
val shellPrompt = AttributeKey[State => String]("shell-prompt", "The function that constructs the command prompt from the current build state.", 10000)
|
val shellPrompt = AttributeKey[State => String]("shell-prompt", "The function that constructs the command prompt from the current build state.", 10000)
|
||||||
val watch = AttributeKey[Watched]("watch", "Continuous execution configuration.", 1000)
|
val watch = AttributeKey[Watched]("watch", "Continuous execution configuration.", 1000)
|
||||||
private[sbt] val interactive = AttributeKey[Boolean]("interactive", "True if commands are currently being entered from an interactive environment.", 10)
|
private[sbt] val interactive = AttributeKey[Boolean]("interactive", "True if commands are currently being entered from an interactive environment.", 10)
|
||||||
|
private[sbt] val classLoaderCache = AttributeKey[classpath.ClassLoaderCache]("class-loader-cache", "Caches class loaders based on the classpath entries and last modified times.", 10)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,13 @@ trait Identity {
|
||||||
override final def toString = super.toString
|
override final def toString = super.toString
|
||||||
}
|
}
|
||||||
|
|
||||||
/** StateOps methods to be merged at the next binary incompatible release. */
|
/** StateOps methods to be merged at the next binary incompatible release (0.13.0). */
|
||||||
private[sbt] trait NewStateOps
|
private[sbt] trait NewStateOps
|
||||||
{
|
{
|
||||||
def interactive: Boolean
|
def interactive: Boolean
|
||||||
def setInteractive(flag: Boolean): State
|
def setInteractive(flag: Boolean): State
|
||||||
|
def classLoaderCache: classpath.ClassLoaderCache
|
||||||
|
def initializeClassLoaderCache: State
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Convenience methods for State transformations and operations. */
|
/** Convenience methods for State transformations and operations. */
|
||||||
|
|
@ -161,6 +163,9 @@ object State
|
||||||
private[sbt] implicit def newStateOps(s: State): NewStateOps = new NewStateOps {
|
private[sbt] implicit def newStateOps(s: State): NewStateOps = new NewStateOps {
|
||||||
def interactive = s.get(BasicKeys.interactive).getOrElse(false)
|
def interactive = s.get(BasicKeys.interactive).getOrElse(false)
|
||||||
def setInteractive(i: Boolean) = s.put(BasicKeys.interactive, i)
|
def setInteractive(i: Boolean) = s.put(BasicKeys.interactive, i)
|
||||||
|
def classLoaderCache: classpath.ClassLoaderCache = s get BasicKeys.classLoaderCache getOrElse newClassLoaderCache
|
||||||
|
def initializeClassLoaderCache = s.put(BasicKeys.classLoaderCache, newClassLoaderCache)
|
||||||
|
private[this] def newClassLoaderCache = new classpath.ClassLoaderCache(s.configuration.provider.scalaProvider.launcher.topLoader)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Provides operations and transformations on State. */
|
/** Provides operations and transformations on State. */
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package sbt.classpath
|
||||||
|
|
||||||
|
import java.lang.ref.{Reference, SoftReference}
|
||||||
|
import java.io.File
|
||||||
|
import java.net.URLClassLoader
|
||||||
|
import java.util.HashMap
|
||||||
|
|
||||||
|
private[sbt] final class ClassLoaderCache(val commonParent: ClassLoader)
|
||||||
|
{
|
||||||
|
private[this] val delegate = new HashMap[List[File],Reference[CachedClassLoader]]
|
||||||
|
def apply(files: List[File]): ClassLoader =
|
||||||
|
{
|
||||||
|
val tstamps = files.map(_.lastModified)
|
||||||
|
getFromReference(files, tstamps, delegate.get(files))
|
||||||
|
}
|
||||||
|
|
||||||
|
private[this] def getFromReference(files: List[File], stamps: List[Long], existingRef: Reference[CachedClassLoader]) =
|
||||||
|
if(existingRef eq null)
|
||||||
|
newEntry(files, stamps)
|
||||||
|
else
|
||||||
|
get(files, stamps, existingRef.get)
|
||||||
|
|
||||||
|
private[this] def get(files: List[File], stamps: List[Long], existing: CachedClassLoader): ClassLoader =
|
||||||
|
if(existing == null || stamps != existing.timestamps)
|
||||||
|
newEntry(files, stamps)
|
||||||
|
else
|
||||||
|
existing.loader
|
||||||
|
|
||||||
|
private[this] def newEntry(files: List[File], stamps: List[Long]): ClassLoader =
|
||||||
|
{
|
||||||
|
val loader = new URLClassLoader(files.map(_.toURI.toURL).toArray, commonParent)
|
||||||
|
delegate.put(files, new SoftReference(new CachedClassLoader(loader, files, stamps)))
|
||||||
|
loader
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private[sbt] final class CachedClassLoader(val loader: ClassLoader, val files: List[File], val timestamps: List[Long])
|
||||||
|
|
@ -46,18 +46,27 @@ object ScalaInstance
|
||||||
|
|
||||||
def apply(scalaHome: File, launcher: xsbti.Launcher): ScalaInstance =
|
def apply(scalaHome: File, launcher: xsbti.Launcher): ScalaInstance =
|
||||||
apply(libraryJar(scalaHome), compilerJar(scalaHome), launcher, extraJars(scalaHome): _*)
|
apply(libraryJar(scalaHome), compilerJar(scalaHome), launcher, extraJars(scalaHome): _*)
|
||||||
|
def apply(scalaHome: File)(classLoader: List[File] => ClassLoader): ScalaInstance =
|
||||||
|
apply(libraryJar(scalaHome), compilerJar(scalaHome), extraJars(scalaHome): _*)(classLoader)
|
||||||
|
|
||||||
def apply(version: String, scalaHome: File, launcher: xsbti.Launcher): ScalaInstance =
|
def apply(version: String, scalaHome: File, launcher: xsbti.Launcher): ScalaInstance =
|
||||||
apply(version, libraryJar(scalaHome), compilerJar(scalaHome), launcher, extraJars(scalaHome) : _*)
|
apply(version, libraryJar(scalaHome), compilerJar(scalaHome), launcher, extraJars(scalaHome) : _*)
|
||||||
def apply(libraryJar: File, compilerJar: File, launcher: xsbti.Launcher, extraJars: File*): ScalaInstance =
|
def apply(libraryJar: File, compilerJar: File, launcher: xsbti.Launcher, extraJars: File*): ScalaInstance =
|
||||||
|
apply(libraryJar, compilerJar, extraJars : _*)( scalaLoader(launcher) )
|
||||||
|
def apply(libraryJar: File, compilerJar: File, extraJars: File*)(classLoader: List[File] => ClassLoader): ScalaInstance =
|
||||||
{
|
{
|
||||||
val loader = scalaLoader(launcher, libraryJar :: compilerJar :: extraJars.toList)
|
val loader = classLoader(libraryJar :: compilerJar :: extraJars.toList)
|
||||||
val version = actualVersion(loader)(" (library jar " + libraryJar.getAbsolutePath + ")")
|
val version = actualVersion(loader)(" (library jar " + libraryJar.getAbsolutePath + ")")
|
||||||
new ScalaInstance(version, loader, libraryJar, compilerJar, extraJars, None)
|
new ScalaInstance(version, loader, libraryJar, compilerJar, extraJars, None)
|
||||||
}
|
}
|
||||||
def apply(version: String, libraryJar: File, compilerJar: File, launcher: xsbti.Launcher, extraJars: File*): ScalaInstance =
|
def apply(version: String, libraryJar: File, compilerJar: File, launcher: xsbti.Launcher, extraJars: File*): ScalaInstance =
|
||||||
apply(version, None, libraryJar, compilerJar, launcher, extraJars : _*)
|
apply(version, None, libraryJar, compilerJar, launcher, extraJars : _*)
|
||||||
|
def apply(version: String, libraryJar: File, compilerJar: File, extraJars: File*)(classLoader: List[File] => ClassLoader): ScalaInstance =
|
||||||
|
apply(version, None, libraryJar, compilerJar, extraJars : _*)(classLoader)
|
||||||
def apply(version: String, explicitActual: Option[String], libraryJar: File, compilerJar: File, launcher: xsbti.Launcher, extraJars: File*): ScalaInstance =
|
def apply(version: String, explicitActual: Option[String], libraryJar: File, compilerJar: File, launcher: xsbti.Launcher, extraJars: File*): ScalaInstance =
|
||||||
new ScalaInstance(version, scalaLoader(launcher, libraryJar :: compilerJar :: extraJars.toList), libraryJar, compilerJar, extraJars, explicitActual)
|
apply(version, explicitActual, libraryJar, compilerJar, extraJars : _*)( scalaLoader(launcher) )
|
||||||
|
def apply(version: String, explicitActual: Option[String], libraryJar: File, compilerJar: File, extraJars: File*)(classLoader: List[File] => ClassLoader): ScalaInstance =
|
||||||
|
new ScalaInstance(version, classLoader(libraryJar :: compilerJar :: extraJars.toList), libraryJar, compilerJar, extraJars, explicitActual)
|
||||||
|
|
||||||
def extraJars(scalaHome: File): Seq[File] =
|
def extraJars(scalaHome: File): Seq[File] =
|
||||||
optScalaJar(scalaHome, "jline.jar") ++
|
optScalaJar(scalaHome, "jline.jar") ++
|
||||||
|
|
@ -94,9 +103,8 @@ object ScalaInstance
|
||||||
}
|
}
|
||||||
finally stream.close()
|
finally stream.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
import java.net.{URL, URLClassLoader}
|
import java.net.{URL, URLClassLoader}
|
||||||
private def scalaLoader(launcher: xsbti.Launcher, jars: Seq[File]): ClassLoader =
|
private def scalaLoader(launcher: xsbti.Launcher): Seq[File] => ClassLoader = jars =>
|
||||||
new URLClassLoader(jars.map(_.toURI.toURL).toArray[URL], launcher.topLoader)
|
new URLClassLoader(jars.map(_.toURI.toURL).toArray[URL], launcher.topLoader)
|
||||||
}
|
}
|
||||||
class InvalidScalaInstance(message: String, cause: Throwable) extends RuntimeException(message, cause)
|
class InvalidScalaInstance(message: String, cause: Throwable) extends RuntimeException(message, cause)
|
||||||
Loading…
Reference in New Issue