Skip to content

Commit 6db08e9

Browse files
committed
Merge pull request #100 from DarkDimius/treetransform-next
Give phases periods, not only id's
2 parents 7c5dd00 + ded9e61 commit 6db08e9

22 files changed

+217
-156
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,18 @@ class Compiler {
4242
ctx.usePhases(phases)
4343
val rootScope = new MutableScope
4444
val bootstrap = ctx.fresh
45-
.withPeriod(Period(nextRunId, FirstPhaseId))
46-
.withScope(rootScope)
45+
.setPeriod(Period(nextRunId, FirstPhaseId))
46+
.setScope(rootScope)
4747
rootScope.enter(ctx.definitions.RootPackage)(bootstrap)
4848
val start = bootstrap.fresh
49-
.withOwner(defn.RootClass)
50-
.withTyper(new Typer)
51-
.withNewMode(Mode.ImplicitsEnabled)
52-
.withTyperState(new MutableTyperState(ctx.typerState, new ConsoleReporter()(ctx), isCommittable = true))
49+
.setOwner(defn.RootClass)
50+
.setTyper(new Typer)
51+
.setMode(Mode.ImplicitsEnabled)
52+
.setTyperState(new MutableTyperState(ctx.typerState, new ConsoleReporter()(ctx), isCommittable = true))
5353
ctx.definitions.init(start) // set context of definitions to start
5454
def addImport(ctx: Context, sym: Symbol) =
55-
ctx.fresh.withImportInfo(ImportInfo.rootImport(sym)(ctx))
56-
(start.withRunInfo(new RunInfo(start)) /: defn.RootImports)(addImport)
55+
ctx.fresh.setImportInfo(ImportInfo.rootImport(sym)(ctx))
56+
(start.setRunInfo(new RunInfo(start)) /: defn.RootImports)(addImport)
5757
}
5858

