summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-02-14 08:47:18 +0000
committerPaul Phillips <paulp@improving.org>2010-02-14 08:47:18 +0000
commit1ec5bf5c82ab29a565eeeec2ce8df2bddab7da0b (patch)
tree0b5b3935db11cf7d9bacecbe267e3d29dbf180a8 /src/compiler
parentd7ad3f348753884e154ab40aa848b6f9d85d7b52 (diff)
downloadscala-1ec5bf5c82ab29a565eeeec2ce8df2bddab7da0b.tar.gz
scala-1ec5bf5c82ab29a565eeeec2ce8df2bddab7da0b.tar.bz2
scala-1ec5bf5c82ab29a565eeeec2ce8df2bddab7da0b.zip
More classpath work, and cleanups in the vicini...
More classpath work, and cleanups in the vicinities of everything manipulating classpaths. Review by anyone willing to slog through the approximately dozen different ways the classpath can be influenced.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/CompileClient.scala6
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala18
-rw-r--r--src/compiler/scala/tools/nsc/InterpreterLoop.scala3
-rw-r--r--src/compiler/scala/tools/nsc/MainGenericRunner.scala28
-rw-r--r--src/compiler/scala/tools/nsc/ScriptRunner.scala19
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala43
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Completion.scala9
-rw-r--r--src/compiler/scala/tools/nsc/io/Path.scala9
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala6
-rw-r--r--src/compiler/scala/tools/util/PathResolver.scala142
10 files changed, 147 insertions, 136 deletions
diff --git a/src/compiler/scala/tools/nsc/CompileClient.scala b/src/compiler/scala/tools/nsc/CompileClient.scala
index 00e3d4d37f..b672a616c3 100644
--- a/src/compiler/scala/tools/nsc/CompileClient.scala
+++ b/src/compiler/scala/tools/nsc/CompileClient.scala
@@ -8,6 +8,8 @@ package scala.tools.nsc
import java.io.{ BufferedReader, File, InputStreamReader, PrintWriter }
import Properties.fileEndings
+import scala.tools.util.PathResolver
+import io.Path
import util.ClassPath
/** The client part of the fsc offline compiler. Instead of compiling
@@ -37,7 +39,7 @@ class StandardCompileClient {
while (i < args.length) {
val arg = args(i)
if (fileEndings exists(arg endsWith _)) {
- args(i) = absFileName(arg)
+ args(i) = Path(arg).toAbsolute.path
} else if (arg startsWith "-J") {
//see http://java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/javac.html#J
vmArgs append " "+arg.substring(2)
@@ -54,7 +56,7 @@ class StandardCompileClient {
if (i < args.length) {
arg match {
case "-classpath" | "-sourcepath" | "-bootclasspath" | "-extdirs" | "-d" =>
- args(i) = absFileNames(args(i))
+ args(i) = PathResolver.makeAbsolute(args(i))
i += 1
case "-server" =>
serverAdr = args(i)
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala
index dc2f9082d4..d467fc397b 100644
--- a/src/compiler/scala/tools/nsc/Interpreter.scala
+++ b/src/compiler/scala/tools/nsc/Interpreter.scala
@@ -7,12 +7,14 @@
package scala.tools.nsc
import java.io.{ File, PrintWriter, StringWriter, Writer }
+import File.pathSeparator
import java.lang.{ Class, ClassLoader }
import java.net.{ MalformedURLException, URL }
import java.lang.reflect
import reflect.InvocationTargetException
import scala.PartialFunction.{ cond, condOpt }
+import scala.tools.util.PathResolver
import scala.reflect.Manifest
import scala.collection.mutable
import scala.collection.mutable.{ ListBuffer, HashSet, HashMap, ArrayBuffer }
@@ -164,17 +166,9 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
}
/** the compiler's classpath, as URL's */
- lazy val compilerClasspath: List[URL] = {
- def parseURL(s: String): Option[URL] =
- catching(classOf[MalformedURLException]) opt new URL(s)
-
- val classpathPart =
- ClassPath.expandPath(settings.classpath.value) map (s => new File(s).toURI.toURL)
- val codebasePart =
- (settings.Ycodebase.value split " ").toList flatMap parseURL
-
- classpathPart ::: codebasePart
- }
+ /** XXX ignoring codebase for now, but it used to be appended here. */
+ /** (And one would think it ought to be prepended. */
+ lazy val compilerClasspath: List[URL] = new PathResolver(settings) minimalPathAsURLs
/* A single class loader is used for all commands interpreted by this Interpreter.
It would also be possible to create a new class loader for each command
@@ -1227,7 +1221,7 @@ object Interpreter {
val intLoop = new InterpreterLoop
intLoop.settings = new Settings(Console.println)
// XXX come back to the dot handling
- intLoop.settings appendToClasspath "."
+ intLoop.settings.classpath.value = "."
intLoop.createInterpreter
intLoop.in = InteractiveReader.createDefault(intLoop.interpreter)
diff --git a/src/compiler/scala/tools/nsc/InterpreterLoop.scala b/src/compiler/scala/tools/nsc/InterpreterLoop.scala
index be6881613a..b2fc7772c6 100644
--- a/src/compiler/scala/tools/nsc/InterpreterLoop.scala
+++ b/src/compiler/scala/tools/nsc/InterpreterLoop.scala
@@ -88,6 +88,7 @@ class InterpreterLoop(in0: Option[BufferedReader], out: PrintWriter) {
var interpreter: Interpreter = _ // set by createInterpreter()
// XXX
+ // classpath entries added via :jar
var addedClasspath: List[String] = Nil
/** A reverse list of commands to replay if the user requests a :replay */
@@ -311,7 +312,7 @@ class InterpreterLoop(in0: Option[BufferedReader], out: PrintWriter) {
def addJar(arg: String): Unit = {
val f = File(arg).normalize
if (f.exists) {
- addedClasspath :::= List(f.path)
+ addedClasspath :+= f.path
println("Added " + f.path + " to your classpath.")
replay()
}
diff --git a/src/compiler/scala/tools/nsc/MainGenericRunner.scala b/src/compiler/scala/tools/nsc/MainGenericRunner.scala
index f2871b1646..719425c40c 100644
--- a/src/compiler/scala/tools/nsc/MainGenericRunner.scala
+++ b/src/compiler/scala/tools/nsc/MainGenericRunner.scala
@@ -35,34 +35,16 @@ object MainGenericRunner {
import command.settings
def sampleCompiler = new Global(settings) // def so its not created unless needed
- def processSettings() {
- // append the jars in ${scala.home}/lib to the classpath, as well as "." if none was given.
- val needDot = settings.classpath.value == ""
- settings appendToClasspath PathResolver.genericRunnerClassPath
- if (needDot)
- settings appendToClasspath "."
-
- // XXX is this accomplishing anything?
- settings.defines.applyToCurrentJVM
- }
-
- if (!command.ok)
- return errorFn("%s\n%s".format(command.usageMsg, sampleCompiler.pluginOptionsHelp))
-
- processSettings()
-
- if (settings.version.value)
- return errorFn("Scala code runner %s -- %s".format(versionString, copyrightString))
-
- if (command.shouldStopWithInfo)
- return errorFn(command getInfoMessage sampleCompiler)
-
- val classpath: List[URL] = PathResolver urlsFromSettings settings distinct
+ if (!command.ok) return errorFn("%s\n%s".format(command.usageMsg, sampleCompiler.pluginOptionsHelp))
+ else if (settings.version.value) return errorFn("Scala code runner %s -- %s".format(versionString, copyrightString))
+ else if (command.shouldStopWithInfo) return errorFn(command getInfoMessage sampleCompiler)
def dashe = settings.execute.value
def dashi = settings.loadfiles.value
def slurp = dashi map (file => File(file).slurp()) mkString "\n"
+ val classpath: List[URL] = PathResolver urlsFromSettings settings
+
/** Was code given in a -e argument? */
if (!settings.execute.isDefault) {
/** If a -i argument was also given, we want to execute the code after the
diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala
index 72533f76b5..5d5e4c8c43 100644
--- a/src/compiler/scala/tools/nsc/ScriptRunner.scala
+++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala
@@ -19,6 +19,7 @@ import java.net.URL
import java.util.jar.{ JarEntry, JarOutputStream }
import java.util.regex.Pattern
+import scala.tools.util.PathResolver
import scala.tools.nsc.reporters.{Reporter,ConsoleReporter}
import scala.tools.nsc.util.{ClassPath, CompoundSourceFile, BatchSourceFile, SourceFile, SourceFileFragment}
@@ -194,13 +195,13 @@ object ScriptRunner
settings: GenericRunnerSettings,
scriptFileIn: String): Boolean =
{
- val scriptFile = CompileClient absFileName scriptFileIn
+ val scriptFile = Path(scriptFileIn).toAbsolute.path
{
import settings._
for (setting <- List(classpath, sourcepath, bootclasspath, extdirs, outdir)) {
// DBG("%s = %s".format(setting.name, setting.value))
- setting.value = CompileClient absFileName setting.value
+ setting.value = PathResolver.makeAbsolute(setting.value)
}
}
@@ -299,20 +300,8 @@ object ScriptRunner
compiledLocation: String,
scriptArgs: List[String]): Boolean =
{
- def fileToURL(f: JFile): Option[URL] =
- try Some(f.toURI.toURL) catch { case _: Exception => None }
-
- def paths(str: String, expandStar: Boolean): List[URL] =
- for {
- file <- ClassPath.expandPath(str, expandStar) map (new JFile(_))
- if file.exists
- url <- fileToURL(file)
- } yield url
-
val classpath =
- (paths(settings.bootclasspath.value, true) :::
- paths(compiledLocation, false) :::
- paths(settings.classpath.value, true))
+ (PathResolver urlsFromSettings settings) ::: (PathResolver fromPathString compiledLocation asURLs)
try {
ObjectRunner.run(
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala
index b773da38b3..48292953c7 100644
--- a/src/compiler/scala/tools/nsc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/Settings.scala
@@ -9,7 +9,7 @@ package scala.tools.nsc
import java.io.File
import File.pathSeparator
import io.AbstractFile
-import util.SourceFile
+import util.{ ClassPath, SourceFile }
import Settings._
import annotation.elidable
import scala.tools.util.PathResolver
@@ -19,6 +19,13 @@ import scala.collection.immutable.TreeSet
class Settings(errorFn: String => Unit) extends ScalacSettings {
def this() = this(Console.println)
+ /** It's a hacky situation but there's not much to be done in the
+ * face of settings which mutate and semantic significance to the
+ * originally given classpath.
+ */
+ private var _userSuppliedClassPath: String = null
+ def userSuppliedClassPath = if (_userSuppliedClassPath == null) "" else _userSuppliedClassPath
+
/** Iterates over the arguments applying them to settings where applicable.
* Then verifies setting dependencies are met.
*
@@ -40,13 +47,23 @@ class Settings(errorFn: String => Unit) extends ScalacSettings {
var args = arguments
val residualArgs = new ListBuffer[String]
+ /** First time through here we take note of the classpath, if any.
+ */
+ def finish[T](x: T): T = {
+ /** "lazy var" */
+ if (_userSuppliedClassPath == null)
+ _userSuppliedClassPath = if (classpath.isDefault) "" else classpath.value
+
+ x
+ }
+
while (args.nonEmpty) {
if (args.head startsWith "-") {
val args0 = args
args = this parseParams args
if (args eq args0) {
errorFn("bad option: '" + args.head + "'")
- return (false, args)
+ return finish((false, args))
}
}
else if (args.head == "") { // discard empties, sometimes they appear because of ant or etc.
@@ -54,14 +71,14 @@ class Settings(errorFn: String => Unit) extends ScalacSettings {
}
else {
if (!processAll)
- return (checkDependencies, args)
+ return finish((checkDependencies, args))
residualArgs += args.head
args = args.tail
}
}
- (checkDependencies, residualArgs.toList)
+ finish((checkDependencies, residualArgs.toList))
}
def processArgumentString(params: String) = processArguments(splitParams(params), true)
@@ -736,18 +753,20 @@ object Settings {
case Some((a, b)) => value ++= List((a, b)) ; Some(args.tail)
}
- /** Apply the specified properties to the current JVM */
- def applyToCurrentJVM =
- value foreach { case (k, v) => System.getProperties.setProperty(k, v) }
-
def unparse: List[String] =
value map { case (k,v) => "-D" + k + (if (v == "") "" else "=" + v) }
+
override def equals(that: Any) = that match {
case x: DefinesSetting => this isEq x
case _ => false
}
- }
+ /** Apply the specified properties to the current JVM and returns them. */
+ def applyToJVM() = {
+ value foreach { case (k, v) => System.getProperties.setProperty(k, v) }
+ value
+ }
+ }
}
trait ScalacSettings {
@@ -768,9 +787,7 @@ trait ScalacSettings {
val suppressVTWarn = BooleanSetting ("-Ysuppress-vt-typer-warnings", "Suppress warnings from the typer when testing the virtual class encoding, NOT FOR FINAL!")
def appendToClasspath(entry: String) = {
val oldClasspath = classpath.value
- classpath.value =
- if (classpath.value == "") entry
- else classpath.value + pathSeparator + entry
+ classpath.value = ClassPath.join(Seq(classpath.value, entry))
if (Ylogcp.value)
Console.println("Updated classpath from '%s' to '%s'".format(oldClasspath, classpath.value))
@@ -815,8 +832,6 @@ trait ScalacSettings {
val verbose = BooleanSetting ("-verbose", "Output messages about what the compiler is doing")
val version = BooleanSetting ("-version", "Print product version and exit")
- /** New to classpaths */
-
/**
* -X "Advanced" settings
*/
diff --git a/src/compiler/scala/tools/nsc/interpreter/Completion.scala b/src/compiler/scala/tools/nsc/interpreter/Completion.scala
index cb2061ace5..06f00c3d9d 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Completion.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Completion.scala
@@ -22,6 +22,7 @@ import jline._
import java.net.URL
import java.util.{ List => JList }
import java.lang.reflect
+import scala.tools.util.PathResolver
import io.{ Path, Directory }
object Completion {
@@ -46,13 +47,7 @@ import Completion._
class Completion(repl: Interpreter) {
self =>
- private def asURLs(xs: List[String]) = xs map (x => io.File(x).toURL)
- private def classPath = (
- // compiler jars, scala-library.jar etc.
- (repl.compilerClasspath) :::
- // boot classpath, java.lang.* etc.
- (asURLs(repl.settings.bootclasspath.value split ':' toList))
- )
+ private lazy val classPath = PathResolver.fromSettings(repl.settings).asURLs
// the unqualified vals/defs/etc visible in the repl
val ids = new IdentCompletion(repl)
diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala
index b43697d4ce..36784b6bc3 100644
--- a/src/compiler/scala/tools/nsc/io/Path.scala
+++ b/src/compiler/scala/tools/nsc/io/Path.scala
@@ -7,7 +7,7 @@ package io
import java.io.{
FileInputStream, FileOutputStream, BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter,
- BufferedInputStream, BufferedOutputStream, File => JFile }
+ BufferedInputStream, BufferedOutputStream, RandomAccessFile, File => JFile }
import java.net.{ URI, URL }
import collection.{ Seq, Traversable }
import PartialFunction._
@@ -202,6 +202,13 @@ class Path private[io] (val jfile: JFile)
// deletions
def delete() = jfile.delete()
def deleteIfExists() = if (jfile.exists()) delete() else false
+ def truncate() =
+ isFile && {
+ val raf = new RandomAccessFile(jfile, "rw")
+ raf setLength 0
+ raf.close()
+ length == 0
+ }
// todo
// def copyTo(target: Path, options ...): Boolean
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index 25b5b83a23..013cd89a44 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -15,6 +15,7 @@ import scala.collection.mutable.{ListBuffer, ArrayBuffer, HashSet => MutHashSet}
import io.{ File, Directory, Path, AbstractFile }
import scala.tools.util.StringOps.splitWhere
import Path.isJarOrZip
+import scala.tools.util.PathResolver
import File.pathSeparator
/** <p>
@@ -47,7 +48,7 @@ object ClassPath {
}
/** Split classpath using platform-dependent path separator */
- def split(path: String): List[String] = path split pathSeparator filterNot (_ == "") toList
+ def split(path: String): List[String] = (path split pathSeparator).toList filterNot (_ == "") distinct
/** Join classpath using platform-dependent path separator */
def join(path: Seq[String]): String = path filterNot (_ == "") mkString pathSeparator
@@ -55,6 +56,9 @@ object ClassPath {
/** Split the classpath, apply a transformation function, and reassemble it. */
def map(cp: String, f: String => String): String = join(split(cp) map f)
+ /** Split the classpath and map them into urls */
+ def toURLs(cp: String): List[URL] = split(cp) map (x => Path(x).toAbsolute.toURL)
+
/** Expand path and possibly expanding stars */
def expandPath(path: String, expandStar: Boolean = true): List[String] =
if (expandStar) split(path) flatMap expandS
diff --git a/src/compiler/scala/tools/util/PathResolver.scala b/src/compiler/scala/tools/util/PathResolver.scala
index 658ca48d0e..e3195eb767 100644
--- a/src/compiler/scala/tools/util/PathResolver.scala
+++ b/src/compiler/scala/tools/util/PathResolver.scala
@@ -7,7 +7,7 @@ package scala.tools
package util
import java.net.{ URL, MalformedURLException }
-import nsc.{ Settings }
+import nsc.{ Settings, GenericRunnerSettings }
import nsc.util.{ ClassPath, JavaClassPath, ScalaClassLoader }
import nsc.io.{ File, Directory, Path }
import ClassPath.{ JavaContext, DefaultJavaContext, join, split }
@@ -18,14 +18,34 @@ import PartialFunction.condOpt
//
object PathResolver {
+ // val debugLogger = {
+ // val f = File("/tmp/path-resolve-log.txt")
+ // if (f.exists) f.truncate()
+ // else f.createFile()
+ //
+ // val res = f.bufferedWriter()
+ // res write ("Started debug log: %s\n".format(new java.util.Date))
+ // res
+ // }
+ // def log(msg: Any) = {
+ // Console println msg
+ // debugLogger.write(msg.toString + "\n")
+ // debugLogger flush
+ // }
+
private def propOrElse(name: String, alt: String) = System.getProperty(name, alt)
private def envOrElse(name: String, alt: String) = Option(System getenv name) getOrElse alt
+ private def firstNonEmpty(xs: String*) = xs find (_ != "") getOrElse ""
private def fileOpt(f: Path): Option[String] = f ifFile (_.path)
private def dirOpt(d: Path): Option[String] = d ifDirectory (_.path)
private def expandToPath(p: Path) = join(ClassPath.expandPath(p.path, true))
private def expandToContents(p: Path) = join(ClassPath.expandDir(p.path))
+ /** Map all classpath elements to absolute paths and reconstruct the classpath.
+ */
+ def makeAbsolute(cp: String) = ClassPath.map(cp, x => Path(x).toAbsolute.path)
+
/** pretty print class path */
def ppcp(s: String) = split(s) match {
case Nil => ""
@@ -42,30 +62,25 @@ object PathResolver {
}
def classPathEnv = envOrElse("CLASSPATH", "")
- def toolPathEnv = envOrElse("TOOL_CLASSPATH", "") // XXX this should go
- def classPathProp = propOrElse("java.class.path", "")
+ def sourcePathEnv = envOrElse("SOURCEPATH", "") // not used
def javaBootClassPath = propOrElse("sun.boot.class.path", searchForBootClasspath)
+ def javaUserClassPath = propOrElse("java.class.path", "")
def javaExtDirs = propOrElse("java.ext.dirs", "")
def userHome = propOrElse("user.home", "")
def scalaHome = propOrElse("scala.home", "")
- def scalaExtDirs = propOrElse("scala.ext.dirs", "") // XXX not in spec
-
- // XXX note "." not used yet
- def classPath = if (classPathProp != "") classPathProp else classPathEnv
+ def scalaExtDirs = propOrElse("scala.ext.dirs", "")
override def toString = """
|object Environment {
- | classPathEnv = %s
- | toolPathEnv = %s
- | classPathProp = %s
| javaBootClassPath = %s
+ | javaUserClassPath = %s
| javaExtDirs = %s
| userHome = %s
| scalaHome = %s
| scalaExtDirs = %s
|}""".trim.stripMargin.format(
- ppcp(classPathEnv), ppcp(toolPathEnv), ppcp(classPathProp), ppcp(javaBootClassPath),
- ppcp(javaExtDirs), userHome, scalaHome, ppcp(scalaExtDirs)
+ ppcp(javaBootClassPath), ppcp(javaUserClassPath), ppcp(javaExtDirs),
+ userHome, scalaHome, ppcp(scalaExtDirs)
)
}
@@ -78,28 +93,34 @@ object PathResolver {
File(url.getFile).parent.path
} getOrElse ""
- private def translateScalaHome(s: String) = s.replaceAll("""${SCALA_HOME}""", scalaHome)
+ // XXX review these semantics
+ def javaBootClassPath = join(Seq(Environment.javaBootClassPath, Environment.javaUserClassPath)) // ... ignoring Environment.classPathEnv
+ def javaExtDirs = Environment.javaExtDirs
- def scalaHome = Environment.scalaHome match { case "" => guessedScalaHome ; case x => x }
+ def scalaHome = firstNonEmpty(Environment.scalaHome, guessedScalaHome)
def scalaHomeDir = Directory(scalaHome)
def scalaLibDir = Directory(scalaHomeDir / "lib")
def scalaClassesDir = Directory(scalaHomeDir / "classes")
- def scalaLibJar = File(scalaLibDir / "scala-library.jar")
- def scalaLibClassDir = Directory(scalaClassesDir / "library")
- def scalaLibFound: Option[Directory] =
- if (scalaLibJar.isFile) Some(scalaLibDir)
- else if (scalaLibClassDir.isDirectory) Some(scalaClassesDir)
+ def scalaLibAsJar = File(scalaLibDir / "scala-library.jar")
+ def scalaLibAsDir = Directory(scalaClassesDir / "library")
+
+ def scalaLibDirFound: Option[Directory] =
+ if (scalaLibAsJar.isFile) Some(scalaLibDir)
+ else if (scalaLibAsDir.isDirectory) Some(scalaClassesDir)
else None
- def scalaBootClassPath = scalaLibFound map expandToContents getOrElse ""
- def scalaExtDirs = Environment.scalaExtDirs
- def scalaToolPath = Environment.toolPathEnv match {
- case "" => scalaBootClassPath
- // XXX doubtful this is accomplishing anything
- case x => expandToPath(x.replaceAll("""\$\{SCALA_HOME\}""", scalaHome))
+ def scalaLibFound =
+ if (scalaLibAsJar.isFile) scalaLibAsJar.path
+ else if (scalaLibAsDir.isDirectory) scalaLibAsDir.path
+ else ""
+
+ def scalaBootClassPath = scalaLibDirFound match {
+ case Some(dir) => join(ClassPath expandDir dir.path)
+ case _ => ""
}
+ def scalaExtDirs = Environment.scalaExtDirs
def scalaPluginDirs = List("misc", "scala-devel", "plugins")
def scalaPluginPath = join(scalaPluginDirs map (scalaHomeDir / _ path))
@@ -108,55 +129,44 @@ object PathResolver {
// If a class is available in multiple locations, it must be loaded from that with the lowest number.
def executionPath = List(
// 1. The Java bootstrap class path.
- Environment.javaBootClassPath,
+ javaBootClassPath,
// 2. The Java extension class path.
- Environment.javaExtDirs,
- // 3. The first available path below.
- // * The fixed class path (TOOL_CLASSPATH) set in the runner script when it was generated
- // (which can be set as the "classpath" attribute when using the scalatool Ant task).
- // This path may contain absolute locations, or locations relative to Scala's home by using
- // the shell variable ${SCALA_HOME} in the path.
- // * The class path formed by all JAR and ZIP files and all folders in Scala's home lib folder.
- scalaToolPath
+ javaExtDirs,
+ // 3. The class path formed by all JAR and ZIP files and all folders in Scala's home lib folder.
+ scalaBootClassPath
)
override def toString = """
|object Defaults {
+ | javaBootClassPath = %s
| scalaHome = %s
+ | scalaLibDirFound = %s
| scalaLibFound = %s
| scalaBootClassPath = %s
| scalaPluginPath = %s
|}""".trim.stripMargin.format(
- scalaHome, scalaLibFound, ppcp(scalaBootClassPath), ppcp(scalaPluginPath)
+ ppcp(javaBootClassPath),
+ scalaHome, scalaLibDirFound, scalaLibFound,
+ ppcp(scalaBootClassPath), ppcp(scalaPluginPath)
)
}
def executionPath = join(Defaults.executionPath)
+ def executionPathURLs = fromPathString(executionPath).asURLs
- /** The original logic of MainGenericRunner.
- */
- def genericRunnerClassPath: String = {
- // this is to make the interpreter work when running without the scala script
- // (e.g. from eclipse). Before, "java.class.path" was added to the user classpath
- // in Settings; this was changed to match the behavior of Sun's javac. So the
- // classpath generated here consist of only the scala lib/* jars if scalaHome
- // can be found, and the whole user classpath otherwise.
- if (Environment.scalaHome == "") Environment.classPath
- else Defaults.scalaBootClassPath
- }
private def classPathContainersFromSettings(settings: Settings, context: JavaContext) = {
val pr = new PathResolver(settings)
import context._
import pr.Calculated._
- // XXX how do the contents of lib/* break down between bootclasspath and extdirs?
- // XXX and what exactly is codebase for?
+ // XXX how should the contents of lib/* break down between bootclasspath and extdirs?
+ // XXX what exactly is codebase for?
val sources = List(
classesInPath(javaBootClassPath), // -javabootclasspath multiple entries, no expansion
contentsOfDirsInPath(scalaBootClassPath), // -bootclasspath ???
contentsOfDirsInPath(javaExtDirs), // -javaextdirs multiple dirs, each expands to contents
contentsOfDirsInPath(scalaExtDirs), // -extdirs ???
- classesInExpandedPath(classPath), // -classpath multiple entries, first expanding *s
+ classesInExpandedPath(userClassPath), // -classpath multiple entries, first expanding *s
classesAtAllURLS(codeBase), // -Ycodebase ??? multiple URLs
sourcesInPath(sourcePath) // -sourcepath multiple source entries, no expansion
)
@@ -168,7 +178,7 @@ object PathResolver {
}
def urlsFromSettings(settings: Settings): List[URL] = urlsFromSettings(settings, DefaultJavaContext)
def urlsFromSettings(settings: Settings, context: JavaContext): List[URL] =
- classPathContainersFromSettings(settings, context) flatMap (_.asURLs)
+ classPathContainersFromSettings(settings, context) flatMap (_.asURLs) distinct
private def contextFromSettings(s: Settings) =
if (s.inline.value) new JavaContext else DefaultJavaContext
@@ -191,8 +201,11 @@ object PathResolver {
}
def fromPathString(path: String): JavaClassPath = fromPathString(path, DefaultJavaContext)
- def fromPathString(path: String, context: JavaContext): JavaClassPath =
- new JavaClassPath(context.classesInExpandedPath(path), context)
+ def fromPathString(path: String, context: JavaContext): JavaClassPath = {
+ val s = new Settings()
+ s.classpath.value = path
+ fromSettings(s, context)
+ }
/** With no arguments, show the interesting values in Environment and Defaults.
* If there are arguments, show those in Calculated as if those options had been
@@ -276,7 +289,7 @@ object PathResolver {
} else Nil
}
}
-import PathResolver.{ Defaults, Environment, ppcp }
+import PathResolver.{ Defaults, Environment, firstNonEmpty, ppcp }
class PathResolver(settings: Settings) {
private def cmdLineOrElse(name: String, alt: String) = {
@@ -300,13 +313,15 @@ class PathResolver(settings: Settings) {
* those in Defaults.
*/
object Calculated {
- def javaBootClassPath = cmdLineOrElse("javabootclasspath", Environment.javaBootClassPath)
+ def scalaHome = Defaults.scalaHome
+ def javaBootClassPath = cmdLineOrElse("javabootclasspath", Defaults.javaBootClassPath)
def scalaBootClassPath = cmdLineOrElse("bootclasspath", Defaults.scalaBootClassPath)
- def javaExtDirs = cmdLineOrElse("javaextdirs", Environment.javaExtDirs)
+ def javaExtDirs = cmdLineOrElse("javaextdirs", Defaults.javaExtDirs)
def scalaExtDirs = cmdLineOrElse("extdirs", Defaults.scalaExtDirs)
- def classPath = cmdLineOrElse("classpath", Environment.classPath)
+ def userClassPath = cmdLineOrElse("classpath", "")
def sourcePath = cmdLineOrElse("sourcepath", "")
def codeBase = cmdLineOrElse("Ycodebase", "")
+ def dotPath = if (settings.userSuppliedClassPath == "") "." else ""
def referencePath = List(
// 1. The value of -javabootclasspath if it is set, or the Java bootstrap class path.
@@ -325,24 +340,31 @@ class PathResolver(settings: Settings) {
// * ---> XXX what about java.class.path?
// * The value of the CLASSPATH environment variable.
// * The current directory (that is the location of ".").
- if (classPath == "") "." else classPath
+ userClassPath,
+ dotPath
)
override def toString = """
|object Calculated {
+ | scalaHome = %s
| javaBootClassPath = %s
| scalaBootClassPath = %s
| javaExtDirs = %s
| scalaExtDirs = %s
- | classPath = %s
+ | userClassPath = %s
| sourcePath = %s
- | codeBase = %s
+ | referencePath = %s
|}""".trim.stripMargin.format(
+ scalaHome,
ppcp(javaBootClassPath), ppcp(scalaBootClassPath),
ppcp(javaExtDirs), ppcp(scalaExtDirs),
- ppcp(classPath), ppcp(sourcePath), codeBase
+ ppcp(userClassPath), ppcp(sourcePath),
+ ppcp(PathResolver.this.referencePath)
)
}
def referencePath = join(Calculated.referencePath)
+ def referencePathAsURLs = ClassPath toURLs referencePath
+ def minimalPath = join(Seq(Calculated.scalaBootClassPath, Calculated.userClassPath))
+ def minimalPathAsURLs = ClassPath toURLs minimalPath
}