@@ -15,7 +15,7 @@ import dotty.tools.io.Jar
15
15
import dotty .tools .runner .ScalaClassLoader
16
16
import java .nio .file .Paths
17
17
import dotty .tools .dotc .config .CommandLineParser
18
- import dotty .tools .scripting .StringDriver
18
+ import dotty .tools .scripting .{ StringDriver , StringDriverException , ScriptingException }
19
19
20
20
enum ExecuteMode :
21
21
case Guess
@@ -118,40 +118,40 @@ object MainGenericRunner {
118
118
@ sharable val scalaOption = raw """ @.* """ .r
119
119
@ sharable val colorOption = raw """ -color:.* """ .r
120
120
@ tailrec
121
- def process (args : List [String ], settings : Settings ): Settings = args match
121
+ def processArgs (args : List [String ], settings : Settings ): Settings = args match
122
122
case Nil =>
123
123
settings
124
124
case " -run" :: fqName :: tail =>
125
- process (tail, settings.withExecuteMode(ExecuteMode .Run ).withTargetToRun(fqName))
125
+ processArgs (tail, settings.withExecuteMode(ExecuteMode .Run ).withTargetToRun(fqName))
126
126
case (" -cp" | " -classpath" | " --class-path" ) :: cp :: tail =>
127
127
val (tailargs, newEntries) = processClasspath(cp, tail)
128
- process (tailargs, settings.copy(classPath = settings.classPath ++ newEntries.filter(_.nonEmpty)))
128
+ processArgs (tailargs, settings.copy(classPath = settings.classPath ++ newEntries.filter(_.nonEmpty)))
129
129
case (" -version" | " --version" ) :: _ =>
130
130
settings.copy(
131
131
executeMode = ExecuteMode .Repl ,
132
132
residualArgs = List (" -version" )
133
133
)
134
134
case (" -v" | " -verbose" | " --verbose" ) :: tail =>
135
- process (
135
+ processArgs (
136
136
tail,
137
137
settings.copy(
138
138
verbose = true ,
139
139
residualArgs = settings.residualArgs :+ " -verbose"
140
140
)
141
141
)
142
142
case " -save" :: tail =>
143
- process (tail, settings.withSave)
143
+ processArgs (tail, settings.withSave)
144
144
case " -nosave" :: tail =>
145
- process (tail, settings.noSave)
145
+ processArgs (tail, settings.noSave)
146
146
case " -with-compiler" :: tail =>
147
- process (tail, settings.withCompiler)
147
+ processArgs (tail, settings.withCompiler)
148
148
case (o @ javaOption(striped)) :: tail =>
149
- process (tail, settings.withJavaArgs(striped).withScalaArgs(o))
149
+ processArgs (tail, settings.withJavaArgs(striped).withScalaArgs(o))
150
150
case (o @ scalaOption(_* )) :: tail =>
151
151
val remainingArgs = (CommandLineParser .expandArg(o) ++ tail).toList
152
- process (remainingArgs, settings)
152
+ processArgs (remainingArgs, settings)
153
153
case (o @ colorOption(_* )) :: tail =>
154
- process (tail, settings.withScalaArgs(o))
154
+ processArgs (tail, settings.withScalaArgs(o))
155
155
case " -e" :: expression :: tail =>
156
156
val mainSource = s " @main def main(args: String *): Unit = \n ${expression}"
157
157
settings
@@ -169,13 +169,13 @@ object MainGenericRunner {
169
169
.withScriptArgs(tail* )
170
170
else
171
171
val newSettings = if arg.startsWith(" -" ) then settings else settings.withPossibleEntryPaths(arg).withModeShouldBePossibleRun
172
- process (tail, newSettings.withResidualArgs(arg))
173
- end process
172
+ processArgs (tail, newSettings.withResidualArgs(arg))
173
+ end processArgs
174
174
175
- def main (args : Array [String ]): Unit =
175
+ def process (args : Array [String ]): Boolean =
176
176
val scalaOpts = envOrNone(" SCALA_OPTS" ).toArray.flatMap(_.split(" " )).filter(_.nonEmpty)
177
177
val allArgs = scalaOpts ++ args
178
- val settings = process (allArgs.toList, Settings ())
178
+ val settings = processArgs (allArgs.toList, Settings ())
179
179
if settings.exitCode != 0 then System .exit(settings.exitCode)
180
180
181
181
def removeCompiler (cp : Array [String ]) =
@@ -185,12 +185,13 @@ object MainGenericRunner {
185
185
else
186
186
cp
187
187
188
- def run (settings : Settings ): Unit = settings.executeMode match
188
+ def run (settings : Settings ): Option [ Throwable ] = settings.executeMode match
189
189
case ExecuteMode .Repl =>
190
190
val properArgs =
191
191
List (" -classpath" , settings.classPath.mkString(classpathSeparator)).filter(Function .const(settings.classPath.nonEmpty))
192
192
++ settings.residualArgs
193
193
repl.Main .main(properArgs.toArray)
194
+ None
194
195
195
196
case ExecuteMode .PossibleRun =>
196
197
val newClasspath = (settings.classPath :+ " ." ).flatMap(_.split(classpathSeparator).filter(_.nonEmpty)).map(File (_).toURI.toURL)
@@ -207,10 +208,11 @@ object MainGenericRunner {
207
208
case None =>
208
209
settings.withExecuteMode(ExecuteMode .Repl )
209
210
run(newSettings)
211
+
210
212
case ExecuteMode .Run =>
211
213
val scalaClasspath = ClasspathFromClassloader (Thread .currentThread().getContextClassLoader).split(classpathSeparator)
212
214
val newClasspath = (settings.classPath.flatMap(_.split(classpathSeparator).filter(_.nonEmpty)) ++ removeCompiler(scalaClasspath) :+ " ." ).map(File (_).toURI.toURL)
213
- val res = ObjectRunner .runAndCatch(newClasspath, settings.targetToRun, settings.residualArgs).flatMap {
215
+ ObjectRunner .runAndCatch(newClasspath, settings.targetToRun, settings.residualArgs).flatMap {
214
216
case ex : ClassNotFoundException if ex.getMessage == settings.targetToRun =>
215
217
val file = settings.targetToRun
216
218
Jar (file).mainClass match
@@ -220,7 +222,7 @@ object MainGenericRunner {
220
222
Some (IllegalArgumentException (s " No main class defined in manifest in jar: $file" ))
221
223
case ex => Some (ex)
222
224
}
223
- errorFn( " " , res)
225
+
224
226
case ExecuteMode .Script =>
225
227
val targetScript = Paths .get(settings.targetScript).toFile
226
228
val targetJar = settings.targetScript.replaceAll(" [.][^\\ /]*$" , " " )+ " .jar"
@@ -232,11 +234,10 @@ object MainGenericRunner {
232
234
sys.props(" script.path" ) = targetScript.toPath.toAbsolutePath.normalize.toString
233
235
val scalaClasspath = ClasspathFromClassloader (Thread .currentThread().getContextClassLoader).split(classpathSeparator)
234
236
val newClasspath = (settings.classPath.flatMap(_.split(classpathSeparator).filter(_.nonEmpty)) ++ removeCompiler(scalaClasspath) :+ " ." ).map(File (_).toURI.toURL)
235
- val res = if mainClass.nonEmpty then
237
+ if mainClass.nonEmpty then
236
238
ObjectRunner .runAndCatch(newClasspath :+ File (targetJar).toURI.toURL, mainClass, settings.scriptArgs)
237
239
else
238
240
Some (IllegalArgumentException (s " No main class defined in manifest in jar: $precompiledJar" ))
239
- errorFn(" " , res)
240
241
241
242
else
242
243
val properArgs =
@@ -246,7 +247,8 @@ object MainGenericRunner {
246
247
++ settings.scalaArgs
247
248
++ List (" -script" , settings.targetScript)
248
249
++ settings.scriptArgs
249
- scripting.Main .main(properArgs.toArray)
250
+ scripting.Main .process(properArgs.toArray)
251
+
250
252
case ExecuteMode .Expression =>
251
253
val cp = settings.classPath match {
252
254
case Nil => " "
@@ -265,12 +267,17 @@ object MainGenericRunner {
265
267
else
266
268
run(settings.withExecuteMode(ExecuteMode .Repl ))
267
269
268
- run(settings)
270
+ run(settings) match
271
+ case Some (ex : (StringDriverException | ScriptingException )) => errorFn(ex.getMessage)
272
+ case e @ Some (ex) => errorFn(" " , e)
273
+ case _ => true
269
274
270
-
271
- def errorFn (str : String , e : Option [Throwable ] = None , isFailure : Boolean = true ): Boolean = {
275
+ def errorFn (str : String , e : Option [Throwable ] = None ): Boolean =
272
276
if (str.nonEmpty) Console .err.println(str)
273
277
e.foreach(_.printStackTrace())
274
- ! isFailure
275
- }
278
+ false
279
+
280
+ def main (args : Array [String ]): Unit =
281
+ if (! process(args)) System .exit(1 )
282
+
276
283
}
0 commit comments