@@ -3,7 +3,7 @@ package dotty.tools
33
44import scala .annotation .tailrec
55import scala .io .Source
6- import scala .util .Try
6+ import scala .util .{ Try , Success , Failure }
77import java .net .URLClassLoader
88import sys .process ._
99import java .io .File
@@ -21,6 +21,7 @@ enum ExecuteMode:
2121 case Script
2222 case Repl
2323 case Run
24+ case PossibleRun
2425
2526case class Settings (
2627 verbose : Boolean = false ,
@@ -30,19 +31,22 @@ case class Settings(
3031 javaArgs : List [String ] = List .empty,
3132 scalaArgs : List [String ] = List .empty,
3233 residualArgs : List [String ] = List .empty,
34+ possibleEntryPaths : List [String ] = List .empty,
3335 scriptArgs : List [String ] = List .empty,
3436 targetScript : String = " " ,
37+ targetFqName : String = " " ,
3538 save : Boolean = false ,
39+ modeShouldBePossibleRun : Boolean = false ,
3640 modeShouldBeRun : Boolean = false ,
3741 compiler : Boolean = false ,
3842) {
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
4650
4751 def withScalaArgs (args : String * ): Settings =
4852 this .copy(scalaArgs = scalaArgs.appendedAll(args.toList))
@@ -53,6 +57,9 @@ case class Settings(
5357 def withResidualArgs (args : String * ): Settings =
5458 this .copy(residualArgs = residualArgs.appendedAll(args.toList))
5559
60+ def withPossibleEntryPaths (args : String * ): Settings =
61+ this .copy(possibleEntryPaths = possibleEntryPaths.appendedAll(args.toList))
62+
5663 def withScriptArgs (args : String * ): Settings =
5764 this .copy(scriptArgs = scriptArgs.appendedAll(args.toList))
5865
@@ -64,9 +71,15 @@ case class Settings(
6471 this .copy(exitCode = 2 )
6572 end withTargetScript
6673
74+ def withTargetFqName (targetFqName : String ): Settings =
75+ this .copy(targetFqName = targetFqName)
76+
6777 def withSave : Settings =
6878 this .copy(save = true )
6979
80+ def withModeShouldBePossibleRun : Settings =
81+ this .copy(modeShouldBePossibleRun = true )
82+
7083 def withModeShouldBeRun : Settings =
7184 this .copy(modeShouldBeRun = true )
7285
@@ -85,8 +98,8 @@ object MainGenericRunner {
8598 def process (args : List [String ], settings : Settings ): Settings = args match
8699 case Nil =>
87100 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) )
90103 case (" -cp" | " -classpath" | " --class-path" ) :: cp :: tail =>
91104 process(tail, settings.copy(classPath = settings.classPath.appended(cp)))
92105 case (" -version" | " --version" ) :: _ =>
@@ -120,7 +133,7 @@ object MainGenericRunner {
120133 .withTargetScript(arg)
121134 .withScriptArgs(tail* )
122135 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
124137 process(tail, newSettings.withResidualArgs(arg))
125138
126139 def main (args : Array [String ]): Unit =
@@ -129,12 +142,24 @@ object MainGenericRunner {
129142 val settings = process(allArgs.toList, Settings ())
130143 if settings.exitCode != 0 then System .exit(settings.exitCode)
131144
132- def run (mode : ExecuteMode ): Unit = mode match
145+ def run (settings : Settings ): Unit = settings.executeMode match
133146 case ExecuteMode .Repl =>
134147 val properArgs =
135148 List (" -classpath" , settings.classPath.mkString(classpathSeparator)).filter(Function .const(settings.classPath.nonEmpty))
136149 ++ settings.residualArgs
137150 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 ))
138163 case ExecuteMode .Run =>
139164 val scalaClasspath = ClasspathFromClassloader (Thread .currentThread().getContextClassLoader).split(classpathSeparator)
140165
@@ -146,7 +171,7 @@ object MainGenericRunner {
146171 cp
147172 val newClasspath = (settings.classPath ++ removeCompiler(scalaClasspath) :+ " ." ).map(File (_).toURI.toURL)
148173
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 {
150175 case ex : ClassNotFoundException if ex.getMessage == settings.residualArgs.head =>
151176 val file = settings.residualArgs.head
152177 Jar (file).mainClass match
@@ -167,12 +192,14 @@ object MainGenericRunner {
167192 ++ settings.scriptArgs
168193 scripting.Main .main(properArgs.toArray)
169194 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 ))
172199 else
173- run(ExecuteMode .Repl )
200+ run(settings.withExecuteMode( ExecuteMode .Repl ) )
174201
175- run(settings.executeMode )
202+ run(settings)
176203
177204
178205 def errorFn (str : String , e : Option [Throwable ] = None , isFailure : Boolean = true ): Boolean = {
0 commit comments