1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
/* NSC -- new Scala compiler
* Copyright 2006-2010 LAMP/EPFL
* @author Lex Spoon
*/
// $Id$
package scala.tools.nsc
import java.io.IOException
import java.lang.{ClassNotFoundException, NoSuchMethodException}
import java.lang.reflect.InvocationTargetException
import java.net.{ URL, MalformedURLException }
import scala.tools.util.PathResolver
import io.{ File }
import util.{ ClassPath, ScalaClassLoader }
import File.pathSeparator
import Properties.{ versionString, copyrightString }
/** An object that runs Scala code. It has three possible
* sources for the code to run: pre-compiled code, a script file,
* or interactive entry.
*/
object MainGenericRunner {
def main(args: Array[String]) {
def errorFn(str: String) = Console println str
def exitSuccess: Nothing = exit(0)
def exitFailure(msg: Any = null): Nothing = {
if (msg != null) errorFn(msg.toString)
exit(1)
}
def exitCond(b: Boolean): Nothing = if (b) exitSuccess else exitFailure(null)
val command = new GenericRunnerCommand(args.toList, errorFn)
import command.settings
def sampleCompiler = new Global(settings) // def so its not created unless needed
def processSettings() {
// append the jars in ${scala.home}/lib to the classpath, as well as "." if none was given.
val needDot = settings.classpath.value == ""
settings appendToClasspath PathResolver.genericRunnerClassPath
if (needDot)
settings appendToClasspath "."
// XXX is this accomplishing anything?
settings.defines.applyToCurrentJVM
}
if (!command.ok)
return errorFn("%s\n%s".format(command.usageMsg, sampleCompiler.pluginOptionsHelp))
processSettings()
if (settings.version.value)
return errorFn("Scala code runner %s -- %s".format(versionString, copyrightString))
if (command.shouldStopWithInfo)
return errorFn(command getInfoMessage sampleCompiler)
val classpath: List[URL] = PathResolver urlsFromSettings settings distinct
def dashe = settings.execute.value
def dashi = settings.loadfiles.value
def slurp = dashi map (file => File(file).slurp()) mkString "\n"
/** Was code given in a -e argument? */
if (!settings.execute.isDefault) {
/** 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
val code =
if (settings.loadfiles.isDefault) dashe
else slurp + "\n" + dashe
exitCond(ScriptRunner.runCommand(settings, code, fullArgs))
}
else command.thingToRun match {
case None =>
// Questionably, we start the interpreter when there are no arguments.
new InterpreterLoop main settings
case Some(thingToRun) =>
val isObjectName =
settings.howtorun.value match {
case "object" => true
case "script" => false
case "guess" => ScalaClassLoader.classExists(classpath, thingToRun)
}
if (isObjectName)
try ObjectRunner.run(classpath, thingToRun, command.arguments)
catch {
case e @ (_: ClassNotFoundException | _: NoSuchMethodException) => exitFailure(e)
case e: InvocationTargetException =>
e.getCause.printStackTrace
exitFailure()
}
else
try exitCond(ScriptRunner.runScript(settings, thingToRun, command.arguments))
catch {
case e: IOException => exitFailure(e.getMessage)
case e: SecurityException => exitFailure(e)
}
}
}
}
|