Skip to content

Commit e5a54cd

Browse files
committed
Fix problem with badly initialized context
1 parent 25aa624 commit e5a54cd

File tree

16 files changed

+90
-71
lines changed

16 files changed

+90
-71
lines changed

compiler/src/dotty/tools/dotc/Driver.scala

+17-9
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,17 @@ class Driver {
6666

6767
protected def command: CompilerCommand = ScalacCommand
6868

69-
def setup(args: Array[String], rootCtx: Context): (Option[List[AbstractFile]], Context) = {
69+
/** Setup context with initialized settings from CLI arguments, then check if there are any settings that
70+
* would change the default behaviour of the compiler.
71+
*
72+
* @return An Option of tuple of List and Context.
73+
* If there is no setting like `-help` preventing us from continuing compilation, this method returns
74+
* Some of files to compile and updated Context.
75+
* If compilation should be interrupted, this method returns None.
76+
*/
77+
def setup(args: Array[String], rootCtx: Context): Option[(List[AbstractFile], Context)] = {
7078
val ictx = rootCtx.fresh
71-
val settings = config.ScalaSettings()
72-
val summary = command.distill(args, settings, settings.defaultState)
79+
val summary = command.distill(args, ictx.settings)(ictx.settingsState)
7380
ictx.setSettings(summary.sstate)
7481
MacroClassLoader.init(ictx)
7582
Positioned.init(using ictx)
@@ -78,9 +85,9 @@ class Driver {
7885
if !ctx.settings.YdropComments.value || ctx.mode.is(Mode.ReadComments) then
7986
ictx.setProperty(ContextDoc, new ContextDocstrings)
8087
val fileNamesOrNone = command.checkUsage(summary, sourcesRequired)(using ctx.settings)(using ctx.settingsState)
81-
fileNamesOrNone.fold((None, ictx)) { fileNames =>
88+
fileNamesOrNone.map { fileNames =>
8289
val files = fileNames.map(ctx.getFile)
83-
(Some(files), fromTastySetup(files))
90+
(files, fromTastySetup(files))
8491
}
8592
}
8693
}
@@ -187,10 +194,11 @@ class Driver {
187194
* if compilation succeeded.
188195
*/
189196
def process(args: Array[String], rootCtx: Context): Reporter = {
190-
val (files, compileCtx) = setup(args, rootCtx)
191-
files.fold(compileCtx.reporter) {
192-
doCompile(newCompiler(using compileCtx), _)(using compileCtx)
193-
}
197+
setup(args, rootCtx) match
198+
case Some((files, compileCtx)) =>
199+
doCompile(newCompiler(using compileCtx), files)(using compileCtx)
200+
case None =>
201+
rootCtx.reporter
194202
}
195203

196204
def main(args: Array[String]): Unit = {

compiler/src/dotty/tools/dotc/Resident.scala

+15-15
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,21 @@ class Resident extends Driver {
4040

4141
final override def process(args: Array[String], rootCtx: Context): Reporter = {
4242
@tailrec def loop(args: Array[String], prevCtx: Context): Reporter = {
43-
var (possibleFiles, ctx) = setup(args, prevCtx)
44-
if possibleFiles.isDefined then
45-
inContext(ctx) {
46-
doCompile(residentCompiler, possibleFiles.get) // using more complex constructs like fold or map instead of get will make @tailrec complain
47-
}
48-
var nextCtx = ctx
49-
var line = getLine()
50-
while (line == reset) {
51-
nextCtx = rootCtx
52-
line = getLine()
53-
}
54-
if (line.startsWith(quit)) ctx.reporter
55-
else loop(line split "\\s+", nextCtx)
56-
else
57-
ctx.reporter
43+
setup(args, prevCtx) match
44+
case Some((files, ctx)) =>
45+
inContext(ctx) {
46+
doCompile(residentCompiler, files)
47+
}
48+
var nextCtx = ctx
49+
var line = getLine()
50+
while (line == reset) {
51+
nextCtx = rootCtx
52+
line = getLine()
53+
}
54+
if (line.startsWith(quit)) ctx.reporter
55+
else loop(line split "\\s+", nextCtx)
56+
case None =>
57+
prevCtx.reporter
5858
}
5959
loop(args, rootCtx)
6060
}

compiler/src/dotty/tools/dotc/config/CliCommand.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ trait CliCommand:
4040
"""
4141

4242
/** Distill arguments into summary detailing settings, errors and files to main */
43-
def distill(args: Array[String], sg: Settings.SettingGroup, ss: SettingsState): ArgsSummary =
43+
def distill(args: Array[String], sg: Settings.SettingGroup)(ss: SettingsState = sg.defaultState): ArgsSummary =
4444
/**
4545
* Expands all arguments starting with @ to the contents of the
4646
* file named like each argument.
@@ -62,7 +62,7 @@ trait CliCommand:
6262
case x => List(x)
6363
}
6464

65-
sg.processArguments(expandedArguments, ss, processAll = true)
65+
sg.processArguments(expandedArguments, processAll = true, settingsState = ss)
6666

6767
/** Creates a help message for a subset of options based on cond */
6868
protected def availableOptionsMsg(cond: Setting[?] => Boolean)(using settings: ConcreteSettings)(using SettingsState): String =

compiler/src/dotty/tools/dotc/config/CompilerCommand.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Properties._
1010
import scala.collection.JavaConverters._
1111

1212
abstract class CompilerCommand extends CliCommand:
13-
final type ConcreteSettings = ScalaSettings
13+
type ConcreteSettings = ScalaSettings
1414

1515
final def helpMsg(using settings: ScalaSettings)(using SettingsState, Context): String =
1616
if (settings.help.value) usageMessage

compiler/src/dotty/tools/dotc/config/PathResolver.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ object PathResolver {
144144
}
145145
else inContext(ContextBase().initialCtx) {
146146
val ArgsSummary(sstate, rest, errors, warnings) =
147-
ctx.settings.processArguments(args.toList, ctx.settingsState, true)
147+
ctx.settings.processArguments(args.toList, true, ctx.settingsState)
148148
errors.foreach(println)
149149
val pr = new PathResolver()(using ctx.fresh.setSettings(sstate))
150150
println(" COMMAND: 'scala %s'".format(args.mkString(" ")))

compiler/src/dotty/tools/dotc/config/Settings.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ object Settings {
244244
}
245245
}
246246

247-
def processArguments(arguments: List[String], settingsState: SettingsState, processAll: Boolean): ArgsSummary =
247+
def processArguments(arguments: List[String], processAll: Boolean, settingsState: SettingsState = defaultState): ArgsSummary =
248248
processArguments(ArgsSummary(settingsState, arguments, Nil, Nil), processAll, Nil)
249249

250250
def publish[T](settingf: Int => Setting[T]): Setting[T] = {

compiler/src/dotty/tools/dotc/decompiler/IDEDecompilerDriver.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ class IDEDecompilerDriver(val settings: List[String]) extends dotc.Driver {
1919
val rootCtx = initCtx.fresh.addMode(Mode.Interactive | Mode.ReadPositions | Mode.ReadComments)
2020
rootCtx.setSetting(rootCtx.settings.YretainTrees, true)
2121
rootCtx.setSetting(rootCtx.settings.fromTasty, true)
22-
val ctx = setup(settings.toArray :+ "dummy.scala", rootCtx)._2
22+
val ctx = setup(settings.toArray :+ "dummy.scala", rootCtx) match
23+
case Some((_, ctx)) => ctx
24+
case None => rootCtx
2325
ctx.initialize()(using ctx)
2426
ctx
2527
}

compiler/src/dotty/tools/dotc/decompiler/Main.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ object Main extends dotc.Driver {
1818
new TASTYDecompiler
1919
}
2020

21-
override def setup(args0: Array[String], rootCtx: Context): (Option[List[AbstractFile]], Context) = {
21+
override def setup(args0: Array[String], rootCtx: Context): Option[(List[AbstractFile], Context)] = {
2222
var args = args0.filter(a => a != "-decompile")
2323
if (!args.contains("-from-tasty")) args = "-from-tasty" +: args
2424
if (args.contains("-d")) args = "-color:never" +: args

compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
3232
val rootCtx = initCtx.fresh.addMode(Mode.ReadPositions).addMode(Mode.Interactive).addMode(Mode.ReadComments)
3333
rootCtx.setSetting(rootCtx.settings.YretainTrees, true)
3434
rootCtx.setSetting(rootCtx.settings.YcookComments, true)
35-
val ctx = setup(settings.toArray, rootCtx)._2
35+
val ctx = setup(settings.toArray, rootCtx) match
36+
case Some((_, ctx)) => ctx
37+
case None => rootCtx
3638
ctx.initialize()(using ctx)
3739
ctx
3840
}

compiler/src/dotty/tools/repl/ReplDriver.scala

+8-4
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,14 @@ class ReplDriver(settings: Array[String],
6868
private def initialCtx = {
6969
val rootCtx = initCtx.fresh.addMode(Mode.ReadPositions | Mode.Interactive | Mode.ReadComments)
7070
rootCtx.setSetting(rootCtx.settings.YcookComments, true)
71-
val (files, ictx) = setup(settings, rootCtx)
72-
shouldStart = files.isDefined
73-
ictx.base.initialize()(using ictx)
74-
ictx
71+
setup(settings, rootCtx) match
72+
case Some((files, ictx)) =>
73+
shouldStart = true
74+
ictx.base.initialize()(using ictx)
75+
ictx
76+
case None =>
77+
shouldStart = false
78+
rootCtx
7579
}
7680

7781
/** the initial, empty state of the REPL session */

compiler/src/dotty/tools/scripting/ScriptingDriver.scala

+24-24
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,30 @@ import sys.process._
1919
class ScriptingDriver(compilerArgs: Array[String], scriptFile: File, scriptArgs: Array[String]) extends Driver:
2020
def compileAndRun(pack:(Path, String, String) => Boolean = null): Unit =
2121
val outDir = Files.createTempDirectory("scala3-scripting")
22-
val (toCompileOrNone, rootCtx) = setup(compilerArgs :+ scriptFile.getAbsolutePath, initCtx.fresh)
23-
toCompileOrNone.map { toCompile =>
24-
given Context = rootCtx.fresh.setSetting(rootCtx.settings.outputDir,
25-
new PlainDirectory(Directory(outDir)))
26-
27-
if doCompile(newCompiler, toCompile).hasErrors then
28-
throw ScriptingException("Errors encountered during compilation")
29-
30-
try
31-
val (mainClass, mainMethod) = detectMainClassAndMethod(outDir, ctx.settings.classpath.value, scriptFile)
32-
val invokeMain: Boolean =
33-
Option(pack) match
34-
case Some(func) =>
35-
func(outDir, ctx.settings.classpath.value, mainClass)
36-
case None =>
37-
true
38-
end match
39-
if invokeMain then mainMethod.invoke(null, scriptArgs)
40-
catch
41-
case e: java.lang.reflect.InvocationTargetException =>
42-
throw e.getCause
43-
finally
44-
deleteFile(outDir.toFile)
45-
}
22+
setup(compilerArgs :+ scriptFile.getAbsolutePath, initCtx.fresh) match
23+
case Some((toCompile, rootCtx)) =>
24+
given Context = rootCtx.fresh.setSetting(rootCtx.settings.outputDir,
25+
new PlainDirectory(Directory(outDir)))
26+
27+
if doCompile(newCompiler, toCompile).hasErrors then
28+
throw ScriptingException("Errors encountered during compilation")
29+
30+
try
31+
val (mainClass, mainMethod) = detectMainClassAndMethod(outDir, ctx.settings.classpath.value, scriptFile)
32+
val invokeMain: Boolean =
33+
Option(pack) match
34+
case Some(func) =>
35+
func(outDir, ctx.settings.classpath.value, mainClass)
36+
case None =>
37+
true
38+
end match
39+
if invokeMain then mainMethod.invoke(null, scriptArgs)
40+
catch
41+
case e: java.lang.reflect.InvocationTargetException =>
42+
throw e.getCause
43+
finally
44+
deleteFile(outDir.toFile)
45+
case None =>
4646
end compileAndRun
4747

4848
private def deleteFile(target: File): Unit =

compiler/test/dotty/tools/dotc/ScalaCommandTest.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class ScalaCommandTest:
1616
@Test def `Simple one parameter`: Unit =
1717
val settings = config.ScalaSettings()
1818
val args = "-cp path/to/classes1:other/path/to/classes2 files".split(" ")
19-
val summary = ScalacCommand.distill(args, settings, settings.defaultState)
19+
val summary = ScalacCommand.distill(args, settings)()
2020
given SettingsState = summary.sstate
2121
assertEquals("path/to/classes1:other/path/to/classes2", settings.classpath.value)
2222
assertEquals("files" :: Nil, summary.arguments)
@@ -28,7 +28,7 @@ class ScalaCommandTest:
2828
writer.write("-sourceroot myNewRoot someMoreFiles");
2929
writer.close();
3030
val args = s"-cp path/to/classes1:other/path/to/classes2 @$file someFiles".split(" ")
31-
val summary = ScalacCommand.distill(args, settings, settings.defaultState)
31+
val summary = ScalacCommand.distill(args, settings)()
3232

3333
given SettingsState = summary.sstate
3434
assertEquals("path/to/classes1:other/path/to/classes2", settings.classpath.value)

compiler/test/dotty/tools/dotc/SettingsTests.scala

+6-6
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class SettingsTests {
4747

4848
inContext {
4949
val args = List("-foo", "b", "-bar", "1")
50-
val summary = Settings.processArguments(args, Settings.defaultState, true)
50+
val summary = Settings.processArguments(args, true)
5151
assertTrue(summary.errors.isEmpty)
5252
given SettingsState = summary.sstate
5353
assertEquals("b", Settings.foo.value)
@@ -65,7 +65,7 @@ class SettingsTests {
6565

6666
inContext {
6767
val args = List("-foo", "b", "-bar", "1", "-baz", "5")
68-
val summary = Settings.processArguments(args, Settings.defaultState, true)
68+
val summary = Settings.processArguments(args, true)
6969
assertTrue(summary.errors.isEmpty)
7070
given SettingsState = summary.sstate
7171
assertEquals("b", Settings.foo.value)
@@ -75,15 +75,15 @@ class SettingsTests {
7575

7676
inContext {
7777
val args = List("-foo:b")
78-
val summary = Settings.processArguments(args, Settings.defaultState, true)
78+
val summary = Settings.processArguments(args, true)
7979
assertTrue(summary.errors.isEmpty)
8080
given SettingsState = summary.sstate
8181
assertEquals("b", Settings.foo.value)
8282
}
8383

8484
inContext {
8585
val args = List("-foo", "c", "-bar", "3", "-baz", "-1")
86-
val summary = Settings.processArguments(args, Settings.defaultState, true)
86+
val summary = Settings.processArguments(args, true)
8787
val expectedErrors = List(
8888
"c is not a valid choice for -foo",
8989
"3 is not a valid choice for -bar",
@@ -94,14 +94,14 @@ class SettingsTests {
9494

9595
inContext {
9696
val args = List("-foo:c")
97-
val summary = Settings.processArguments(args, Settings.defaultState, true)
97+
val summary = Settings.processArguments(args, true)
9898
val expectedErrors = List("c is not a valid choice for -foo")
9999
assertEquals(expectedErrors, summary.errors)
100100
}
101101

102102
inContext {
103103
val args = List("-quux", "a", "-quuz", "0")
104-
val summary = Settings.processArguments(args, Settings.defaultState, true)
104+
val summary = Settings.processArguments(args, true)
105105
val expectedErrors = List(
106106
"a is not a valid choice for -quux",
107107
"0 is not a valid choice for -quuz",

sbt-bridge/src/dotty/tools/xsbt/CompilerBridgeDriver.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ synchronized public void run(VirtualFile[] sources, AnalysisCallback callback, L
6060
.setReporter(reporter)
6161
.setSbtCallback(callback);
6262

63-
Contexts.Context context = setup(args, initialCtx)._2;
63+
Contexts.Context context = setup(args, initialCtx).map(t -> t._2).getOrElse(() -> initialCtx);
6464

6565
if (ScalacCommand.isHelpFlag(context.settings(), context.settingsState())) {
6666
throw new InterfaceCompileFailed(args, new Problem[0], StopInfoError);

scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ object Scaladoc:
7676
given CompilerContext = newContext
7777
val ss = ScaladocSettings()
7878
import ss._
79-
val summary = ScaladocCommand.distill(args, ss, ss.defaultState)
79+
val summary = ScaladocCommand.distill(args, ss)()
8080
val argumentFilesOrNone = ScaladocCommand.checkUsage(summary, true)(using ss)(using summary.sstate)
8181

8282
extension[T](arg: Setting[T])

staging/src/scala/quoted/staging/QuoteDriver.scala

+4-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ private class QuoteDriver(appClassloader: ClassLoader) extends Driver:
3333
new VirtualDirectory("<quote compilation output>")
3434
end outDir
3535

36-
val (_, ctx0: Context) = setup(settings.compilerArgs.toArray :+ "dummy.scala", initCtx.fresh)
36+
val freshContext = initCtx.fresh
37+
val ctx0 = setup(settings.compilerArgs.toArray :+ "dummy.scala", freshContext) match
38+
case Some((_, ctx0: Context)) => ctx0
39+
case None => freshContext
3740
val ctx = setCompilerSettings(ctx0.fresh.setSetting(ctx0.settings.outputDir, outDir), settings)
3841

3942
new QuoteCompiler().newRun(ctx).compileExpr(exprBuilder) match

0 commit comments

Comments
 (0)