blob: 039bba1647ee5ec340934f211921774a86b3ac4a (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
package dotty.tools.dotc
package core
import Periods._, Contexts._
trait Phases { self: Context =>
import Phases._
def phase: Phase = base.phases(period.phaseId)
def phasesStack: List[Phase] =
if (phase == this.NoPhase) Nil
else phase :: outersIterator.dropWhile(_.phase == phase).next.phasesStack
/** Execute `op` at given phase id */
def atPhase[T](phase: Phase)(op: Context => T): T =
atPhase(phase.id)(op)
def atPhaseNotLaterThan[T](limit: Phase)(op: Context => T): T =
if (!limit.exists || phase <= limit) op(this) else atPhase(limit)(op)
def atPhaseNotLaterThanTyper[T](op: Context => T): T =
atPhaseNotLaterThan(base.typerPhase)(op)
}
object Phases {
trait PhasesBase { this: ContextBase =>
lazy val allPhases = phases.slice(FirstPhaseId, nphases)
val NoPhase = new Phase(initialCtx) {
def name = "<no phase>"
def run() { throw new Error("NoPhase.run") }
}
object SomePhase extends Phase(initialCtx) {
def name = "<some phase>"
def run() { throw new Error("SomePhase.run") }
}
def phaseNamed(name: String) =
allPhases.find(_.name == name).getOrElse(NoPhase)
final val typerName = "typer"
final val refchecksName = "refchecks"
final val erasureName = "erasure"
final val flattenName = "flatten"
lazy val typerPhase = phaseNamed(typerName)
lazy val refchecksPhase = phaseNamed(refchecksName)
lazy val erasurePhase = phaseNamed(erasureName)
lazy val flattenPhase = phaseNamed(flattenName)
}
abstract class Phase(initctx: Context) {
val id: Int = initctx.nphases
initctx.nphases += 1
def name: String
def run(): Unit
def description: String = name
def checkable: Boolean = true
final def exists: Boolean = id != NoPhaseId
final def <= (that: Phase) =
exists && id <= that.id
final def prev(implicit ctx: Context): Phase =
if (id > FirstPhaseId) ctx.phases(id - 1) else initctx.NoPhase
final def next(implicit ctx: Context): Phase =
if (hasNext) ctx.phases(id + 1) else initctx.NoPhase
final def hasNext(implicit ctx: Context) = id + 1 < ctx.nphases
final def iterator(implicit ctx: Context) =
Iterator.iterate(this)(_.next) takeWhile (_.hasNext)
final def erasedTypes(implicit ctx: Context): Boolean = ctx.erasurePhase <= this
final def flatClasses(implicit ctx: Context): Boolean = ctx.flattenPhase <= this
final def refChecked (implicit ctx: Context): Boolean = ctx.refchecksPhase <= this
override def toString = name
}
}
|