diff options
author | Paul Phillips <paulp@improving.org> | 2011-03-21 22:25:40 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-03-21 22:25:40 +0000 |
commit | 455ee619fbfde17c8a9208d3e2ebf7d867cbd560 (patch) | |
tree | 686ccedbf5004eeb1507bbedc3b8c0d4b8d273fd /src/compiler/scala/tools/nsc/GenericRunnerCommand.scala | |
parent | 7946facede9482d8a363b6474b163c11ab3a662c (diff) | |
download | scala-455ee619fbfde17c8a9208d3e2ebf7d867cbd560.tar.gz scala-455ee619fbfde17c8a9208d3e2ebf7d867cbd560.tar.bz2 scala-455ee619fbfde17c8a9208d3e2ebf7d867cbd560.zip |
[I'm laptop only so there's some chance this wi...
[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.
Diffstat (limited to 'src/compiler/scala/tools/nsc/GenericRunnerCommand.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/GenericRunnerCommand.scala | 78 |
1 files changed, 46 insertions, 32 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) +} |