summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAntonio Cunei <antonio.cunei@epfl.ch>2011-03-22 16:12:34 +0000
committerAntonio Cunei <antonio.cunei@epfl.ch>2011-03-22 16:12:34 +0000
commitb40373367e6803349470ecabc3ef646f50353139 (patch)
tree46ffca136ba3e12a0a80f2e93c8c2f05d7b7ad5b /src
parentcf2ad5308cd095521f45aa88d9fe8981ff4717a6 (diff)
downloadscala-b40373367e6803349470ecabc3ef646f50353139.tar.gz
scala-b40373367e6803349470ecabc3ef646f50353139.tar.bz2
scala-b40373367e6803349470ecabc3ef646f50353139.zip
Merged revisions 24525-24539 via svnmerge from
https://lampsvn.epfl.ch/svn-repos/scala/scala/trunk ........ r24525 | kzys | 2011-03-21 13:24:48 +0100 (Mon, 21 Mar 2011) | 1 line [scaladoc] Add HtmlFactoryTest and reorganize directory structure. Reviewed by pedrofurla. ........ r24526 | kzys | 2011-03-21 13:44:20 +0100 (Mon, 21 Mar 2011) | 2 lines [scaladoc] Add a test for #4361. ........ r24527 | plocinic | 2011-03-21 14:37:53 +0100 (Mon, 21 Mar 2011) | 1 line Closes #4202 again, closes #4363. if someone can enlighten me why we actually had that exclusion for companion objects in the first place I would be grateful. review by odersky ........ r24528 | kzys | 2011-03-21 14:47:57 +0100 (Mon, 21 Mar 2011) | 2 lines [scaladoc] Add a test for #4306. Review by pedrofurla. ........ r24529 | extempore | 2011-03-21 17:19:33 +0100 (Mon, 21 Mar 2011) | 2 lines One hundred! One hundred times slower on windows! Ah, ha, ha! Adjusted test case, no review. ........ r24530 | cunei | 2011-03-21 18:08:00 +0100 (Mon, 21 Mar 2011) | 2 lines license files ........ r24531 | cunei | 2011-03-21 18:13:20 +0100 (Mon, 21 Mar 2011) | 2 lines license files. ........ r24532 | cunei | 2011-03-21 18:47:44 +0100 (Mon, 21 Mar 2011) | 5 lines removed gpl Some javascript utils are dual licensed under gpl and mit. We already include the mit ones. ........ r24533 | extempore | 2011-03-21 23:25:40 +0100 (Mon, 21 Mar 2011) | 20 lines [I'm laptop only so there's some chance this will incur temporary breakage, but it needs committing.] Heading off gratuitous complications which haven't yet shipped, I eliminated the -jar startup option in favor of doing what we already do, figuring it out. So now all these things work. scala foo/bar.scala // if file is a script or has one main method scala foo.Bar // if it has a legal main method scala foo.jar // if it has a legal MainClass attribute Also changed "-savecompiled" to "-save" and given scala source called foo.scala, generate foo.jar rather than foo.scala.jar. Cleaned up a bunch of related code and further polished the scala startup message. And unbroke choice settings and improved that error too, which closes #3849. While trying to write a test for the choice setting, was reminded that partest just discards invalid flags files. Made it fail instead, which closes #3712. Fixed the new failures that revealed. No review. ........ r24534 | extempore | 2011-03-21 23:46:53 +0100 (Mon, 21 Mar 2011) | 2 lines We need a successful build, not sure why this hasn't been disabled yet. Disabled failing coder test, no review. ........ r24535 | extempore | 2011-03-22 01:06:44 +0100 (Tue, 22 Mar 2011) | 3 lines Oh the irony, disabling the failing test made the build fail, because another test is hardcoded to use its paths. Disabled that test too. We'll put humpty back together again. No review. ........ r24536 | extempore | 2011-03-22 05:28:21 +0100 (Tue, 22 Mar 2011) | 6 lines Not yet learned my lesson about partest and empty directories. Rather than reapply that bandaid, went after partest. Attempts to make partest ignore empty directories. Discover directory tests aren't run when the command line tool is used, make them run like everyone else. Find more tests which due to misplacement are silently ignored, move them into tested locations. No review. ........ r24537 | kzys | 2011-03-22 15:10:25 +0100 (Tue, 22 Mar 2011) | 2 lines [scaladoc] Closes #4366. Review by pedrofurla. ........ r24538 | moors | 2011-03-22 15:31:36 +0100 (Tue, 22 Mar 2011) | 1 line closes #4205: quick&dirty fix to force loading of info's and thus avoid order-dependency until we fix unsafeTypeParams for good. no review ........ r24539 | moors | 2011-03-22 16:43:28 +0100 (Tue, 22 Mar 2011) | 1 line closes #4345. skip variance checks for calls to super accessor. no review ........
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/GenericRunnerCommand.scala78
-rw-r--r--src/compiler/scala/tools/nsc/GenericRunnerSettings.scala22
-rw-r--r--src/compiler/scala/tools/nsc/MainGenericRunner.scala64
-rw-r--r--src/compiler/scala/tools/nsc/ScriptRunner.scala19
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala14
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/Body.scala13
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala35
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala14
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala7
-rw-r--r--src/compiler/scala/tools/nsc/io/Jar.scala25
-rw-r--r--src/compiler/scala/tools/nsc/io/Path.scala27
-rw-r--r--src/compiler/scala/tools/nsc/io/Sources.scala5
-rw-r--r--src/compiler/scala/tools/nsc/settings/MutableSettings.scala8
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala2
-rw-r--r--src/compiler/scala/tools/nsc/util/ClassPath.scala1
-rw-r--r--src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala9
-rw-r--r--src/partest/scala/tools/partest/PartestTask.scala1
-rw-r--r--src/partest/scala/tools/partest/nest/CompileManager.scala15
-rw-r--r--src/partest/scala/tools/partest/nest/ConsoleRunner.scala39
-rw-r--r--src/partest/scala/tools/partest/nest/DirectRunner.scala17
-rw-r--r--src/partest/scala/tools/partest/nest/TestFile.scala19
26 files changed, 262 insertions, 182 deletions
diff --git a/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala b/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
index 68689a4109..86ab76b59c 100644
--- a/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
+++ b/src/compiler/scala/tools/nsc/GenericRunnerCommand.scala
@@ -5,6 +5,8 @@
package scala.tools.nsc
+import GenericRunnerCommand._
+
/** A command for ScriptRunner */
class GenericRunnerCommand(
args: List[String],
@@ -24,30 +26,31 @@ extends CompilerCommand(args, settings) {
// change CompilerCommand behavior
override def shouldProcessArguments: Boolean = false
- /** thingToRun: What to run. If it is None, then the interpreter should be started
- * arguments: Arguments to pass to the object or script to run
- */
- val (_ok, thingToRun, arguments) = {
- val (ok, remaining) = settings.processArguments(args, false)
- val mainClass =
- if (settings.jarfile.isDefault) None
- else new io.Jar(settings.jarfile.value).mainClass
-
- // If there is a jar with a main class, the remaining args are passed to that.
- // Otherwise, the first remaining argument is the program to run, and the rest
- // of the arguments go to it. If remaining is empty, we'll start the repl.
- mainClass match {
- case Some(name) => (ok, Some(name), remaining)
- case _ => (ok, remaining.headOption, remaining drop 1)
+ private lazy val (_ok, targetAndArguments) = settings.processArguments(args, false)
+ override def ok = _ok
+ private def guessHowToRun(target: String): GenericRunnerCommand.HowToRun = {
+ if (!ok) Error
+ else if (io.Jar.isJarOrZip(target)) AsJar
+ else if (util.ScalaClassLoader.classExists(settings.classpathURLs, target)) AsObject
+ else {
+ val f = io.File(target)
+ if (!f.hasExtension("class", "jar", "zip") && f.canRead) AsScript
+ else sys.error("Cannot figure out how to run target: " + target)
}
}
- override def ok = _ok
-
+ /** String with either the jar file, class name, or script file name. */
+ def thingToRun = targetAndArguments.headOption getOrElse ""
+ /** Arguments to thingToRun. */
+ def arguments = targetAndArguments drop 1
+
+ val howToRun = targetAndArguments match {
+ case Nil => AsRepl
+ case hd :: _ => waysToRun find (_.name == settings.howtorun.value) getOrElse guessHowToRun(hd)
+ }
private def interpolate(s: String) = s.trim.replaceAll("@cmd@", cmdName).replaceAll("@compileCmd@", compCmdName) + "\n"
def shortUsageMsg = interpolate("""
-Usage: @cmd@ <options> [<script|class|object> <arguments>]
- or @cmd@ <options> [-jar <jarfile> <arguments>]
+Usage: @cmd@ <options> [<script|class|object|jar> <arguments>]
or @cmd@ -help
All options to @compileCmd@ are also allowed. See @compileCmd@ -help.
@@ -59,26 +62,37 @@ what to run. Runnable targets are:
- a file containing scala source
- the name of a compiled class
- - a runnable jar file with a Main-Class attribute (if -jar is given)
- - if no argument is given, the repl (interactive shell) is started
+ - a runnable jar file with a valid Main-Class attribute
+ - or if no argument is given, the repl (interactive shell) is started
-Options to the runner which reach the java runtime:
+Options to @cmd@ which reach the java runtime:
-Dname=prop passed directly to java to set system properties
-J<arg> -J is stripped and <arg> passed to java as-is
-nobootcp do not put the scala jars on the boot classpath (slower)
-Other scala startup options:
+Other startup options:
- -howtorun specify what to run <script|object|guess> (default: guess)
- -i <file> preload <file> before starting the repl
- -e <string> execute <string> as if entered in the repl
- -nc no compilation daemon: do not use the fsc offline compiler
- -savecompiled save the compiled script in a jar for future use
+ -howtorun what to run <script|object|jar|guess> (default: guess)
+ -i <file> preload <file> before starting the repl
+ -e <string> execute <string> as if entered in the repl
+ -save save the compiled script in a jar for future use
+ -nc no compilation daemon: do not use the fsc offline compiler
-A file argument will be run as a scala script unless it contains only top
-level classes and objects, and exactly one runnable main method. In that
-case the file will be compiled and the main method invoked. This provides
-a bridge between scripts and standard scala source.
+A file argument will be run as a scala script unless it contains only
+self-contained compilation units (classes and objects) and exactly one
+runnable main method. In that case the file will be compiled and the
+main method invoked. This provides a bridge between scripts and standard
+scala source.
""") + "\n"
}
+
+object GenericRunnerCommand {
+ sealed abstract class HowToRun(val name: String) { }
+ case object AsJar extends HowToRun("jar")
+ case object AsObject extends HowToRun("object")
+ case object AsScript extends HowToRun("script")
+ case object AsRepl extends HowToRun("repl")
+ case object Error extends HowToRun("<error>")
+ val waysToRun = List(AsJar, AsObject, AsScript, AsRepl)
+}
diff --git a/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala b/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala
index bd0ea4a4ba..45f8d1af5f 100644
--- a/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala
+++ b/src/compiler/scala/tools/nsc/GenericRunnerSettings.scala
@@ -5,24 +5,17 @@
package scala.tools.nsc
+import scala.tools.util.PathResolver
+
class GenericRunnerSettings(error: String => Unit) extends Settings(error) {
- // A -jar option means the remainder of the command line should be
- // passed to the main program in the jar. If -jar is given, jarfile
- // will be set, but we also need to prepend the jar to the classpath
- // since it may not be there.
- val jarfile =
- StringSetting(
- "-jar",
- "jar",
- "Specify the jarfile in which to look for the main class",
- "").stopProcessing() withPostSetHook (classpath prepend _.value)
+ def classpathURLs = new PathResolver(this) asURLs
val howtorun =
ChoiceSetting(
"-howtorun",
"how",
"how to run the specified code",
- List("guess", "object", "script"),
+ List("object", "script", "jar", "guess"),
"guess")
val loadfiles =
@@ -38,14 +31,15 @@ class GenericRunnerSettings(error: String => Unit) extends Settings(error) {
"execute a single command",
"")
- val savecompiled =
+ val save =
BooleanSetting(
- "-savecompiled",
- "save the compiled script (assumes the code is a script)")
+ "-save",
+ "save the compiled script (assumes the code is a script)") withAbbreviation "-savecompiled"
val nc = BooleanSetting(
"-nc",
"do not use the fsc compilation daemon") withAbbreviation "-nocompdaemon"
@deprecated("Use `nc` instead") def nocompdaemon = nc
+ @deprecated("Use `save` instead") def savecompiled = save
}
diff --git a/src/compiler/scala/tools/nsc/MainGenericRunner.scala b/src/compiler/scala/tools/nsc/MainGenericRunner.scala
index e40fdea3b9..7ead4cce4a 100644
--- a/src/compiler/scala/tools/nsc/MainGenericRunner.scala
+++ b/src/compiler/scala/tools/nsc/MainGenericRunner.scala
@@ -13,6 +13,7 @@ import io.{ File }
import util.{ ClassPath, ScalaClassLoader }
import Properties.{ versionString, copyrightString }
import interpreter.{ ILoop }
+import GenericRunnerCommand._
/** An object that runs Scala code. It has three possible
* sources for the code to run: pre-compiled code, a script file,
@@ -35,7 +36,7 @@ object MainGenericRunner {
def process(args: Array[String]): Boolean = {
val command = new GenericRunnerCommand(args.toList, (x: String) => errorFn(x))
- import command.settings
+ import command.{ settings, howToRun, thingToRun }
def sampleCompiler = new Global(settings) // def so its not created unless needed
if (!command.ok) return errorFn("\n" + command.shortUsageMsg)
@@ -55,44 +56,35 @@ object MainGenericRunner {
files ++ str mkString "\n\n"
}
- val classpath: List[URL] = new PathResolver(settings) asURLs
+ def runTarget(): Either[Throwable, Boolean] = howToRun match {
+ case AsObject =>
+ ObjectRunner.runAndCatch(settings.classpathURLs, thingToRun, command.arguments)
+ case AsScript =>
+ ScriptRunner.runScriptAndCatch(settings, thingToRun, command.arguments)
+ case AsJar =>
+ ObjectRunner.runAndCatch(
+ File(thingToRun).toURL +: settings.classpathURLs,
+ new io.Jar(thingToRun).mainClass getOrElse sys.error("Cannot find main class for jar: " + thingToRun),
+ command.arguments
+ )
+ case _ =>
+ // We start the repl when no arguments are given.
+ Right(new ILoop process settings)
+ }
- /** Was code given in a -e argument? */
+ /** If -e and -i were both given, we want to execute the -e code after the
+ * -i files have been included, so they are read into strings and prepended to
+ * the code given in -e. The -i option is documented to only make sense
+ * interactively so this is a pretty reasonable assumption.
+ *
+ * This all needs a rewrite though.
+ */
if (isE) {
- /** If a -i argument was also given, we want to execute the code after the
- * files have been included, so they are read into strings and prepended to
- * the code given in -e. The -i option is documented to only make sense
- * interactively so this is a pretty reasonable assumption.
- *
- * This all needs a rewrite though.
- */
- val fullArgs = command.thingToRun.toList ::: command.arguments
-
- return ScriptRunner.runCommand(settings, combinedCode, fullArgs)
+ ScriptRunner.runCommand(settings, combinedCode, thingToRun +: command.arguments)
}
- else command.thingToRun match {
- case None =>
- // We start the repl when no arguments are given.
- new ILoop process settings
-
- case Some(thingToRun) =>
- val isObjectName =
- settings.howtorun.value match {
- case "object" => true
- case "script" => false
- case "guess" => ScalaClassLoader.classExists(classpath, thingToRun)
- }
-
- val result = try {
- if (isObjectName) ObjectRunner.runAndCatch(classpath, thingToRun, command.arguments)
- else ScriptRunner.runScriptAndCatch(settings, thingToRun, command.arguments)
- }
- catch { case ex => Left(ex) }
-
- result match {
- case Left(ex) => errorFn(ex)
- case Right(b) => b
- }
+ else runTarget() match {
+ case Left(ex) => errorFn(ex)
+ case Right(b) => b
}
}
}
diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala
index 07aa62d164..96b7bce885 100644
--- a/src/compiler/scala/tools/nsc/ScriptRunner.scala
+++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala
@@ -61,13 +61,10 @@ class ScriptRunner extends HasCompileSocket {
def isScript(settings: Settings) = settings.script.value != ""
/** Choose a jar filename to hold the compiled version of a script. */
- private def jarFileFor(scriptFile: String): File = {
- val name =
- if (scriptFile endsWith ".jar") scriptFile
- else scriptFile + ".jar"
-
- File(name)
- }
+ private def jarFileFor(scriptFile: String)= File(
+ if (scriptFile endsWith ".jar") scriptFile
+ else scriptFile.stripSuffix(".scala") + ".jar"
+ )
/** Read the entire contents of a file as a String. */
private def contentsOfFile(filename: String) = File(filename).slurp()
@@ -140,7 +137,7 @@ class ScriptRunner extends HasCompileSocket {
* not take place until there are no non-daemon threads running. Tickets #1955, #2006.
*/
waitingForThreads {
- if (settings.savecompiled.value) {
+ if (settings.save.value) {
val jarFile = jarFileFor(scriptFile)
def jarOK = jarFile.canRead && (jarFile isFresher File(scriptFile))
@@ -179,10 +176,8 @@ class ScriptRunner extends HasCompileSocket {
compiledLocation: String,
scriptArgs: List[String]): Boolean =
{
- val pr = new PathResolver(settings)
- val classpath = File(compiledLocation).toURL +: pr.asURLs
-
- ObjectRunner.runAndCatch(classpath, scriptMain(settings), scriptArgs) match {
+ val cp = File(compiledLocation).toURL +: settings.classpathURLs
+ ObjectRunner.runAndCatch(cp, scriptMain(settings), scriptArgs) match {
case Left(ex) => ex.printStackTrace() ; false
case _ => true
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala
index 199c184bfc..a14bacb267 100644
--- a/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala
@@ -64,20 +64,24 @@ class HtmlFactory(val universe: doc.Universe, index: doc.Index) {
new page.Index(universe, index) writeFor this
+ writeTemplates(page => page.writeFor(this))
+
+ for(letter <- index.firstLetterIndex) {
+ new html.page.ReferenceIndex(letter._1, index, universe) writeFor this
+ }
+ }
+
+ def writeTemplates(writeForThis: HtmlPage => Unit): Unit = {
val written = mutable.HashSet.empty[DocTemplateEntity]
def writeTemplate(tpl: DocTemplateEntity): Unit =
if (!(written contains tpl)) {
- new page.Template(tpl) writeFor this
+ writeForThis(new page.Template(tpl))
written += tpl
tpl.templates map (writeTemplate(_))
}
writeTemplate(universe.rootPackage)
-
- for(letter <- index.firstLetterIndex) {
- new html.page.ReferenceIndex(letter._1, index, universe) writeFor this
- }
}
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
index 95016099ff..21d6ba91a9 100644
--- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -34,7 +34,7 @@ abstract class HtmlPage { thisPage =>
protected def headers: NodeSeq
/** The body of this page. */
- protected def body: NodeSeq
+ def body: NodeSeq
/** Writes this page as a file. The file's location is relative to the generator's site root, and the encoding is
* also defined by the generator.
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala b/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
index dd2093a88e..52ef154325 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
@@ -67,7 +67,18 @@ final case class Link(target: String, title: Inline) extends Inline
final case class EntityLink(target: TemplateEntity) extends Inline
final case class Monospace(text: String) extends Inline
final case class Text(text: String) extends Inline
-final case class HtmlTag(data: String) extends Inline
+final case class HtmlTag(data: String) extends Inline {
+ def canClose(open: HtmlTag) = {
+ open.data.stripPrefix("<") == data.stripPrefix("</")
+ }
+
+ def close = {
+ if (data.indexOf("</") == -1)
+ Some(HtmlTag("</" + data.stripPrefix("<")))
+ else
+ None
+ }
+}
/** The summary of a comment, usually its first sentence. There must be exactly one summary per body. */
final case class Summary(text: Inline) extends Inline
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala b/src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala
index e39907ac55..b3033188e9 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala
@@ -18,8 +18,41 @@ abstract class Comment {
/** The main body of the comment that describes what the entity does and is. */
def body: Body
+ private def closeHtmlTags(inline: Inline) = {
+ val stack = mutable.ListBuffer.empty[HtmlTag]
+ def scan(i: Inline): Unit = {
+ i match {
+ case Chain(list) =>
+ list.foreach(scan)
+ case tag: HtmlTag => {
+ if (stack.length > 0 && tag.canClose(stack.last)) {
+ stack.remove(stack.length-1)
+ } else {
+ tag.close match {
+ case Some(t) =>
+ stack += t
+ case None =>
+ ;
+ }
+ }
+ }
+ case _ =>
+ ;
+ }
+ }
+ scan(inline)
+ Chain(List(inline) ++ stack.reverse)
+ }
+
/** A shorter version of the body. Usually, this is the first sentence of the body. */
- def short: Inline = body.summary getOrElse Text("")
+ def short: Inline = {
+ body.summary match {
+ case Some(s) =>
+ closeHtmlTags(s)
+ case _ =>
+ Text("")
+ }
+ }
/** A list of authors. The empty list is used when no author is defined. */
def authors: List[Body]
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
index d82d5bfa5a..7485533641 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
@@ -172,7 +172,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
/** Safe HTML tags that can be kept. */
protected val SafeTags =
- new Regex("""((&\w+;)|(&#\d+;)|(<code( [^>]*)?>.*</code>)|(</?(abbr|acronym|address|area|a|bdo|big|blockquote|br|button|b|caption|cite|col|colgroup|dd|del|dfn|em|fieldset|form|hr|img|input|ins|i|kbd|label|legend|link|map|object|optgroup|option|param|pre|q|samp|select|small|span|strong|sub|sup|table|tbody|td|textarea|tfoot|th|thead|tr|tt|var)( [^>]*)?/?>))""")
+ new Regex("""((&\w+;)|(&#\d+;)|(<code( [^>]*)?>.*?</code>)|(</?(abbr|acronym|address|area|a|bdo|big|blockquote|br|button|b|caption|cite|col|colgroup|dd|del|dfn|em|fieldset|form|hr|img|input|ins|i|kbd|label|legend|link|map|object|optgroup|option|param|pre|q|samp|select|small|span|strong|sub|sup|table|tbody|td|textarea|tfoot|th|thead|tr|tt|var)( [^>]*)?/?>))""")
protected val safeTagMarker = '\u000E'
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index 3d4ff7a20b..584b8867b2 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -38,7 +38,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
with LoopCommands
{
def this(in0: BufferedReader, out: PrintWriter) = this(Some(in0), out)
- def this() = this(None, new PrintWriter(Console.out))
+ def this() = this(None, new PrintWriter(Console.out, true))
var in: InteractiveReader = _ // the input stream from which commands come
var settings: Settings = _
@@ -162,8 +162,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
|Type in expressions to have them evaluated.
|Type :help for more information.""" .
stripMargin.format(versionString, javaVmName, javaVersion)
+ val addendum = if (isReplDebug) "\n" + new java.util.Date else ""
- plushln(welcomeMsg)
+ plushln(welcomeMsg + addendum)
}
/** Show the history */
@@ -748,7 +749,12 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
}
@deprecated("Use `process` instead")
- def main(args: Array[String]): Unit = process(args)
+ def main(args: Array[String]): Unit = {
+ if (isReplDebug)
+ System.out.println(new java.util.Date)
+
+ process(args)
+ }
@deprecated("Use `process` instead")
def main(settings: Settings): Unit = process(settings)
}
@@ -765,7 +771,7 @@ object ILoop {
stringFromStream { ostream =>
Console.withOut(ostream) {
val input = new BufferedReader(new StringReader(code))
- val output = new PrintWriter(new OutputStreamWriter(ostream))
+ val output = new PrintWriter(new OutputStreamWriter(ostream), true)
val repl = new ILoop(input, output)
val settings = new Settings
settings.classpath.value = sys.props("java.class.path")
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 527a9b153a..d74aa5e6df 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -87,6 +87,8 @@ class IMain(val settings: Settings, protected val out: PrintWriter) {
// not sure if we have some motivation to print directly to console
private def echo(msg: String) { Console println msg }
+ // protected def defaultImports: List[String] = List("_root_.scala.sys.exit")
+
/** We're going to go to some trouble to initialize the compiler asynchronously.
* It's critical that nothing call into it until it's been initialized or we will
* run into unrecoverable issues, but the perceived repl startup time goes
@@ -114,6 +116,7 @@ class IMain(val settings: Settings, protected val out: PrintWriter) {
// Can't use printMessage here, it deadlocks
Console.println("Repl compiler initialized.")
}
+ // addImports(defaultImports: _*)
true
}
catch {
@@ -609,6 +612,10 @@ class IMain(val settings: Settings, protected val out: PrintWriter) {
quietRun("val %s = %s".format(tempName, name))
quietRun("val %s = %s.asInstanceOf[%s]".format(name, tempName, newType))
}
+ def quietImport(ids: String*): IR.Result = beQuietDuring(addImports(ids: _*))
+ def addImports(ids: String*): IR.Result =
+ if (ids.isEmpty) IR.Success
+ else interpret("import " + ids.mkString(", "))
def quietBind(p: NamedParam): IR.Result = beQuietDuring(bind(p))
def bind(p: NamedParam): IR.Result = bind(p.name, p.tpe, p.value)
diff --git a/src/compiler/scala/tools/nsc/io/Jar.scala b/src/compiler/scala/tools/nsc/io/Jar.scala
index 0796742fb6..a9f0acaa00 100644
--- a/src/compiler/scala/tools/nsc/io/Jar.scala
+++ b/src/compiler/scala/tools/nsc/io/Jar.scala
@@ -65,8 +65,29 @@ class JarWriter(file: File, val manifest: Manifest = new Manifest()) {
}
object Jar {
- // CLASS_PATH
- // CONTENT_TYPE
+ // See http://download.java.net/jdk7/docs/api/java/nio/file/Path.html
+ // for some ideas.
+ private val ZipMagicNumber = List[Byte](80, 75, 3, 4)
+ private def magicNumberIsZip(f: Path) = f.isFile && (f.toFile.bytes().take(4).toList == ZipMagicNumber)
+
+ def isJarOrZip(f: Path): Boolean = isJarOrZip(f, true)
+ def isJarOrZip(f: Path, examineFile: Boolean): Boolean =
+ f.hasExtension("zip", "jar") || (examineFile && magicNumberIsZip(f))
+
+ def locateByClass(clazz: Class[_]): Option[File] = {
+ try Some(File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()))
+ catch { case _: Exception => None }
+ }
+ /** Walks upward from wherever the scala library jar is searching for
+ * the given jar name. This approach finds the scala library jar in the
+ * release layout and in trunk builds going up from pack.
+ */
+ def locateByName(name: String): Option[File] = {
+ def toSrc(d: Directory) = d.dirs.toList map (_ / name)
+ def walk(d: Directory) = d.parents flatMap toSrc find (_.isFile) map (_.toFile)
+
+ locateByClass(classOf[ScalaObject]) flatMap (x => walk(x.parent))
+ }
def create(file: File, sourceDir: Directory, mainClass: String): File = {
val writer = new Jar(file).jarWriter()
diff --git a/src/compiler/scala/tools/nsc/io/Path.scala b/src/compiler/scala/tools/nsc/io/Path.scala
index 68e9867dd7..3cfab55aaa 100644
--- a/src/compiler/scala/tools/nsc/io/Path.scala
+++ b/src/compiler/scala/tools/nsc/io/Path.scala
@@ -28,37 +28,12 @@ import scala.util.Random.alphanumeric
*/
object Path {
- // See http://download.java.net/jdk7/docs/api/java/nio/file/Path.html
- // for some ideas.
- private val ZipMagicNumber = List[Byte](80, 75, 3, 4)
- private def magicNumberIsZip(f: Path) = f.isFile && (f.toFile.bytes().take(4).toList == ZipMagicNumber)
-
- /** If examineFile is true, it will look at the first four bytes of the file
- * and see if the magic number indicates it may be a jar or zip.
- */
- def isJarOrZip(f: Path): Boolean = isJarOrZip(f, true)
- def isJarOrZip(f: Path, examineFile: Boolean): Boolean =
- f.hasExtension("zip", "jar") || (examineFile && magicNumberIsZip(f))
+ def isJarOrZip(f: Path, examineFile: Boolean = true) = Jar.isJarOrZip(f, examineFile)
// not certain these won't be problematic, but looks good so far
implicit def string2path(s: String): Path = apply(s)
implicit def jfile2path(jfile: JFile): Path = apply(jfile)
- def locateJarByClass(clazz: Class[_]): Option[File] = {
- try Some(File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()))
- catch { case _: Exception => None }
- }
- /** Walks upward from wherever the scala library jar is searching for
- * the given jar name. This approach finds the scala library jar in the
- * release layout and in trunk builds going up from pack.
- */
- def locateJarByName(name: String): Option[File] = {
- def toSrc(d: Directory) = d.dirs.toList map (_ / name)
- def walk(d: Directory) = d.parents flatMap toSrc find (_.isFile) map (_.toFile)
-
- locateJarByClass(classOf[ScalaObject]) flatMap (x => walk(x.parent))
- }
-
// java 7 style, we don't use it yet
// object AccessMode extends Enumeration("AccessMode") {
// val EXECUTE, READ, WRITE = Value
diff --git a/src/compiler/scala/tools/nsc/io/Sources.scala b/src/compiler/scala/tools/nsc/io/Sources.scala
index 48682e4ad4..c763b04511 100644
--- a/src/compiler/scala/tools/nsc/io/Sources.scala
+++ b/src/compiler/scala/tools/nsc/io/Sources.scala
@@ -4,7 +4,7 @@ package io
import util.ClassPath
import java.util.concurrent.{ Future, ConcurrentHashMap, ExecutionException }
import java.util.zip.ZipException
-import Path.{ isJarOrZip, locateJarByName }
+import Jar.{ isJarOrZip, locateByClass }
import collection.JavaConverters._
import Properties.{ envOrElse, propOrElse }
@@ -62,7 +62,6 @@ trait LowPrioritySourcesImplicits {
implicit def fallbackSources: Sources = defaultSources
}
-
object Sources extends LowPrioritySourcesImplicits {
// Examples of what libraryJar might be, each of which we'd like to find
// the source files automatically:
@@ -70,7 +69,7 @@ object Sources extends LowPrioritySourcesImplicits {
// /scala/trunk/build/pack/lib/scala-library.jar
// /scala/trunk/build/quick/classes/library
// /scala/inst/scala-2.9.0.r24213-b20110206233447/lib/scala-library.jar
- private def libraryJar = Path.locateJarByClass(classOf[ScalaObject]) map (_.toAbsolute.path)
+ private def libraryJar = locateByClass(classOf[ScalaObject]) map (_.toAbsolute.path)
private def autoSourcePaths: List[String] = libraryJar.toList flatMap { lib =>
val markers = List("build/pack/lib", "build/quick/classes", "scala-library.jar")
markers filter (lib contains _) flatMap { m =>
diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
index 6a357cc08a..b485d4725a 100644
--- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
@@ -527,10 +527,14 @@ class MutableSettings(val errorFn: String => Unit) extends AbsSettings with Scal
protected var v: String = default
def indexOfChoice: Int = choices indexOf value
- def tryToSet(args: List[String]) = { value = default ; Some(args) }
+ private def usageErrorMessage = {
+ "Usage: %s:<%s>\n where <%s> choices are %s (default: %s)\n".format(
+ name, helpArg, helpArg, choices mkString ", ", default)
+ }
+ def tryToSet(args: List[String]) = errorAndValue(usageErrorMessage, None)
override def tryToSetColon(args: List[String]) = args match {
- case Nil => errorAndValue("missing " + helpArg, None)
+ case Nil => errorAndValue(usageErrorMessage, None)
case List(x) if choices contains x => value = x ; Some(Nil)
case List(x) => errorAndValue("'" + x + "' is not a valid choice for '" + name + "'", None)
case xs => errorAndValue("'" + name + "' does not accept multiple arguments.", None)
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 0240e80816..d7f9063ec6 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1309,7 +1309,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
* class Foo . companionModule --> object Foo
*/
final def companionModule: Symbol =
- if (isClass && !isAnonOrRefinementClass) companionModule0
+ if (isClass && !isRefinementClass) companionModule0
else NoSymbol
/** For a module: its linked class
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index fd86fb7345..3e41df45f8 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -5618,6 +5618,7 @@ A type's typeSymbol should never be inspected directly.
val errors = new ListBuffer[(Type, Symbol, List[(Symbol, Symbol)], List[(Symbol, Symbol)], List[(Symbol, Symbol)])]
(tparams zip targs).foreach{ case (tparam, targ) if (targ.isHigherKinded || !tparam.typeParams.isEmpty) =>
// @M must use the typeParams of the type targ, not the typeParams of the symbol of targ!!
+ targ.typeSymbolDirect.info // force symbol load for #4205
val tparamsHO = targ.typeParams
val (arityMismatches, varianceMismatches, stricterBounds) =
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 05224ae37b..caba8f9bd1 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -574,10 +574,9 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
private def staticRef(sym: Symbol): Tree = {
sym.owner.info //todo: needed?
sym.owner.owner.info //todo: needed?
- if (sym.owner.sourceModule == NoSymbol) {
+ if (sym.owner.sourceModule == NoSymbol)
assert(false, "" + sym + " in " + sym.owner + " in " + sym.owner.owner +
" " + sym.owner.owner.info.decls.toList)//debug
- }
REF(sym.owner.sourceModule) DOT sym
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 3d769f6cfd..63542e6dd5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -688,7 +688,7 @@ abstract class RefChecks extends InfoTransform {
!(tvar.isTypeParameterOrSkolem && sym.isTypeParameterOrSkolem &&
tvar.owner == sym.owner)) state = -state;
else if (!sym.owner.isClass ||
- sym.isTerm && ((sym.isPrivateLocal || sym.isProtectedLocal) && !(escapedPrivateLocals contains sym))) {
+ sym.isTerm && ((sym.isPrivateLocal || sym.isProtectedLocal || sym.isSuperAccessor /* super accessors are implicitly local #4345*/) && !(escapedPrivateLocals contains sym))) {
// return AnyVariance if `sym` is local to a term
// or is private[this] or protected[this]
state = AnyVariance
diff --git a/src/compiler/scala/tools/nsc/util/ClassPath.scala b/src/compiler/scala/tools/nsc/util/ClassPath.scala
index 1e29dd4fae..bb404480a9 100644
--- a/src/compiler/scala/tools/nsc/util/ClassPath.scala
+++ b/src/compiler/scala/tools/nsc/util/ClassPath.scala
@@ -83,6 +83,7 @@ object ClassPath {
/** Join the paths as a classpath */
def fromPaths(paths: Path*): String = join(paths map (_.path): _*)
+ def fromURLs(urls: URL*): String = fromPaths(urls map (x => Path(x.getPath)) : _*)
/** Split the classpath and map them into URLs */
def toURLs(cp: String): List[URL] = toPaths(cp) map (_.toURL)
diff --git a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala
index ee71d04827..be69c39547 100644
--- a/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala
+++ b/src/compiler/scala/tools/nsc/util/ScalaClassLoader.scala
@@ -93,13 +93,20 @@ object ScalaClassLoader {
with ScalaClassLoader {
private var classloaderURLs = urls.toList
+ private def classpathString = ClassPath.fromURLs(urls: _*)
/** Override to widen to public */
override def addURL(url: URL) = {
classloaderURLs +:= url
super.addURL(url)
}
-
+ override def run(objectName: String, arguments: Seq[String]) {
+ try super.run(objectName, arguments)
+ catch { case x: ClassNotFoundException =>
+ throw new ClassNotFoundException(objectName +
+ " (args = %s, classpath = %s)".format(arguments mkString ", ", classpathString))
+ }
+ }
override def toString = urls.mkString("URLClassLoader(\n ", "\n ", "\n)\n")
}
diff --git a/src/partest/scala/tools/partest/PartestTask.scala b/src/partest/scala/tools/partest/PartestTask.scala
index 551500e626..f1b3ea496d 100644
--- a/src/partest/scala/tools/partest/PartestTask.scala
+++ b/src/partest/scala/tools/partest/PartestTask.scala
@@ -14,7 +14,6 @@ package partest
import scala.actors.Actor._
import scala.util.Properties.setProp
import scala.tools.nsc.io.{ Directory, Path => SPath }
-import nsc.Settings
import nsc.util.ClassPath
import util.PathResolver
import scala.tools.ant.sabbus.CompilationPathProperty
diff --git a/src/partest/scala/tools/partest/nest/CompileManager.scala b/src/partest/scala/tools/partest/nest/CompileManager.scala
index 42e4d02934..fbf758d5a5 100644
--- a/src/partest/scala/tools/partest/nest/CompileManager.scala
+++ b/src/partest/scala/tools/partest/nest/CompileManager.scala
@@ -10,10 +10,9 @@ package nest
import scala.tools.nsc.{ Global, Settings, CompilerCommand, FatalError, io }
import scala.tools.nsc.reporters.{ Reporter, ConsoleReporter }
-import scala.tools.nsc.util.ClassPath
+import scala.tools.nsc.util.{ ClassPath, FakePos }
import scala.tools.util.PathResolver
import io.Path
-
import java.io.{ File, BufferedReader, PrintWriter, FileReader, Writer, FileWriter, StringWriter }
import File.pathSeparator
@@ -95,7 +94,13 @@ class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler {
case "presentation" => PresentationTestFile.apply
}
val test: TestFile = testFileFn(files.head, fileManager)
- test.defineSettings(command.settings, out.isEmpty)
+ if (!test.defineSettings(command.settings, out.isEmpty)) {
+ testRep.error(FakePos("partest"), test.flags match {
+ case Some(flags) => "bad flags: " + flags
+ case _ => "bad settings: " + command.settings
+ })
+ }
+
val toCompile = files map (_.getPath)
try {
@@ -106,8 +111,8 @@ class DirectCompiler(val fileManager: FileManager) extends SimpleCompiler {
testRep.error(null, "fatal error: " + msg)
}
- testRep.printSummary
- testRep.writer.close
+ testRep.printSummary()
+ testRep.writer.close()
}
finally logWriter.close()
diff --git a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
index b79c2bbbdb..e2afc5644f 100644
--- a/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
+++ b/src/partest/scala/tools/partest/nest/ConsoleRunner.scala
@@ -21,22 +21,23 @@ class ConsoleRunner extends DirectRunner {
import PathSettings.{ srcDir, testRoot }
case class TestSet(kind: String, filter: Path => Boolean, msg: String)
+ def stdFilter(p: Path) = p.isDirectory || (p hasExtension "scala")
val testSets = {
- val pathFilter: Path => Boolean = _ hasExtension "scala"
+ val pathFilter: Path => Boolean = x => x.isDirectory || (x hasExtension "scala")
List(
- TestSet("pos", pathFilter, "Testing compiler (on files whose compilation should succeed)"),
- TestSet("neg", pathFilter, "Testing compiler (on files whose compilation should fail)"),
- TestSet("run", pathFilter, "Testing interpreter and backend"),
- TestSet("jvm", pathFilter, "Testing JVM backend"),
+ TestSet("pos", stdFilter, "Testing compiler (on files whose compilation should succeed)"),
+ TestSet("neg", stdFilter, "Testing compiler (on files whose compilation should fail)"),
+ TestSet("run", stdFilter, "Testing interpreter and backend"),
+ TestSet("jvm", stdFilter, "Testing JVM backend"),
TestSet("res", x => x.isFile && (x hasExtension "res"), "Testing resident compiler"),
TestSet("buildmanager", _.isDirectory, "Testing Build Manager"),
- TestSet("shootout", pathFilter, "Testing shootout tests"),
- TestSet("script", pathFilter, "Testing script tests"),
- TestSet("scalacheck", x => pathFilter(x) || x.isDirectory, "Testing ScalaCheck tests"),
+ TestSet("shootout", stdFilter, "Testing shootout tests"),
+ TestSet("script", stdFilter, "Testing script tests"),
+ TestSet("scalacheck", stdFilter, "Testing ScalaCheck tests"),
TestSet("scalap", _.isDirectory, "Run scalap decompiler tests"),
- TestSet("specialized", pathFilter, "Testing specialized tests"),
+ TestSet("specialized", stdFilter, "Testing specialized tests"),
TestSet("presentation", _.isDirectory, "Testing presentation compiler tests.")
)
}
@@ -49,10 +50,7 @@ class ConsoleRunner extends DirectRunner {
private val testSetArgs = testSets map ("--" + _.kind)
private val testSetArgMap = testSetArgs zip testSets toMap
- def denotesTestSet(arg: String) = testSetArgs contains arg
- def denotesTestFile(arg: String) = (arg endsWith ".scala") || (arg endsWith ".res")
- def denotesTestDir(arg: String) = Path(arg).isDirectory
- def denotesTestPath(arg: String) = denotesTestDir(arg) || denotesTestFile(arg)
+ def denotesTestSet(arg: String) = testSetArgs contains arg
private def printVersion { NestUI outline (versionMsg + "\n") }
@@ -72,22 +70,17 @@ class ConsoleRunner extends DirectRunner {
(path.isFile && pred(path)) ||
(path.isDirectory && srcs.exists(pred)) ||
- (pred(Path(path.toAbsolute.stripExtension + ".check")))
+ (pred(path changeExtension "check"))
}
def main(argstr: String) {
val parsed = CommandLineParser(argstr) withUnaryArgs unaryArgs withBinaryArgs binaryArgs
- val args = parsed.residualArgs
+ val args = onlyValidTestPaths(parsed.residualArgs)
/** Early return on no args, version, or invalid args */
if (argstr == "") return NestUI.usage()
if (parsed isSet "--version") return printVersion
if (parsed isSet "--help") return NestUI.usage()
- if (args exists (x => !denotesTestPath(x))) {
- val invalid = (args filterNot denotesTestPath).head
- NestUI.failure("Invalid argument '%s'\n" format invalid)
- return NestUI.usage()
- }
parsed get "--srcpath" foreach (x => setProp("partest.srcdir", x))
@@ -97,7 +90,7 @@ class ConsoleRunner extends DirectRunner {
else if (parsed isSet "--pack") new ConsoleFileManager("build/pack")
else new ConsoleFileManager // auto detection, see ConsoleFileManager.findLatest
- def argNarrowsTests(x: String) = denotesTestSet(x) || denotesTestFile(x) || denotesTestDir(x)
+ def argNarrowsTests(x: String) = denotesTestSet(x) || denotesTestPath(x)
NestUI._verbose = parsed isSet "--verbose"
fileManager.showDiff = true
@@ -126,7 +119,7 @@ class ConsoleRunner extends DirectRunner {
val grepOption = parsed get "--grep"
val grepPaths = grepOption.toList flatMap { expr =>
val subjectDirs = testSetKinds map (srcDir / _ toDirectory)
- val testPaths = subjectDirs flatMap (_.files filter (x => x.hasExtension("scala") || x.isDirectory))
+ val testPaths = subjectDirs flatMap (_.files filter stdFilter)
val paths = testPaths filter (p => pathMatchesExpr(p, expr))
if (paths.isEmpty)
@@ -168,7 +161,7 @@ class ConsoleRunner extends DirectRunner {
"Java options are: " + vmOpts,
"Source directory is: " + srcDir,
""
- ) foreach (x => NestUI outline (x + "\n"))
+ ) foreach (x => NestUI verbose (x + "\n"))
NestUI.verbose("available processors: " + Runtime.getRuntime().availableProcessors())
diff --git a/src/partest/scala/tools/partest/nest/DirectRunner.scala b/src/partest/scala/tools/partest/nest/DirectRunner.scala
index 96b0c5bea6..d4b1c8dcb1 100644
--- a/src/partest/scala/tools/partest/nest/DirectRunner.scala
+++ b/src/partest/scala/tools/partest/nest/DirectRunner.scala
@@ -26,6 +26,20 @@ trait DirectRunner {
import PartestDefaults.numActors
+ def denotesTestFile(arg: String) = Path(arg).hasExtension("scala", "res")
+ def denotesTestDir(arg: String) = Path(arg).ifDirectory(_.files.nonEmpty) exists (x => x)
+ def denotesTestPath(arg: String) = denotesTestDir(arg) || denotesTestFile(arg)
+
+ /** No duplicate, no empty directories, don't mess with this unless
+ * you like partest hangs.
+ */
+ def onlyValidTestPaths[T](args: List[T]): List[T] = {
+ args.distinct filter (arg => denotesTestPath("" + arg) || {
+ NestUI.warning("Discarding invalid test path '%s'\n" format arg)
+ false
+ })
+ }
+
def setProperties() {
if (isPartestDebug)
scala.actors.Debug.level = 3
@@ -37,8 +51,7 @@ trait DirectRunner {
}
def runTestsForFiles(_kindFiles: List[File], kind: String): immutable.Map[String, Int] = {
- /** NO DUPLICATES, or partest will blow the count and hang forever. */
- val kindFiles = _kindFiles.distinct
+ val kindFiles = onlyValidTestPaths(_kindFiles)
val groupSize = (kindFiles.length / numActors) + 1
val consFM = new ConsoleFileManager
diff --git a/src/partest/scala/tools/partest/nest/TestFile.scala b/src/partest/scala/tools/partest/nest/TestFile.scala
index 9bfb4a992a..a00b94eba9 100644
--- a/src/partest/scala/tools/partest/nest/TestFile.scala
+++ b/src/partest/scala/tools/partest/nest/TestFile.scala
@@ -24,13 +24,18 @@ abstract class TestFile(kind: String) {
def setOutDirTo = objectDir
- def defineSettings(settings: Settings, setOutDir: Boolean) = {
+ def defineSettings(settings: Settings, setOutDir: Boolean): Boolean = {
settings.classpath append dir.path
if (setOutDir)
settings.outdir.value = setOutDirTo.path
- flags foreach (settings processArgumentString _)
+ // have to catch bad flags somewhere
+ flags foreach { f =>
+ if (!settings.processArgumentString(f)._1)
+ return false
+ }
settings.classpath append fileManager.CLASSPATH
+ true
}
override def toString(): String = "%s %s".format(kind, file)
@@ -49,10 +54,12 @@ case class ScalapTestFile(file: JFile, fileManager: FileManager) extends TestFil
override def setOutDirTo = file.parent
}
case class SpecializedTestFile(file: JFile, fileManager: FileManager) extends TestFile("specialized") {
- override def defineSettings(settings: Settings, setOutDir: Boolean) = {
- super.defineSettings(settings, setOutDir)
- // add the instrumented library version to classpath
- settings.classpath.value = ClassPath.join(PathSettings.srcSpecLib.toString, settings.classpath.value)
+ override def defineSettings(settings: Settings, setOutDir: Boolean): Boolean = {
+ super.defineSettings(settings, setOutDir) && {
+ // add the instrumented library version to classpath
+ settings.classpath prepend PathSettings.srcSpecLib.toString
+ true
+ }
}
}
case class PresentationTestFile(file: JFile, fileManager: FileManager) extends TestFile("presentation")