From 455ee619fbfde17c8a9208d3e2ebf7d867cbd560 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Mon, 21 Mar 2011 22:25:40 +0000 Subject: [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. --- .../scala/tools/nsc/GenericRunnerCommand.scala | 78 +++++++++++++--------- 1 file changed, 46 insertions(+), 32 deletions(-) (limited to 'src/compiler/scala/tools/nsc/GenericRunnerCommand.scala') 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@ [ ] - or @cmd@ [-jar ] +Usage: @cmd@ [ ] 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 -J is stripped and 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 (default: guess) - -i preload before starting the repl - -e execute 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 (default: guess) + -i preload before starting the repl + -e execute 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("") + val waysToRun = List(AsJar, AsObject, AsScript, AsRepl) +} -- cgit v1.2.3