Skip to content

Commit 392a2cf

Browse files
committed
Assemble phases for -Vphases
1 parent eea62ba commit 392a2cf

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

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

273-
/** TODO: There's a fundamental design problem here: We assemble phases using `fusePhases`
274-
* when we first build the compiler. But we modify them with -Yskip, -Ystop
275-
* on each run. That modification needs to either transform the tree structure,
276-
* or we need to assemble phases on each run, and take -Yskip, -Ystop into
277-
* account. I think the latter would be preferable.
278-
*/
279273
def compileSources(sources: List[SourceFile]): Unit =
280274
if (sources forall (_.exists)) {
281275
units = sources.map(CompilationUnit(_))
282276
compileUnits()
283277
}
284278

285-
286279
def compileUnits(us: List[CompilationUnit]): Unit = {
287280
units = us
288281
compileUnits()
@@ -308,23 +301,9 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
308301
then ActiveProfile(ctx.settings.VprofileDetails.value.max(0).min(1000))
309302
else NoProfile
310303

311-
// If testing pickler, make sure to stop after pickling phase:
312-
val stopAfter =
313-
if (ctx.settings.YtestPickler.value) List("pickler")
314-
else ctx.settings.YstopAfter.value
315-
316-
val runCtx = ctx.fresh
304+
val runCtx = assemblePhases()
317305
runCtx.setProfiler(Profiler())
318306

319-
val pluginPlan = ctx.base.addPluginPhases(ctx.base.phasePlan)
320-
val phases = ctx.base.fusePhases(pluginPlan,
321-
ctx.settings.Yskip.value, ctx.settings.YstopBefore.value, stopAfter, ctx.settings.Ycheck.value)
322-
ctx.base.usePhases(phases, runCtx)
323-
val phasesSettings = List("-Vphases", "-Vprint")
324-
for phasesSetting <- ctx.settings.allSettings if phasesSettings.contains(phasesSetting.name) do
325-
for case vs: List[String] <- phasesSetting.userValue; p <- vs do
326-
if !phases.exists(List(p).containsPhase) then report.warning(s"'$p' specifies no phase")
327-
328307
if ctx.settings.YnoDoubleBindings.value then
329308
ctx.base.checkNoDoubleBindings = true
330309

@@ -334,7 +313,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
334313
var phasesWereAdjusted = false
335314

336315
var forceReachPhaseMaybe =
337-
if (ctx.isBestEffort && phases.exists(_.phaseName == "typer")) Some("typer")
316+
if (ctx.isBestEffort && allPhases.exists(_.phaseName == "typer")) Some("typer")
338317
else None
339318

340319
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 scala.util.chaining.given
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 = 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()
@@ -561,4 +561,24 @@ object Phases {
561561
private def replace(oldPhaseClass: Class[? <: Phase], newPhases: Phase => List[Phase], current: List[List[Phase]]): List[List[Phase]] =
562562
current.map(_.flatMap(phase =>
563563
if (oldPhaseClass.isInstance(phase)) newPhases(phase) else phase :: Nil))
564+
565+
def assemblePhases()(using Context): FreshContext =
566+
val runCtx = ctx.fresh
567+
568+
// If testing pickler, make sure to stop after pickling phase:
569+
val stopAfter =
570+
if (ctx.settings.YtestPickler.value) List("pickler")
571+
else ctx.settings.YstopAfter.value
572+
573+
val pluginPlan = ctx.base.addPluginPhases(ctx.base.phasePlan)
574+
val phases = ctx.base.fusePhases(pluginPlan,
575+
ctx.settings.Yskip.value, ctx.settings.YstopBefore.value, stopAfter, ctx.settings.Ycheck.value)
576+
ctx.base.usePhases(phases, runCtx)
577+
578+
val phasesSettings = List("-Vphases", "-Vprint")
579+
for phasesSetting <- ctx.settings.allSettings if phasesSettings.contains(phasesSetting.name) do
580+
for case vs: List[String] <- phasesSetting.userValue; p <- vs do
581+
if !phases.exists(List(p).containsPhase) then report.warning(s"'$p' specifies no phase")
582+
runCtx
583+
end assemblePhases
564584
}

0 commit comments

Comments
 (0)