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 | |
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.
17 files changed, 282 insertions, 267 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 } diff --git a/src/partest/scala/tools/partest/nest/CompileManager.scala b/src/partest/scala/tools/partest/nest/CompileManager.scala index ecf8b07b8e..9535b35c95 100644 --- a/src/partest/scala/tools/partest/nest/CompileManager.scala +++ b/src/partest/scala/tools/partest/nest/CompileManager.scala @@ -8,18 +8,19 @@ package scala.tools.partest package nest -import scala.tools.nsc.{Global, Settings, CompilerCommand, FatalError} +import scala.tools.nsc.{ Global, Settings, CompilerCommand, FatalError } import scala.tools.nsc.reporters.{Reporter, ConsoleReporter} import scala.tools.nsc.util.ClassPath import scala.tools.util.PathResolver -import java.io.{File, BufferedReader, PrintWriter, FileReader, FileWriter, StringWriter} +import java.io.{ File, BufferedReader, PrintWriter, FileReader, Writer, FileWriter, StringWriter } import File.pathSeparator -class ExtConsoleReporter(override val settings: Settings, reader: BufferedReader, var writer: PrintWriter) extends ConsoleReporter(settings, reader, writer) { - def this(settings: Settings) = { - this(settings, Console.in, new PrintWriter(new FileWriter("/dev/null"))) - } +class ExtConsoleReporter(override val settings: Settings, reader: BufferedReader, var writer: PrintWriter) +extends ConsoleReporter(settings, reader, writer) { + + def this(settings: Settings) = this(settings, Console.in, new PrintWriter(new FileWriter("/dev/null"))) + def hasWarnings: Boolean = WARNING.count != 0 } @@ -27,20 +28,14 @@ abstract class SimpleCompiler { def compile(out: Option[File], files: List[File], kind: String, log: File): Boolean } -class TestSettings(fileMan: FileManager) extends Settings(x => ()) { - javabootclasspath.value = ClassPath.join( - List(PathResolver.Environment.javaBootClassPath, fileMan.LATEST_LIB) - ) -} +class TestSettings(fileMan: FileManager) extends Settings(_ => ()) { } class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler { def newGlobal(settings: Settings, reporter: Reporter): Global = new Global(settings, reporter) def newGlobal(settings: Settings, logWriter: FileWriter): Global = { - val rep = new ExtConsoleReporter(settings, - Console.in, - new PrintWriter(logWriter)) + val rep = newReporter(settings, logWriter) rep.shortname = true newGlobal(settings, rep) } @@ -50,12 +45,15 @@ class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler { settings.deprecation.value = true settings.nowarnings.value = false settings.encoding.value = "iso-8859-1" + // XXX + settings.javabootclasspath.value = + ClassPath.join(Seq(PathResolver.Environment.javaBootClassPath, fileManager.LATEST_LIB)) + settings } - def newReporter(sett: Settings) = new ExtConsoleReporter(sett, - Console.in, - new PrintWriter(new StringWriter)) + def newReporter(sett: Settings, writer: Writer = new StringWriter) = + new ExtConsoleReporter(sett, Console.in, new PrintWriter(writer)) private def updatePluginPath(options: String): String = { val (opt1, opt2) = @@ -95,49 +93,50 @@ class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler { } else "" val allOpts = fileManager.SCALAC_OPTS+" "+argString NestUI.verbose("scalac options: "+allOpts) + val args = (allOpts split "\\s").toList - val command = new CompilerCommand(args, testSettings, x => {}, false) + val command = new CompilerCommand(args, testSettings, _ => (), false) val global = newGlobal(command.settings, logWriter) val testRep: ExtConsoleReporter = global.reporter.asInstanceOf[ExtConsoleReporter] - val test: TestFile = kind match { - case "pos" => PosTestFile(files(0), fileManager, out.isEmpty) - case "neg" => NegTestFile(files(0), fileManager, out.isEmpty) - case "run" => RunTestFile(files(0), fileManager, out.isEmpty) - case "jvm" => JvmTestFile(files(0), fileManager, out.isEmpty) - case "shootout" => ShootoutTestFile(files(0), fileManager, out.isEmpty) - case "scalap" => ScalapTestFile(files(0), fileManager, out.isEmpty) - case "scalacheck" => - ScalaCheckTestFile(files(0), fileManager, out.isEmpty) + val testFileFn: (File, FileManager, Boolean) => TestFile = kind match { + case "pos" => PosTestFile.apply + case "neg" => NegTestFile.apply + case "run" => RunTestFile.apply + case "jvm" => JvmTestFile.apply + case "shootout" => ShootoutTestFile.apply + case "scalap" => ScalapTestFile.apply + case "scalacheck" => ScalaCheckTestFile.apply } - test.defineSettings(command.settings) - out match { - case Some(outDir) => - command.settings.outdir.value = outDir.getAbsolutePath - command.settings appendToClasspath outDir.getAbsolutePath - case None => - // do nothing + val test: TestFile = testFileFn(files.head, fileManager, out.isEmpty) + test defineSettings command.settings + + out map { outDir => + command.settings.outdir.value = outDir.getAbsolutePath + command.settings appendToClasspath outDir.getAbsolutePath } - val toCompile = files.map(_.getPath) + val toCompile = files map (_.getPath) + try { NestUI.verbose("compiling "+toCompile) - try { - (new global.Run) compile toCompile - } catch { + try new global.Run compile toCompile + catch { case FatalError(msg) => testRep.error(null, "fatal error: " + msg) } + testRep.printSummary testRep.writer.flush testRep.writer.close - } catch { + } + catch { case e => e.printStackTrace() return false - } finally { - logWriter.close() } + finally logWriter.close() + !testRep.hasErrors } } diff --git a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala index 27cd36e3e7..c8ec9a9f6f 100644 --- a/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala +++ b/src/partest/scala/tools/partest/nest/ConsoleFileManager.scala @@ -10,6 +10,7 @@ package nest import java.io.{File, FilenameFilter, IOException, StringWriter} import java.net.URI +import scala.tools.util.PathResolver class ConsoleFileManager extends FileManager { @@ -40,7 +41,8 @@ class ConsoleFileManager extends FileManager { SCALAC_OPTS = SCALAC_OPTS+" "+moreOpts } - var CLASSPATH = System.getProperty("java.class.path", ".") + var CLASSPATH = PathResolver.Environment.javaUserClassPath match { case "" => "." ; case x => x } + NestUI.verbose("CLASSPATH: "+CLASSPATH) var JAVACMD = System.getProperty("scalatest.javacmd", "java") @@ -135,7 +137,6 @@ else NestUI.verbose("Running with classes in "+testClassesFile) latestFile = prefixFileWith(testClassesFile.getParentFile, "bin") latestLibFile = prefixFileWith(testClassesFile, "library") - latestActFile = prefixFileWith(testClassesFile, "library") latestCompFile = prefixFileWith(testClassesFile, "compiler") latestPartestFile = prefixFileWith(testClassesFile, "partest") latestFjbgFile = prefixFile("lib/fjbg.jar") @@ -145,15 +146,14 @@ else NestUI.verbose("Running on "+testBuild) latestFile = prefixFile(testBuild+"/bin") latestLibFile = prefixFile(testBuild+"/lib/scala-library.jar") - latestActFile = prefixFile(testBuild+"/lib/scala-library.jar") latestCompFile = prefixFile(testBuild+"/lib/scala-compiler.jar") latestPartestFile = prefixFile(testBuild+"/lib/scala-partest.jar") - } else { + } + else { def setupQuick() { NestUI.verbose("Running build/quick") latestFile = prefixFile("build/quick/bin") latestLibFile = prefixFile("build/quick/classes/library") - latestActFile = prefixFile("build/quick/classes/library") latestCompFile = prefixFile("build/quick/classes/compiler") latestPartestFile = prefixFile("build/quick/classes/partest") } @@ -163,7 +163,6 @@ else val p = testParent.getParentFile latestFile = prefixFileWith(p, "bin") latestLibFile = prefixFileWith(p, "lib/scala-library.jar") - latestActFile = prefixFileWith(p, "lib/scala-library.jar") latestCompFile = prefixFileWith(p, "lib/scala-compiler.jar") latestPartestFile = prefixFileWith(p, "lib/scala-partest.jar") } @@ -172,7 +171,6 @@ else NestUI.verbose("Running dists/latest") latestFile = prefixFile("dists/latest/bin") latestLibFile = prefixFile("dists/latest/lib/scala-library.jar") - latestActFile = prefixFile("dists/latest/lib/scala-library.jar") latestCompFile = prefixFile("dists/latest/lib/scala-compiler.jar") latestPartestFile = prefixFile("dists/latest/lib/scala-partest.jar") } @@ -181,59 +179,34 @@ else NestUI.verbose("Running build/pack") latestFile = prefixFile("build/pack/bin") latestLibFile = prefixFile("build/pack/lib/scala-library.jar") - latestActFile = prefixFile("build/pack/lib/scala-library.jar") latestCompFile = prefixFile("build/pack/lib/scala-compiler.jar") latestPartestFile = prefixFile("build/pack/lib/scala-partest.jar") } - def max(a: Long, b: Long) = if (a > b) a else b - val dists = new File(testParent, "dists") val build = new File(testParent, "build") // in case of an installed dist, testRootFile is one level deeper val bin = new File(testParent.getParentFile, "bin") + def mostRecentOf(base: String, names: String*) = + names map (x => prefixFile(base + "/" + x).lastModified) reduceLeft (_ max _) + // detect most recent build - val quickTime = - max(prefixFile("build/quick/classes/compiler/compiler.properties").lastModified, - prefixFile("build/quick/classes/library/library.properties").lastModified) - val packTime = - max(prefixFile("build/pack/lib/scala-compiler.jar").lastModified, - prefixFile("build/pack/lib/scala-library.jar").lastModified) - val distTime = - max(prefixFile("dists/latest/lib/scala-compiler.jar").lastModified, - prefixFile("dists/latest/lib/scala-library.jar").lastModified) - val instTime = { - val p = testParent.getParentFile - max(prefixFileWith(p, "lib/scala-compiler.jar").lastModified, - prefixFileWith(p, "lib/scala-library.jar").lastModified) - } + val quickTime = mostRecentOf("build/quick/classes", "compiler/compiler.properties", "library/library.properties") + val packTime = mostRecentOf("build/pack/lib", "scala-compiler.jar", "scala-library.jar") + val distTime = mostRecentOf("dists/latest/lib", "scala-compiler.jar", "scala-library.jar") + val instTime = mostRecentOf("lib", "scala-compiler.jar", "scala-library.jar") + + val pairs = Map( + (quickTime, () => setupQuick()), + (packTime, () => setupPack()), + (distTime, () => setupDist()), + (instTime, () => setupInst()) + ) + + // run setup based on most recent time + pairs(pairs.keysIterator.toList max)() - if (quickTime > packTime) { // pack ruled out - if (quickTime > distTime) { // dist ruled out - if (quickTime > instTime) // inst ruled out - setupQuick() - else - setupInst() - } else { // quick ruled out - if (distTime > instTime) // inst ruled out - setupDist() - else - setupInst() - } - } else { // quick ruled out - if (packTime > distTime) { // dist ruled out - if (packTime > instTime) // inst ruled out - setupPack() - else - setupInst() - } else { // pack ruled out - if (distTime > instTime) // inst ruled out - setupDist() - else - setupInst() - } - } latestFjbgFile = prefixFile("lib/fjbg.jar") } @@ -242,14 +215,10 @@ else LATEST_COMP = latestCompFile.getAbsolutePath LATEST_PARTEST = latestPartestFile.getAbsolutePath - // detect whether we are running on Windows - val osName = System.getProperty("os.name") - NestUI.verbose("OS: "+osName) + import util.Properties.isWin - val scalaCommand = if (osName startsWith "Windows") - "scala.bat" else "scala" - val scalacCommand = if (osName startsWith "Windows") - "scalac.bat" else "scalac" + val scalaCommand = if (isWin) "scala.bat" else "scala" + val scalacCommand = if (isWin) "scalac.bat" else "scalac" SCALA = (new File(latestFile, scalaCommand)).getAbsolutePath SCALAC_CMD = (new File(latestFile, scalacCommand)).getAbsolutePath @@ -264,7 +233,6 @@ else var latestFile: File = _ var latestLibFile: File = _ - var latestActFile: File = _ var latestCompFile: File = _ var latestPartestFile: File = _ var latestFjbgFile: File = _ diff --git a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala index 2ae67db566..af8a368489 100644 --- a/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala +++ b/src/partest/scala/tools/partest/nest/ReflectiveRunner.scala @@ -44,9 +44,9 @@ class ReflectiveRunner extends RunnerUtils { new ConsoleFileManager import fileManager. - { latestCompFile, latestLibFile, latestActFile, latestPartestFile, latestFjbgFile } + { latestCompFile, latestLibFile, latestPartestFile, latestFjbgFile } val files = - Array(latestCompFile, latestLibFile, latestActFile, latestPartestFile, latestFjbgFile) + Array(latestCompFile, latestLibFile, latestPartestFile, latestFjbgFile) val sepUrls = files map { _.toURI.toURL } val sepLoader = new URLClassLoader(sepUrls, null) diff --git a/src/partest/scala/tools/partest/nest/TestFile.scala b/src/partest/scala/tools/partest/nest/TestFile.scala index 3ae46399ec..90d8db936f 100644 --- a/src/partest/scala/tools/partest/nest/TestFile.scala +++ b/src/partest/scala/tools/partest/nest/TestFile.scala @@ -26,8 +26,10 @@ abstract class TestFile(kind: String) { protected def baseSettings(settings: Settings) { settings appendToClasspath dirpath - if (createOutDir) - settings.outdir.value = (Path(dir) / objDir).createDirectory(true).path + if (createOutDir) { + val d = (Path(dirpath) / objDir) createDirectory true + settings.outdir.value = d.toAbsolute.path + } // add additional flags found in 'testname.flags' def flagsPath = Path(dir) / (fileBase + ".flags") diff --git a/src/partest/scala/tools/partest/nest/Worker.scala b/src/partest/scala/tools/partest/nest/Worker.scala index bd742a5b13..19fa35cdeb 100644 --- a/src/partest/scala/tools/partest/nest/Worker.scala +++ b/src/partest/scala/tools/partest/nest/Worker.scala @@ -15,7 +15,9 @@ import java.util.{Timer, TimerTask} import scala.tools.nsc.{ ObjectRunner, Settings, CompilerCommand, Global } import scala.tools.nsc.io.{ AbstractFile, PlainFile, Path, Directory, File => SFile } import scala.tools.nsc.reporters.ConsoleReporter -import scala.tools.nsc.util.FakePos +import scala.tools.nsc.util.{ ClassPath, FakePos } +import scala.tools.util.PathResolver +import ClassPath.{ join, split } import scala.actors.{Actor, Exit, TIMEOUT} import scala.actors.Actor._ @@ -55,7 +57,7 @@ class Worker(val fileManager: FileManager) extends Actor { def act() { react { case RunTests(kind, files) => - NestUI.verbose("received "+files.length+" to test") + // NestUI.verbose("received "+files.length+" to test") val master = sender runTests(kind, files) { results => master ! Results(results, createdLogFiles, createdOutputDirs) @@ -123,9 +125,9 @@ class Worker(val fileManager: FileManager) extends Actor { val consFM = new ConsoleFileManager val classpath: List[URL] = { - import consFM.{ latestCompFile, latestLibFile, latestActFile, latestPartestFile } + import consFM.{ latestCompFile, latestLibFile, latestPartestFile } val units = ( - List(outDir, latestCompFile, latestLibFile, latestActFile, latestPartestFile) ::: + List(outDir, latestCompFile, latestLibFile, latestPartestFile) ::: ((CLASSPATH split File.pathSeparatorChar).toList map (x => new File(x))) ) units map (_.toURI.toURL) @@ -173,7 +175,7 @@ class Worker(val fileManager: FileManager) extends Actor { val cmd = javacCmd+ " -d "+outDir.getAbsolutePath+ - " -classpath "+outDir+File.pathSeparator+CLASSPATH+ + " -classpath "+ join(Seq(outDir.toString, CLASSPATH)) + " "+files.mkString(" ") val (success, msg) = try { @@ -235,9 +237,6 @@ class Worker(val fileManager: FileManager) extends Actor { options } else "" - val cp = System.getProperty("java.class.path", ".") - NestUI.verbose("java.class.path: "+cp) - def quote(path: String) = "\""+path+"\"" // Note! As this currently functions, JAVA_OPTS must precede argString @@ -248,21 +247,23 @@ class Worker(val fileManager: FileManager) extends Actor { // // debug: Found javaopts file 'files/shootout/message.scala-2.javaopts', using options: '-Xss32k' // debug: java -Xss32k -Xss2m -Xms256M -Xmx1024M -classpath [...] - val cmd = - JAVACMD+ - " "+JAVA_OPTS+ - " "+argString+ - " -classpath "+outDir+File.pathSeparator+CLASSPATH+ - " -Djava.library.path="+logFile.getParentFile.getAbsolutePath+ - " -Dscalatest.output="+outDir.getAbsolutePath+ - " -Dscalatest.lib="+LATEST_LIB+ - " -Dscalatest.cwd="+outDir.getParent+ - " -Djavacmd="+JAVACMD+ - " -Duser.language=en -Duser.country=US"+ - " scala.tools.nsc.MainGenericRunner"+ - " Test jvm" - NestUI.verbose(cmd) + val cmd = List( + JAVACMD, + JAVA_OPTS, + argString, + "-classpath " + join(Seq(outDir.toString, CLASSPATH)), + "-Djava.library.path="+logFile.getParentFile.getAbsolutePath, + "-Dscalatest.output="+outDir.getAbsolutePath, + "-Dscalatest.lib="+LATEST_LIB, + "-Dscalatest.cwd="+outDir.getParent, + "-Djavacmd="+JAVACMD, + "-Duser.language=en -Duser.country=US", + "scala.tools.nsc.MainGenericRunner", + "Test", + "jvm" + ) mkString " " + NestUI.verbose(cmd) runCommand(cmd, logFile) if (fileManager.showLog) { @@ -410,7 +411,7 @@ class Worker(val fileManager: FileManager) extends Actor { execTest(outDir, logFile, fileBase) else execTestObjectRunner(file, outDir, logFile) - NestUI.verbose(this+" finished running "+fileBase) + // NestUI.verbose(this+" finished running "+fileBase) diff = compareOutput(dir, fileBase, kind, logFile) if (!diff.equals("")) { @@ -430,8 +431,7 @@ class Worker(val fileManager: FileManager) extends Actor { } if (succeeded) { val consFM = new ConsoleFileManager - import consFM.{latestCompFile, latestLibFile, latestActFile, - latestPartestFile} + import consFM.{ latestCompFile, latestLibFile, latestPartestFile } NestUI.verbose("compilation of "+file+" succeeded\n") @@ -439,8 +439,7 @@ class Worker(val fileManager: FileManager) extends Actor { val scalacheckURL = (new File(libs, "ScalaCheck.jar")).toURI.toURL val outURL = outDir.getCanonicalFile.toURI.toURL val classpath: List[URL] = - List(outURL, scalacheckURL, latestCompFile.toURI.toURL, latestLibFile.toURI.toURL, - latestActFile.toURI.toURL, latestPartestFile.toURI.toURL).distinct + List(outURL, scalacheckURL, latestCompFile.toURI.toURL, latestLibFile.toURI.toURL, latestPartestFile.toURI.toURL).distinct val logWriter = new PrintStream(new FileOutputStream(logFile)) @@ -952,8 +951,8 @@ class Worker(val fileManager: FileManager) extends Actor { } def reportAll(results: ImmMap[String, Int], cont: ImmMap[String, Int] => Unit) { - NestUI.verbose("finished testing "+kind+" with "+errors+" errors") - NestUI.verbose("created "+compileMgr.numSeparateCompilers+" separate compilers") + // NestUI.verbose("finished testing "+kind+" with "+errors+" errors") + // NestUI.verbose("created "+compileMgr.numSeparateCompilers+" separate compilers") timer.cancel() cont(results) } diff --git a/test/files/run/programmatic-main.check b/test/files/run/programmatic-main.check new file mode 100644 index 0000000000..44e77e3311 --- /dev/null +++ b/test/files/run/programmatic-main.check @@ -0,0 +1,24 @@ +parser +namer +packageobjects +typer +superaccessors +pickler +refchecks +liftcode +uncurry +tailcalls +explicitouter +erasure +lazyvals +lambdalift +constructors +flatten +mixin +cleanup +icode +inliner +closelim +dce +jvm +terminal diff --git a/test/files/run/programmatic-main.scala b/test/files/run/programmatic-main.scala new file mode 100644 index 0000000000..b6fbdb9d30 --- /dev/null +++ b/test/files/run/programmatic-main.scala @@ -0,0 +1,12 @@ +import scala.tools.nsc._ +import io.Path + +object Test +{ + val basedir = (Path(System.getProperty("scalatest.cwd")).parent / "lib").path + val baseargs = Array("-bootclasspath", basedir + "scala-library.jar", "-cp", basedir + "scala-compiler.jar") + + def main(args: Array[String]): Unit = { + Main process (baseargs ++ Array("-Xshow-phases")) + } +} |