5959
def newRun(implicit ctx: Context): Run = {

src/dotty/tools/dotc/Driver.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ abstract class Driver extends DotClass {
2424

2525
def process(args: Array[String]): Reporter = {
2626
val summary = CompilerCommand.distill(args)(initCtx)
27-
implicit val ctx: Context = initCtx.fresh.withSettings(summary.sstate)
27+
implicit val ctx: Context = initCtx.fresh.setSettings(summary.sstate)
2828
val fileNames = CompilerCommand.checkUsage(summary)
2929
try {
3030
doCompile(newCompiler(), fileNames)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ object PathResolver {
135135

136136
def fromPathString(path: String)(implicit ctx: Context): JavaClassPath = {
137137
val settings = ctx.settings.classpath.update(path)
138-
new PathResolver()(ctx.fresh.withSettings(settings)).result
138+
new PathResolver()(ctx.fresh.setSettings(settings)).result
139139
}
140140

141141
/** With no arguments, show the interesting values in Environment and Defaults.
@@ -152,7 +152,7 @@ object PathResolver {
152152
val ArgsSummary(sstate, rest, errors) =
153153
ctx.settings.processArguments(args.toList, true)
154154
errors.foreach(println)
155-
val pr = new PathResolver()(ctx.fresh.withSettings(sstate))
155+
val pr = new PathResolver()(ctx.fresh.setSettings(sstate))
156156
println(" COMMAND: 'scala %s'".format(args.mkString(" ")))
157157
println("RESIDUAL: 'scala %s'\n".format(rest.mkString(" ")))
158158
pr.result.show

src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -278,12 +278,16 @@ object Contexts {
278278
}
279279

280280
final def withMode(mode: Mode): Context =
281-
if (mode != this.mode) fresh.withNewMode(mode) else this
281+
if (mode != this.mode) fresh.setMode(mode) else this
282+
283+
/**
284+
* This method will always return a phase period equal to phaseId, thus will never return squashed phases
285+
*/
286+
final def withPhase(phaseId: PhaseId): Context =
287+
if (this.phaseId == phaseId) this else fresh.setPhase(phaseId)
288+
final def withPhase(phase: Phase): Context =
289+
if (this.period == phase.period) this else fresh.setPhase(phase)
282290

283-
def withPhase(phase: PhaseId): Context =
284-
if (this.phaseId == phaseId) this else fresh.withPhase(phase)
285-
def withPhase(phase: Phase): Context =
286-
withPhase(phase.id)
287291

288292
final def addMode(mode: Mode): Context = withMode(this.mode | mode)
289293
final def maskMode(mode: Mode): Context = withMode(this.mode & mode)
@@ -306,36 +310,36 @@ object Contexts {
306310
* of its attributes using the with... methods.
307311
*/
308312
abstract class FreshContext extends Context {
309-
def withPeriod(period: Period): this.type = { this.period = period; this }
310-
def withNewMode(mode: Mode): this.type = { this.mode = mode; this }
311-
def withTyperState(typerState: TyperState): this.type = { this.typerState = typerState; this }
312-
def withNewTyperState: this.type = withTyperState(typerState.fresh(isCommittable = true))
313-
def withExploreTyperState: this.type = withTyperState(typerState.fresh(isCommittable = false))
314-
def withPrinterFn(printer: Context => Printer): this.type = { this.printerFn = printer; this }
315-
def withOwner(owner: Symbol): this.type = { assert(owner != NoSymbol); this.owner = owner; this }
316-
def withSettings(sstate: SettingsState): this.type = { this.sstate = sstate; this }
317-
def withCompilationUnit(compilationUnit: CompilationUnit): this.type = { this.compilationUnit = compilationUnit; this }
318-
def withTree(tree: Tree[_ >: Untyped]): this.type = { this.tree = tree; this }
319-
def withScope(scope: Scope): this.type = { this.scope = scope; this }
320-
def withNewScope: this.type = { this.scope = newScope; this }
321-
def withTypeAssigner(typeAssigner: TypeAssigner): this.type = { this.typeAssigner = typeAssigner; this }
322-
def withTyper(typer: Typer): this.type = { this.scope = typer.scope; withTypeAssigner(typer) }
323-
def withImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this }
324-
def withRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this }
325-
def withDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
326-
def withTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this }
327-
def withSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this }
328-
def withMoreProperties(moreProperties: Map[String, Any]): this.type = { this.moreProperties = moreProperties; this }
329-
330-
def withProperty(prop: (String, Any)): this.type = withMoreProperties(moreProperties + prop)
331-
332-
override def withPhase(pid: PhaseId): this.type = withPeriod(Period(runId, pid))
333-
override def withPhase(phase: Phase): this.type = withPhase(phase.id)
334-
335-
def withSetting[T](setting: Setting[T], value: T): this.type =
336-
withSettings(setting.updateIn(sstate, value))
337-
338-
def withDebug = withSetting(base.settings.debug, true)
313+
def setPeriod(period: Period): this.type = { this.period = period; this }
314+
def setMode(mode: Mode): this.type = { this.mode = mode; this }
315+
def setTyperState(typerState: TyperState): this.type = { this.typerState = typerState; this }
316+
def clearTyperState: this.type = setTyperState(typerState.fresh(isCommittable = true))
317+
def setExploreTyperState: this.type = setTyperState(typerState.fresh(isCommittable = false))
318+
def setPrinterFn(printer: Context => Printer): this.type = { this.printerFn = printer; this }
319+
def setOwner(owner: Symbol): this.type = { assert(owner != NoSymbol); this.owner = owner; this }
320+
def setSettings(sstate: SettingsState): this.type = { this.sstate = sstate; this }
321+
def setCompilationUnit(compilationUnit: CompilationUnit): this.type = { this.compilationUnit = compilationUnit; this }
322+
def setTree(tree: Tree[_ >: Untyped]): this.type = { this.tree = tree; this }
323+
def setScope(scope: Scope): this.type = { this.scope = scope; this }
324+
def clearScope: this.type = { this.scope = newScope; this }
325+
def setTypeAssigner(typeAssigner: TypeAssigner): this.type = { this.typeAssigner = typeAssigner; this }
326+
def setTyper(typer: Typer): this.type = { this.scope = typer.scope; setTypeAssigner(typer) }
327+
def setImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this }
328+
def setRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this }
329+
def setDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
330+
def setTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this }
331+
def setSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this }
332+
def setMoreProperties(moreProperties: Map[String, Any]): this.type = { this.moreProperties = moreProperties; this }
333+
334+
def setProperty(prop: (String, Any)): this.type = setMoreProperties(moreProperties + prop)
335+
336+
def setPhase(pid: PhaseId): this.type = setPeriod(Period(runId, pid))
337+
def setPhase(phase: Phase): this.type = setPeriod(Period(runId, phase.start, phase.end))
338+
339+
def setSetting[T](setting: Setting[T], value: T): this.type =
340+
setSettings(setting.updateIn(sstate, value))
341+
342+
def setDebug = setSetting(base.settings.debug, true)
339343
}
340344

341345
/** A class defining the initial context with given context base

src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import printing.Printer
1919
import io.AbstractFile
2020
import config.Config
2121
import util.common._
22+
import collection.mutable.ListBuffer
2223
import Decorators.SymbolIteratorDecorator
2324

2425
/** Denotations represent the meaning of symbols and named types.
@@ -459,7 +460,7 @@ object Denotations {
459460
* 2) the union of all validity periods is a contiguous
460461
* interval.
461462
*/
462-
var nextInRun: SingleDenotation = this
463+
private var nextInRun: SingleDenotation = this
463464

