Skip to content

Commit ded9e61

Browse files
committed
Fix #95: Phases now have their own periods.
1 parent 97faee5 commit ded9e61

File tree

3 files changed

+29
-15
lines changed

3 files changed

+29
-15
lines changed

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,14 @@ object Contexts {
280280
final def withMode(mode: Mode): Context =
281281
if (mode != this.mode) fresh.setMode(mode) else this
282282

283-
final def withPhase(phase: PhaseId): Context =
284-
if (this.phaseId == phaseId) this else fresh.setPhase(phase)
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)
285288
final def withPhase(phase: Phase): Context =
286-
withPhase(phase.id)
289+
if (this.period == phase.period) this else fresh.setPhase(phase)
290+
287291

288292
final def addMode(mode: Mode): Context = withMode(this.mode | mode)
289293
final def maskMode(mode: Mode): Context = withMode(this.mode & mode)
@@ -330,7 +334,7 @@ object Contexts {
330334
def setProperty(prop: (String, Any)): this.type = setMoreProperties(moreProperties + prop)
331335

332336
def setPhase(pid: PhaseId): this.type = setPeriod(Period(runId, pid))
333-
def setPhase(phase: Phase): this.type = setPhase(phase.id)
337+
def setPhase(phase: Phase): this.type = setPeriod(Period(runId, phase.start, phase.end))
334338

335339
def setSetting[T](setting: Setting[T], value: T): this.type =
336340
setSettings(setting.updateIn(sstate, value))

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

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

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ import dotty.tools.dotc.transform.TreeTransforms.{TreeTransformer, TreeTransform
1212
import dotty.tools.dotc.transform.PostTyperTransformers.PostTyperTransformer
1313
import dotty.tools.dotc.transform.TreeTransforms
1414
import TreeTransforms.Separator
15+
import Periods._
1516

1617
trait Phases {
1718
self: Context =>
1819

1920
import Phases._
2021

21-
def phase: Phase = base.phases(period.phaseId)
22+
def phase: Phase = base.phases(period.firstPhaseId)
2223

2324
def phasesStack: List[Phase] =
2425
if ((this eq NoContext) || !phase.exists) Nil
@@ -66,6 +67,7 @@ object Phases {
6667
override def lastPhaseId(implicit ctx: Context) = id
6768
}
6869

70+
6971
/** Use the following phases in the order they are given.
7072
* The list should never contain NoPhase.
7173
* if squashing is enabled, phases in same subgroup will be squashed to single phase.
@@ -112,7 +114,7 @@ object Phases {
112114
override protected def transformations: Array[TreeTransform] = transforms.toArray
113115
}
114116
squashedPhases += block
115-
block.init(this, phasess(i).head.id)
117+
block.init(this, phasess(i).head.id, phasess(i).last.id)
116118
} else squashedPhases += phasess(i).head
117119
i += 1
118120
}
@@ -171,7 +173,7 @@ object Phases {
171173

172174
def exists: Boolean = true
173175

174-
private var myId: PhaseId = -1
176+
private var myPeriod: Period = Periods.InvalidPeriod
175177
private var myBase: ContextBase = null
176178
private var myErasedTypes = false
177179
private var myFlatClasses = false
@@ -181,32 +183,38 @@ object Phases {
181183
* is reserved for NoPhase and the first real phase is at position 1.
182184
* -1 if the phase is not installed in the context.
183185
*/
184-
def id = myId
186+
def id = myPeriod.firstPhaseId
187+
188+
def period = myPeriod
189+
def start = myPeriod.firstPhaseId
190+
def end = myPeriod.lastPhaseId
185191

186192
final def erasedTypes = myErasedTypes
187193
final def flatClasses = myFlatClasses
188194
final def refChecked = myRefChecked
189195

190-
protected[Phases] def init(base: ContextBase, id: Int): Unit = {
191-
if (id >= FirstPhaseId)
192-
assert(myId == -1, s"phase $this has already been used once; cannot be reused")
196+
protected[Phases] def init(base: ContextBase, start: Int, end:Int): Unit = {
197+
if (start >= FirstPhaseId)
198+
assert(myPeriod == Periods.InvalidPeriod, s"phase $this has already been used once; cannot be reused")
193199
myBase = base
194-
myId = id
200+
myPeriod = Period(start, end)
195201
myErasedTypes = prev.name == erasureName || prev.erasedTypes
196202
myFlatClasses = prev.name == flattenName || prev.flatClasses
197203
myRefChecked = prev.name == refChecksName || prev.refChecked
198204
}
199205

206+
protected[Phases] def init(base: ContextBase, id: Int): Unit = init(base, id, id)
207+
200208
final def <=(that: Phase)(implicit ctx: Context) =
201209
exists && id <= that.id
202210

203211
final def prev: Phase =
204-
if (id > FirstPhaseId) myBase.phases(id - 1) else myBase.NoPhase
212+
if (id > FirstPhaseId) myBase.phases(start - 1) else myBase.NoPhase
205213

206214
final def next: Phase =
207-
if (hasNext) myBase.phases(id + 1) else myBase.NoPhase
215+
if (hasNext) myBase.phases(end + 1) else myBase.NoPhase
208216

209-
final def hasNext = id >= FirstPhaseId && id + 1 < myBase.phases.length
217+
final def hasNext = start >= FirstPhaseId && end + 1 < myBase.phases.length
210218

211219
final def iterator =
212220
Iterator.iterate(this)(_.next) takeWhile (_.hasNext)

0 commit comments

Comments
 (0)