diff options
author | Paul Phillips <paulp@improving.org> | 2010-02-14 08:47:18 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-02-14 08:47:18 +0000 |
commit | 1ec5bf5c82ab29a565eeeec2ce8df2bddab7da0b (patch) | |
tree | 0b5b3935db11cf7d9bacecbe267e3d29dbf180a8 /src/compiler | |
parent | d7ad3f348753884e154ab40aa848b6f9d85d7b52 (diff) | |
download | scala-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.scala | 6 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/Interpreter.scala | 18 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/InterpreterLoop.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/MainGenericRunner.scala | 28 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ScriptRunner.scala | 19 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/Settings.scala | 43 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interpreter/Completion.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/io/Path.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/util/ClassPath.scala | 6 | ||||
-rw-r--r-- | src/compiler/scala/tools/util/PathResolver.scala | 142 |
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 } |