Skip to content

Commit 695ce6d

Browse files
committed
Assemble phases for -Vphases
1 parent da2c540 commit 695ce6d

File tree

3 files changed

+39
-30
lines changed

3 files changed

+39
-30
lines changed

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

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import typer.Typer
1212
import typer.ImportInfo.withRootImports
1313
import Decorators.*
1414
import io.AbstractFile
15-
import Phases.{unfusedPhases, Phase}
15+
import Phases.{assemblePhases, unfusedPhases, Phase}
1616

1717
import sbt.interfaces.ProgressCallback
1818

@@ -295,19 +295,12 @@ extends ImplicitRunInfo, ConstraintRunInfo, cc.CaptureRunInfo {
295295
report.echo(this.enrichErrorMessage(s"exception occurred while compiling ${files1.map(_.path)}"))
296296
throw ex
297297

298-
/** TODO: There's a fundamental design problem here: We assemble phases using `fusePhases`
299-
* when we first build the compiler. But we modify them with -Yskip, -Ystop
300-
* on each run. That modification needs to either transform the tree structure,
301-
* or we need to assemble phases on each run, and take -Yskip, -Ystop into
302-
* account. I think the latter would be preferable.
303-
*/
304298
def compileSources(sources: List[SourceFile]): Unit =
305299
if (sources forall (_.exists)) {
306300
units = sources.map(CompilationUnit(_))
307301
compileUnits()
308302
}
309303

310-
311304
def compileUnits(us: List[CompilationUnit]): Unit = {
312305
units = us
313306
compileUnits()
@@ -333,23 +326,9 @@ extends ImplicitRunInfo, ConstraintRunInfo, cc.CaptureRunInfo {
333326
then ActiveProfile(ctx.settings.VprofileDetails.value.max(0).min(1000))
334327
else NoProfile
335328

336-
// If testing pickler, make sure to stop after pickling phase:
337-
val stopAfter =
338-
if (ctx.settings.YtestPickler.value) List("pickler")
339-
else ctx.settings.YstopAfter.value
340-
341-
val runCtx = ctx.fresh
329+
val runCtx = assemblePhases()
342330
runCtx.setProfiler(Profiler())
343331

344-
val pluginPlan = ctx.base.addPluginPhases(ctx.base.phasePlan)
345-
val phases = ctx.base.fusePhases(pluginPlan,
346-
ctx.settings.Yskip.value, ctx.settings.YstopBefore.value, stopAfter, ctx.settings.Ycheck.value)
347-
ctx.base.usePhases(phases, runCtx)
348-
val phasesSettings = List("-Vphases", "-Vprint")
349-
for phasesSetting <- ctx.settings.allSettings if phasesSettings.contains(phasesSetting.name) do
350-
for case vs: List[String] <- phasesSetting.userValue; p <- vs do
351-
if !phases.exists(List(p).containsPhase) then report.warning(s"'$p' specifies no phase")
352-
353332
if ctx.settings.YnoDoubleBindings.value then
354333
ctx.base.checkNoDoubleBindings = true
355334

@@ -359,7 +338,7 @@ extends ImplicitRunInfo, ConstraintRunInfo, cc.CaptureRunInfo {
359338
var phasesWereAdjusted = false
360339

361340
var forceReachPhaseMaybe =
362-
if (ctx.isBestEffort && phases.exists(_.phaseName == "typer")) Some("typer")
341+
if (ctx.isBestEffort && allPhases.exists(_.phaseName == "typer")) Some("typer")
363342
else None
364343

365344
for phase <- allPhases do

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package config
33

44
import Settings.*
55
import core.Contexts.*
6+
import core.Phases.assemblePhases
67
import printing.Highlighting
8+
import transform.MegaPhase
79

810
import dotty.tools.dotc.util.chaining.*
911
import scala.PartialFunction.cond
@@ -115,9 +117,17 @@ trait CliCommand:
115117

116118
/** Used for the formatted output of -Xshow-phases */
117119
protected def phasesMessage(using Context): String =
118-
val phases = new Compiler().phases
120+
val compiler = new Compiler()
121+
ctx.initialize()
122+
ctx.base.setPhasePlan(compiler.phases)
123+
val runCtx = assemblePhases()
124+
val phases = runCtx.base.allPhases
125+
val texts = phases.iterator.map {
126+
case mp: MegaPhase => mp.miniPhases.iterator.map(p => (p.phaseName, p.description)).toList
127+
case p => (p.phaseName, p.description) :: Nil
128+
}.toList
119129
val formatter = Columnator("phase name", "description", maxField = 25)
120-
formatter(phases.map(mega => mega.map(p => (p.phaseName, p.description))))
130+
formatter(texts)
121131

122132
/** Provide usage feedback on argument summary, assuming that all settings
123133
* are already applied in context.

compiler/src/dotty/tools/dotc/core/Phases.scala

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,12 @@ object Phases {
128128
*/
129129
final def usePhases(phasess: List[Phase], runCtx: FreshContext, fuse: Boolean = true): Unit = {
130130

131-
val flatPhases = collection.mutable.ListBuffer[Phase]()
131+
val flatPhases = ListBuffer.empty[Phase]
132132

133-
phasess.foreach(p => p match {
133+
phasess.foreach {
134134
case p: MegaPhase => flatPhases ++= p.miniPhases
135-
case _ => flatPhases += p
136-
})
135+
case p => flatPhases += p
136+
}
137137

138138
phases = (NoPhase :: flatPhases.toList ::: new TerminalPhase :: Nil).toArray
139139
setSpecificPhases()
@@ -564,4 +564,24 @@ object Phases {
564564
private def replace(oldPhaseClass: Class[? <: Phase], newPhases: Phase => List[Phase], current: List[List[Phase]]): List[List[Phase]] =
565565
current.map(_.flatMap(phase =>
566566
if (oldPhaseClass.isInstance(phase)) newPhases(phase) else phase :: Nil))
567+
568+
def assemblePhases()(using Context): FreshContext =
569+
val runCtx = ctx.fresh
570+
571+
// If testing pickler, make sure to stop after pickling phase:
572+
val stopAfter =
573+
if (ctx.settings.YtestPickler.value) List("pickler")
574+
else ctx.settings.YstopAfter.value
575+
576+
val pluginPlan = ctx.base.addPluginPhases(ctx.base.phasePlan)
577+
val phases = ctx.base.fusePhases(pluginPlan,
578+
ctx.settings.Yskip.value, ctx.settings.YstopBefore.value, stopAfter, ctx.settings.Ycheck.value)
579+
ctx.base.usePhases(phases, runCtx)
580+
581+
val phasesSettings = List("-Vphases", "-Vprint")
582+
for phasesSetting <- ctx.settings.allSettings if phasesSettings.contains(phasesSetting.name) do
583+
for case vs: List[String] <- phasesSetting.userValue; p <- vs do
584+
if !phases.exists(List(p).containsPhase) then report.warning(s"'$p' specifies no phase")
585+
runCtx
586+
end assemblePhases
567587
}

0 commit comments

Comments
 (0)