summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ScriptRunner.scala
diff options
context:
space:
mode:
authorAntoine Gourlay <antoine@gourlay.fr>2014-08-26 09:43:49 +0200
committerAntoine Gourlay <antoine@gourlay.fr>2014-08-26 13:26:59 +0200
commit9519eb094130ab121fa10767916e812b76bdc947 (patch)
tree98286a0cf6f92abdec8256f37ed68c977ffadf3c /src/compiler/scala/tools/nsc/ScriptRunner.scala
parent3555e0ec840a7ab843794e53a17142bd6ee49d87 (diff)
downloadscala-9519eb094130ab121fa10767916e812b76bdc947.tar.gz
scala-9519eb094130ab121fa10767916e812b76bdc947.tar.bz2
scala-9519eb094130ab121fa10767916e812b76bdc947.zip
SI-5254 running an empty scala script should succeed
The script runner made the assumption that "compilation succeeded" implies "there is a Main class to run", but this can be wrong if the script is empty (or only contains imports/comments). The ScriptRunner now uses the ClassPath utility to check if there really is a main class. If not, it doesn't try to run it and returns peacefully. This also makes `scala -e ''` succeed.
Diffstat (limited to 'src/compiler/scala/tools/nsc/ScriptRunner.scala')
-rw-r--r--src/compiler/scala/tools/nsc/ScriptRunner.scala34
1 files changed, 23 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala
index c2d62db558..7d5c6f6fff 100644
--- a/src/compiler/scala/tools/nsc/ScriptRunner.scala
+++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala
@@ -6,7 +6,7 @@
package scala
package tools.nsc
-import io.{ Directory, File, Path }
+import io.{ AbstractFile, Directory, File, Path }
import java.io.IOException
import scala.tools.nsc.reporters.{Reporter,ConsoleReporter}
import util.Exceptional.unwrap
@@ -111,6 +111,12 @@ class ScriptRunner extends HasCompileSocket {
else None
}
+ def hasClassToRun(d: Directory): Boolean = {
+ import util.ClassPath.{ DefaultJavaContext => ctx }
+ val cp = ctx.newClassPath(AbstractFile.getDirectory(d))
+ cp.findClass(mainClass).isDefined
+ }
+
/* The script runner calls sys.exit to communicate a return value, but this must
* not take place until there are no non-daemon threads running. Tickets #1955, #2006.
*/
@@ -124,15 +130,21 @@ class ScriptRunner extends HasCompileSocket {
compile match {
case Some(compiledPath) =>
- try io.Jar.create(jarFile, compiledPath, mainClass)
- catch { case _: Exception => jarFile.delete() }
-
- if (jarOK) {
- compiledPath.deleteRecursively()
- handler(jarFile.toAbsolute.path)
+ if (!hasClassToRun(compiledPath)) {
+ // it compiled ok, but there is nothing to run;
+ // running an empty script should succeed
+ true
+ } else {
+ try io.Jar.create(jarFile, compiledPath, mainClass)
+ catch { case _: Exception => jarFile.delete() }
+
+ if (jarOK) {
+ compiledPath.deleteRecursively()
+ handler(jarFile.toAbsolute.path)
+ }
+ // jar failed; run directly from the class files
+ else handler(compiledPath.path)
}
- // jar failed; run directly from the class files
- else handler(compiledPath.path)
case _ => false
}
}
@@ -140,8 +152,8 @@ class ScriptRunner extends HasCompileSocket {
if (jarOK) handler(jarFile.toAbsolute.path) // pre-compiled jar is current
else recompile() // jar old - recompile the script.
}
- // don't use a cache jar at all--just use the class files
- else compile exists (cp => handler(cp.path))
+ // don't use a cache jar at all--just use the class files, if they exist
+ else compile exists (cp => !hasClassToRun(cp) || handler(cp.path))
}
}