@@ -3,7 +3,7 @@ package dotty.tools
3
3
4
4
import scala .annotation .tailrec
5
5
import scala .io .Source
6
- import scala .util .Try
6
+ import scala .util .{ Try , Success , Failure }
7
7
import java .net .URLClassLoader
8
8
import sys .process ._
9
9
import java .io .File
@@ -21,6 +21,7 @@ enum ExecuteMode:
21
21
case Script
22
22
case Repl
23
23
case Run
24
+ case PossibleRun
24
25
25
26
case class Settings (
26
27
verbose : Boolean = false ,
@@ -30,19 +31,22 @@ case class Settings(
30
31
javaArgs : List [String ] = List .empty,
31
32
scalaArgs : List [String ] = List .empty,
32
33
residualArgs : List [String ] = List .empty,
34
+ possibleEntryPaths : List [String ] = List .empty,
33
35
scriptArgs : List [String ] = List .empty,
34
36
targetScript : String = " " ,
37
+ targetFqName : String = " " ,
35
38
save : Boolean = false ,
39
+ modeShouldBePossibleRun : Boolean = false ,
36
40
modeShouldBeRun : Boolean = false ,
37
41
compiler : Boolean = false ,
38
42
) {
39
- def withExecuteMode (em : ExecuteMode ): Settings = this .executeMode match
40
- case ExecuteMode .Guess =>
41
- this .copy(executeMode = em)
42
- case _ =>
43
- println(s " execute_mode==[ $executeMode], attempted overwrite by [ $em] " )
44
- this .copy(exitCode = 1 )
45
- end withExecuteMode
43
+ def withExecuteMode (em : ExecuteMode ): Settings = // this.executeMode match
44
+ // case ExecuteMode.Guess =>
45
+ this .copy(executeMode = em)
46
+ // case _ =>
47
+ // println(s"execute_mode==[$executeMode], attempted overwrite by [$em]")
48
+ // this.copy(exitCode = 1)
49
+ // end withExecuteMode
46
50
47
51
def withScalaArgs (args : String * ): Settings =
48
52
this .copy(scalaArgs = scalaArgs.appendedAll(args.toList))
@@ -53,6 +57,9 @@ case class Settings(
53
57
def withResidualArgs (args : String * ): Settings =
54
58
this .copy(residualArgs = residualArgs.appendedAll(args.toList))
55
59
60
+ def withPossibleEntryPaths (args : String * ): Settings =
61
+ this .copy(possibleEntryPaths = possibleEntryPaths.appendedAll(args.toList))
62
+
56
63
def withScriptArgs (args : String * ): Settings =
57
64
this .copy(scriptArgs = scriptArgs.appendedAll(args.toList))
58
65
@@ -64,9 +71,15 @@ case class Settings(
64
71
this .copy(exitCode = 2 )
65
72
end withTargetScript
66
73
74
+ def withTargetFqName (targetFqName : String ): Settings =
75
+ this .copy(targetFqName = targetFqName)
76
+
67
77
def withSave : Settings =
68
78
this .copy(save = true )
69
79
80
+ def withModeShouldBePossibleRun : Settings =
81
+ this .copy(modeShouldBePossibleRun = true )
82
+
70
83
def withModeShouldBeRun : Settings =
71
84
this .copy(modeShouldBeRun = true )
72
85
@@ -85,8 +98,8 @@ object MainGenericRunner {
85
98
def process (args : List [String ], settings : Settings ): Settings = args match
86
99
case Nil =>
87
100
settings
88
- case " -run" :: tail =>
89
- process(tail, settings.withExecuteMode(ExecuteMode .Run ))
101
+ case " -run" :: fqName :: tail =>
102
+ process(tail, settings.withExecuteMode(ExecuteMode .Run ).withTargetFqName(fqName) )
90
103
case (" -cp" | " -classpath" | " --class-path" ) :: cp :: tail =>
91
104
process(tail, settings.copy(classPath = settings.classPath.appended(cp)))
92
105
case (" -version" | " --version" ) :: _ =>
@@ -120,7 +133,7 @@ object MainGenericRunner {
120
133
.withTargetScript(arg)
121
134
.withScriptArgs(tail* )
122
135
else
123
- val newSettings = if arg.startsWith(" -" ) then settings else settings.withModeShouldBeRun
136
+ val newSettings = if arg.startsWith(" -" ) then settings else settings.withPossibleEntryPaths(arg).withModeShouldBePossibleRun
124
137
process(tail, newSettings.withResidualArgs(arg))
125
138
126
139
def main (args : Array [String ]): Unit =
@@ -129,12 +142,24 @@ object MainGenericRunner {
129
142
val settings = process(allArgs.toList, Settings ())
130
143
if settings.exitCode != 0 then System .exit(settings.exitCode)
131
144
132
- def run (mode : ExecuteMode ): Unit = mode match
145
+ def run (settings : Settings ): Unit = settings.executeMode match
133
146
case ExecuteMode .Repl =>
134
147
val properArgs =
135
148
List (" -classpath" , settings.classPath.mkString(classpathSeparator)).filter(Function .const(settings.classPath.nonEmpty))
136
149
++ settings.residualArgs
137
150
repl.Main .main(properArgs.toArray)
151
+
152
+ case ExecuteMode .PossibleRun =>
153
+ val targetFqName = settings.possibleEntryPaths.find { entryPath =>
154
+ Try (Thread .currentThread().getContextClassLoader.loadClass(entryPath)) match
155
+ case Failure (_) => false
156
+ case Success (_) => true
157
+ }
158
+ targetFqName match
159
+ case Some (fqName) =>
160
+ run(settings.withTargetFqName(fqName).withResidualArgs(settings.residualArgs.filter { _ != fqName }* ).withExecuteMode(ExecuteMode .Run ))
161
+ case None =>
162
+ run(settings.withExecuteMode(ExecuteMode .Repl ))
138
163
case ExecuteMode .Run =>
139
164
val scalaClasspath = ClasspathFromClassloader (Thread .currentThread().getContextClassLoader).split(classpathSeparator)
140
165
@@ -146,7 +171,7 @@ object MainGenericRunner {
146
171
cp
147
172
val newClasspath = (settings.classPath ++ removeCompiler(scalaClasspath) :+ " ." ).map(File (_).toURI.toURL)
148
173
149
- val res = ObjectRunner .runAndCatch(newClasspath, settings.residualArgs.head , settings.residualArgs.drop( 1 ) ).flatMap {
174
+ val res = ObjectRunner .runAndCatch(newClasspath, settings.targetFqName , settings.residualArgs).flatMap {
150
175
case ex : ClassNotFoundException if ex.getMessage == settings.residualArgs.head =>
151
176
val file = settings.residualArgs.head
152
177
Jar (file).mainClass match
@@ -167,12 +192,14 @@ object MainGenericRunner {
167
192
++ settings.scriptArgs
168
193
scripting.Main .main(properArgs.toArray)
169
194
case ExecuteMode .Guess =>
170
- if settings.modeShouldBeRun then
171
- run(ExecuteMode .Run )
195
+ if settings.modeShouldBePossibleRun then
196
+ run(settings.withExecuteMode(ExecuteMode .PossibleRun ))
197
+ else if settings.modeShouldBeRun then
198
+ run(settings.withExecuteMode(ExecuteMode .Run ))
172
199
else
173
- run(ExecuteMode .Repl )
200
+ run(settings.withExecuteMode( ExecuteMode .Repl ) )
174
201
175
- run(settings.executeMode )
202
+ run(settings)
176
203
177
204
178
205
def errorFn (str : String , e : Option [Throwable ] = None , isFailure : Boolean = true ): Boolean = {
0 commit comments