summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-02-22 00:15:32 +0000
committerPaul Phillips <paulp@improving.org>2010-02-22 00:15:32 +0000
commit91cdb1531656d9240e9ee64509ab528d727d1b51 (patch)
treea33bbdb66b0ee1bb147bb8628902f66bc7f66756 /src/compiler/scala/tools/nsc
parentf07bdbab911a7bcef042373d45fab302753f5a1f (diff)
downloadscala-91cdb1531656d9240e9ee64509ab528d727d1b51.tar.gz
scala-91cdb1531656d9240e9ee64509ab528d727d1b51.tar.bz2
scala-91cdb1531656d9240e9ee64509ab528d727d1b51.zip
More laboring on Settings, ClassPaths, Ant Task...
More laboring on Settings, ClassPaths, Ant Tasks, Partest, and similar epicenters of thrilldom. No review.
Diffstat (limited to 'src/compiler/scala/tools/nsc')
-rw-r--r--src/compiler/scala/tools/nsc/CompilerCommand.scala4
-rw-r--r--src/compiler/scala/tools/nsc/Interpreter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/InterpreterLoop.scala22
-rw-r--r--src/compiler/scala/tools/nsc/ScriptRunner.scala4
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala81
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala12
6 files changed, 79 insertions, 46 deletions
diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala
index 5d0c0a0196..a805da1fcc 100644
--- a/src/compiler/scala/tools/nsc/CompilerCommand.scala
+++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala
@@ -29,7 +29,7 @@ class CompilerCommand(
val cmdName = "scalac"
private val helpSyntaxColumnWidth: Int =
- (settings.settingSet map (_.helpSyntax.length)) max
+ (settings.visibleSettings map (_.helpSyntax.length)) max
private def format(s: String): String =
if (s.length >= helpSyntaxColumnWidth) s
@@ -37,7 +37,7 @@ class CompilerCommand(
/** Creates a help message for a subset of options based on cond */
def createUsageMsg(label: String, cond: (Setting) => Boolean): String =
- settings.settingSet .
+ settings.visibleSettings .
filter(cond) .
map(s => format(s.helpSyntax) + " " + s.helpDescription) .
toList.sorted.mkString("Usage: %s <options> <source files>\n%s options include:\n " .
diff --git a/src/compiler/scala/tools/nsc/Interpreter.scala b/src/compiler/scala/tools/nsc/Interpreter.scala
index 71a210de3f..d8507a4e7c 100644
--- a/src/compiler/scala/tools/nsc/Interpreter.scala
+++ b/src/compiler/scala/tools/nsc/Interpreter.scala
@@ -189,8 +189,6 @@ class Interpreter(val settings: Settings, out: PrintWriter) {
}
/** the compiler's classpath, as URL's */
- /** 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) asURLs
/* A single class loader is used for all commands interpreted by this Interpreter.
diff --git a/src/compiler/scala/tools/nsc/InterpreterLoop.scala b/src/compiler/scala/tools/nsc/InterpreterLoop.scala
index c04feb9efd..b8e25c4bd4 100644
--- a/src/compiler/scala/tools/nsc/InterpreterLoop.scala
+++ b/src/compiler/scala/tools/nsc/InterpreterLoop.scala
@@ -13,6 +13,7 @@ import scala.tools.nsc.{ InterpreterResults => IR }
import scala.annotation.tailrec
import scala.collection.mutable.ListBuffer
import scala.concurrent.ops
+import util.{ ClassPath }
import interpreter._
import io.{ File, Process }
@@ -88,9 +89,8 @@ class InterpreterLoop(in0: Option[BufferedReader], out: PrintWriter) {
var settings: Settings = _ // set by main()
var interpreter: Interpreter = _ // set by createInterpreter()
- // XXX
- // classpath entries added via :jar
- var addedClasspath: List[String] = Nil
+ // classpath entries added via :cp
+ var addedClasspath: String = ""
/** A reverse list of commands to replay if the user requests a :replay */
var replayCommandStack: List[String] = Nil
@@ -112,8 +112,8 @@ class InterpreterLoop(in0: Option[BufferedReader], out: PrintWriter) {
/** Create a new interpreter. */
def createInterpreter() {
- // if (!addedClasspath.isEmpty)
- // addedClasspath foreach (settings appendToClasspath _)
+ if (addedClasspath != "")
+ settings.classpath append addedClasspath
interpreter = new Interpreter(settings, out) {
override protected def parentClassLoader = classOf[InterpreterLoop].getClassLoader
@@ -191,10 +191,10 @@ class InterpreterLoop(in0: Option[BufferedReader], out: PrintWriter) {
val standardCommands: List[Command] = {
import CommandImplicits._
List(
+ OneArg("cp", "add an entry (jar or directory) to the classpath", addClasspath),
NoArgs("help", "print this help message", printHelp),
VarArgs("history", "show the history (optional arg: lines to show)", printHistory),
LineArg("h?", "search the history", searchHistory),
- OneArg("jar", "add a jar to the classpath", addJar),
OneArg("load", "load and interpret a Scala file", load),
NoArgs("power", "enable power user mode", power),
NoArgs("quit", "exit the interpreter", () => Result(false, None)),
@@ -316,15 +316,15 @@ class InterpreterLoop(in0: Option[BufferedReader], out: PrintWriter) {
Result(true, shouldReplay)
}
-
- def addJar(arg: String): Unit = {
+ def addClasspath(arg: String): Unit = {
val f = File(arg).normalize
if (f.exists) {
- addedClasspath :+= f.path
- println("Added " + f.path + " to your classpath.")
+ addedClasspath = ClassPath.join(addedClasspath, f.path)
+ val totalClasspath = ClassPath.join(settings.classpath.value, addedClasspath)
+ println("Added '%s'. Your new classpath is:\n%s".format(f.path, totalClasspath))
replay()
}
- else out.println("The file '" + f + "' doesn't seem to exist.")
+ else out.println("The path '" + f + "' doesn't seem to exist.")
}
/** This isn't going to win any efficiency awards, but it's only
diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala
index b8629279c2..7be39aa27c 100644
--- a/src/compiler/scala/tools/nsc/ScriptRunner.scala
+++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala
@@ -196,8 +196,8 @@ object ScriptRunner
scriptFileIn: String): Boolean =
{
val scriptFile = Path(scriptFileIn).toAbsolute.path
- val compSettingNames = new Settings(error).settingSet.toList map (_.name)
- val compSettings = settings.settingSet.toList filter (compSettingNames contains _.name)
+ val compSettingNames = new Settings(error).visibleSettings.toList map (_.name)
+ val compSettings = settings.visibleSettings.toList filter (compSettingNames contains _.name)
val coreCompArgs = compSettings flatMap (_.unparse)
val compArgs = coreCompArgs ::: List("-Xscript", scriptMain(settings), scriptFile)
var compok = true
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala
index 42d7a50938..69a840cb83 100644
--- a/src/compiler/scala/tools/nsc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/Settings.scala
@@ -15,6 +15,7 @@ import annotation.elidable
import scala.tools.util.{ PathResolver, StringOps }
import scala.collection.mutable.ListBuffer
import scala.collection.immutable.TreeSet
+import interpreter.{ returning }
class Settings(errorFn: String => Unit) extends ScalacSettings {
def this() = this(Console.println)
@@ -65,9 +66,9 @@ class Settings(errorFn: String => Unit) extends ScalacSettings {
}
def processArgumentString(params: String) = processArguments(splitParams(params), true)
- override def hashCode() = settingSet.hashCode
+ override def hashCode() = visibleSettings.hashCode
override def equals(that: Any) = that match {
- case s: Settings => this.settingSet == s.settingSet
+ case s: Settings => this.visibleSettings == s.visibleSettings
case _ => false
}
@@ -88,7 +89,7 @@ class Settings(errorFn: String => Unit) extends ScalacSettings {
case _ => "" == value
}
- for (setting <- settingSet ; (dep, value) <- setting.dependency)
+ for (setting <- visibleSettings ; (dep, value) <- setting.dependency)
if (!setting.isDefault && !hasValue(dep, value)) {
errorFn("incomplete option " + setting.name + " (requires " + dep.name + ")")
return false
@@ -192,7 +193,7 @@ class Settings(errorFn: String => Unit) extends ScalacSettings {
// checks both name and any available abbreviations
def lookupSetting(cmd: String): Option[Setting] =
- settingSet.find(x => x.name == cmd || (x.abbreviations contains cmd))
+ allSettings.find(x => x.name == cmd || (x.abbreviations contains cmd))
// The *Setting classes used to be case classes defined inside of Settings.
// The choice of location was poor because it tied the type of each setting
@@ -205,11 +206,11 @@ class Settings(errorFn: String => Unit) extends ScalacSettings {
//
// For some reason, "object defines extends Setting(...)"
// does not work here. The object is present but the setting
- // is not added to allsettings.
+ // is not added to allSettings.
//
// To capture similar semantics, I created instance methods on setting
// which call a factory method for the right kind of object and then add
- // the newly constructed instance to allsettings. The constructors are
+ // the newly constructed instance to allSettings. The constructors are
// private to force all creation to go through these methods.
//
// The usage of case classes was becoming problematic (due to custom
@@ -221,7 +222,7 @@ class Settings(errorFn: String => Unit) extends ScalacSettings {
// and tell them how to announce errors
private def add[T <: Setting](s: T): T = {
s setErrorHandler errorFn
- allsettings += s
+ allSettings += s
s
}
@@ -243,6 +244,17 @@ class Settings(errorFn: String => Unit) extends ScalacSettings {
lazy val OutputSetting = untupled((output _).tupled andThen add[OutputSetting])
lazy val DefinesSetting = () => add(new DefinesSetting())
+ def PathSetting(name: String, arg: String, descr: String, default: String): PathSetting = {
+ val prepend = new Settings.StringSetting(name + "/p", "", "", "") { override val isInternalOnly = true }
+ val append = new Settings.StringSetting(name + "/a", "", "", "") { override val isInternalOnly = true }
+
+ /** Not flipping this part on just yet.
+ add[StringSetting](prepend)
+ add[StringSetting](append)
+ */
+ returning(new PathSetting(name, arg, descr, default, prepend, append))(x => add[PathSetting](x))
+ }
+
override def toString() = "Settings {\n%s}\n" format (userSetSettings map (" " + _ + "\n") mkString)
}
@@ -401,6 +413,9 @@ object Settings {
/** The name of the option as written on the command line, '-' included. */
def name: String
+ /** If the setting should not appear in help output, etc. */
+ def isInternalOnly = false
+
/** Error handling function, set after creation by enclosing Settings instance */
private var _errorFn: String => Unit = _
private[Settings] def setErrorHandler(e: String => Unit) = _errorFn = e
@@ -578,10 +593,29 @@ object Settings {
override def equals(that: Any) = that match {
case x: StringSetting => this isEq x
- case _ => false
+ case _ => false
}
}
+ class PathSetting private[Settings](
+ name: String,
+ arg: String,
+ descr: String,
+ default: String,
+ prependPath: StringSetting,
+ appendPath: StringSetting)
+ extends StringSetting(name, arg, descr, default) {
+ import ClassPath.join
+ def prepend(s: String) = prependPath.value = join(s, prependPath.value)
+ def append(s: String) = appendPath.value = join(appendPath.value, s)
+
+ override def value = join(
+ prependPath.value,
+ super.value,
+ appendPath.value
+ )
+ }
+
/** Set the output directory. */
class OutputSetting private[Settings](
outputDirs: OutputDirs,
@@ -764,16 +798,16 @@ trait ScalacSettings {
import PathResolver.{ Defaults, Environment }
/** Sorted set of settings */
- protected var allsettings: Set[Setting] = TreeSet[Setting]()
+ protected var allSettings: Set[Setting] = TreeSet[Setting]()
/** All settings */
- def settingSet: Set[Setting] = allsettings
+ def visibleSettings: Set[Setting] = allSettings filterNot (_.isInternalOnly)
/** Set settings */
- def userSetSettings: Set[Setting] = settingSet filterNot (_.isDefault)
+ def userSetSettings: Set[Setting] = visibleSettings filterNot (_.isDefault)
/** Disable a setting */
- def disable(s: Setting) = allsettings -= s
+ def disable(s: Setting) = allSettings -= s
/**
* Temporary Settings
@@ -781,7 +815,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 = ClassPath.join(Seq(classpath.value, entry))
+ classpath.value = ClassPath.join(classpath.value, entry)
if (Ylogcp.value)
Console.println("Updated classpath from '%s' to '%s'".format(oldClasspath, classpath.value))
@@ -791,18 +825,15 @@ trait ScalacSettings {
* Classpath related settings
*/
- val bootclasspath = StringSetting ("-bootclasspath", "path", "Override location of bootstrap class files", "")
- val classpath = StringSetting ("-classpath", "path", "Specify where to find user class files", "") withAbbreviation ("-cp")
- val extdirs = StringSetting ("-extdirs", "dirs", "Override location of installed extensions", "")
- val javabootclasspath = StringSetting ("-javabootclasspath", "path", "Override java boot classpath.", "")
- val javabootAppend = StringSetting ("-javabootclasspath/a", "path", "Append to java boot classpath", "")
- val javabootPrepend = StringSetting ("-javabootclasspath/p", "path", "Prepend to java boot classpath", "")
- val javaextdirs = StringSetting ("-javaextdirs", "path", "Override java extdirs classpath.", "")
-
- val outdir = OutputSetting (outputDirs, ".")
- val sourcepath = StringSetting ("-sourcepath", "path", "Specify where to find input source files", "")
- val Ycodebase = StringSetting ("-Ycodebase", "codebase", "Specify the URL containing the Scala libraries", "")
- val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.")
+ val classpath = PathSetting ("-classpath", "path", "Specify where to find user class files", ".") withAbbreviation ("-cp")
+ val bootclasspath = PathSetting ("-bootclasspath", "path", "Override location of bootstrap class files", Defaults.scalaBootClassPath)
+ val extdirs = PathSetting ("-extdirs", "dirs", "Override location of installed extensions", Defaults.scalaExtDirs)
+ val javabootclasspath = PathSetting ("-javabootclasspath", "path", "Override java boot classpath.", Defaults.javaBootClassPath)
+ val javaextdirs = PathSetting ("-javaextdirs", "path", "Override java extdirs classpath.", Defaults.javaExtDirs)
+
+ val outdir = OutputSetting (outputDirs, ".")
+ val sourcepath = StringSetting ("-sourcepath", "path", "Specify where to find input source files", "")
+ val Ylogcp = BooleanSetting ("-Ylog-classpath", "Output information about what classpath is being applied.")
/**
* Standard settings
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index 59fc790bf1..cc737b9fbb 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -71,10 +71,13 @@ object ClassPath {
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
+ def join(path: String*): String = path filterNot (_ == "") mkString pathSeparator
/** Split the classpath, apply a transformation function, and reassemble it. */
- def map(cp: String, f: String => String): String = join(split(cp) map f)
+ def map(cp: String, f: String => String): String = join(split(cp) map f: _*)
+
+ /** Split the classpath, filter according to predicate, and reassemble. */
+ def filter(cp: String, p: String => Boolean): String = join(split(cp) filter p: _*)
/** Split the classpath and map them into urls */
def toURLs(cp: String): List[URL] = split(cp) map (x => Path(x).toAbsolute.toURL)
@@ -387,10 +390,11 @@ extends ClassPath[T] {
})
}
- def asClasspathString: String = ClassPath.join(entries partialMap {
+ def asClasspathString: String = join(entries partialMap {
case x: DirectoryClassPath => x.dir.path
case x: MergedClassPath[_] => x.asClasspathString
- })
+ }: _*)
+
def show {
println("ClassPath %s has %d entries and results in:\n".format(name, entries.size))
asClasspathString split ':' foreach (x => println(" " + x))