diff options
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")) + } +} |