464465
/** The version of this SingleDenotation that was valid in the first phase
465466
* of this run.
@@ -470,6 +471,17 @@ object Denotations {
470471
current
471472
}
472473

474+
def history: List[SingleDenotation] = {
475+
val b = new ListBuffer[SingleDenotation]
476+
var current = initial
477+
do {
478+
b += (current)
479+
current = current.nextInRun
480+
}
481+
while (current ne initial)
482+
b.toList
483+
}
484+
473485
/** Move validity period of this denotation to a new run. Throw a StaleSymbol error
474486
* if denotation is no longer valid.
475487
*/
@@ -518,27 +530,30 @@ object Denotations {
518530
cur = next
519531
cur
520532
} else {
533+
//println(s"might need new denot for $cur, valid for ${cur.validFor} at $currentPeriod")
521534
// not found, cur points to highest existing variant
522-
var startPid = cur.validFor.lastPhaseId + 1
523-
val nextTranformerId = ctx.nextDenotTransformerId(startPid)
524-
val transformer = ctx.denotTransformers(nextTranformerId)
525-
//println(s"transforming with $transformer")
526-
if (currentPeriod.lastPhaseId > transformer.id)
527-
next = transformer.transform(cur)(ctx.withPhase(startPid)).syncWithParents
528-
if (next eq cur)
529-
startPid = cur.validFor.firstPhaseId
535+
val nextTransformerId = ctx.nextDenotTransformerId(cur.validFor.lastPhaseId)
536+
if (currentPeriod.lastPhaseId <= nextTransformerId)
537+
cur.validFor = Period(currentPeriod.runId, cur.validFor.firstPhaseId, nextTransformerId)
530538
else {
531-
next match {
532-
case next: ClassDenotation => next.resetFlag(Frozen)
533-
case _ =>
539+
var startPid = nextTransformerId + 1
540+
val transformer = ctx.denotTransformers(nextTransformerId)
541+
//println(s"transforming $this with $transformer")
542+
next = transformer.transform(cur)(ctx.withPhase(transformer)).syncWithParents
543+
if (next eq cur)
544+
startPid = cur.validFor.firstPhaseId
545+
else {
546+
next match {
547+
case next: ClassDenotation => next.resetFlag(Frozen)
548+
case _ =>
549+
}
550+
next.nextInRun = cur.nextInRun
551+
cur.nextInRun = next
552+
cur = next
534553
}
535-
next.nextInRun = cur.nextInRun
536-
cur.nextInRun = next
537-
cur = next
554+
cur.validFor = Period(currentPeriod.runId, startPid, transformer.lastPhaseId)
555+
//println(s"new denot: $cur, valid for ${cur.validFor}")
538556
}
539-
cur.validFor = Period(
540-
currentPeriod.runId, startPid, transformer.lastPhaseId)
541-
//println(s"new denot: $cur, valid for ${cur.validFor}")
542557
cur.current // multiple transformations could be required
543558
}
544559
} else {
@@ -562,7 +577,7 @@ object Denotations {
562577
case denot: SymDenotation => s"in ${denot.owner}"
563578
case _ => ""
564579
}
565-
def msg = s"stale symbol; $this#${symbol.id}$ownerMsg, defined in run ${myValidFor.runId}, is referred to in run ${ctx.period.runId}"
580+
def msg = s"stale symbol; $this#${symbol.id} $ownerMsg, defined in run ${myValidFor.runId}, is referred to in run ${ctx.runId}"
566581
throw new StaleSymbol(msg)
567582
}
568583

src/dotty/tools/dotc/core/Periods.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ abstract class Periods extends DotClass { self: Context =>
1919

2020
/** Execute `op` at given period */
2121
def atPeriod[T](pd: Period)(op: Context => T): T =
22-
op(ctx.fresh.withPeriod(pd))
22+
op(ctx.fresh.setPeriod(pd))
2323

2424
/** Execute `op` at given phase id */
2525
def atPhase[T](pid: PhaseId)(op: Context => T): T =
26-
op(ctx.fresh.withPhase(pid))
26+
op(ctx.withPhase(pid))
2727

2828
/** The period containing the current period where denotations do not change.
2929
* We compute this by taking as first phase the first phase less or equal to
@@ -129,6 +129,8 @@ object Periods {
129129

130130
final val InitialPeriod = Period(InitialRunId, FirstPhaseId)
131131

132+
final val InvalidPeriod = Period(NoRunId, NoPhaseId)
133+
132134
/** An ordinal number for compiler runs. First run has number 1. */
133135
type RunId = Int
134136
final val NoRunId = 0

0 commit comments

Comments
 (0)