Skip to content

Commit c5980ee

Browse files
committed
Assemble phases for -Vphases
1 parent b90a47d commit c5980ee

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

@@ -294,19 +294,12 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
294294
report.echo(this.enrichErrorMessage(s"exception occurred while compiling ${files1.map(_.path)}"))
295295
throw ex
296296

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

309-
310303
def compileUnits(us: List[CompilationUnit]): Unit = {
311304
units = us
312305
compileUnits()
@@ -332,23 +325,9 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
332325
then ActiveProfile(ctx.settings.VprofileDetails.value.max(0).min(1000))
333326
else NoProfile
334327

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

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

@@ -358,7 +337,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
358337
var phasesWereAdjusted = false
359338

360339
var forceReachPhaseMaybe =
361-
if (ctx.isBestEffort && phases.exists(_.phaseName == "typer")) Some("typer")
340+
if (ctx.isBestEffort && allPhases.exists(_.phaseName == "typer")) Some("typer")
362341
else None
363342

364343
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
@@ -5,7 +5,9 @@ import scala.language.unsafeNulls
55

66
import Settings.*
77
import core.Contexts.*
8+
import core.Phases.assemblePhases
89
import printing.Highlighting
10+
import transform.MegaPhase
911

1012
import dotty.tools.dotc.util.chaining.*
1113
import scala.PartialFunction.cond
@@ -117,9 +119,17 @@ trait CliCommand:
117119

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

124134
/** Provide usage feedback on argument summary, assuming that all settings
125135
* 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)