Skip to content

Commit ee214a5

Browse files
committed
Merge pull request #111 from DarkDimius/phase-req
Allow phases to give restrictions on pipeline position.
2 parents 42e7488 + bbad484 commit ee214a5

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed

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

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,24 @@ object Phases {
7474
*/
7575
private def squashPhases(phasess: List[List[Phase]]): Array[Phase] = {
7676
val squashedPhases = ListBuffer[Phase]()
77+
var prevPhases: Set[String] = Set.empty
7778
var postTyperEmmited = false
7879
var i = 0
7980
while (i < phasess.length) {
8081
if (phasess(i).length > 1) {
81-
assert(phasess(i).forall(x => x.isInstanceOf[TreeTransform]), "Only tree transforms can be squashed")
82+
val phasesInBlock: Set[String] = phasess(i).map(_.name).toSet
83+
for(phase<-phasess(i)) {
84+
phase match {
85+
case p: TreeTransform =>
8286

87+
val unmetRequirements = p.runsAfterGroupsOf &~ prevPhases
88+
assert(unmetRequirements.isEmpty,
89+
s"${phase.name} requires ${unmetRequirements.mkString(", ")} to be in different TreeTransformer")
90+
91+
case _ =>
92+
assert(false, s"Only tree transforms can be squashed, ${phase.name} can not be squashed")
93+
}
94+
}
8395
val transforms = phasess(i).asInstanceOf[List[TreeTransform]]
8496
val block =
8597
if (!postTyperEmmited) {
@@ -93,6 +105,7 @@ object Phases {
93105
override def transformations: Array[TreeTransform] = transforms.toArray
94106
}
95107
squashedPhases += block
108+
prevPhases ++= phasess(i).map(_.name)
96109
block.init(this, phasess(i).head.id, phasess(i).last.id)
97110
} else squashedPhases += phasess(i).head
98111
i += 1
@@ -106,11 +119,16 @@ object Phases {
106119
*/
107120
def usePhases(phasess: List[List[Phase]], squash: Boolean = true) = {
108121
phases = (NoPhase :: phasess.flatten ::: new TerminalPhase :: Nil).toArray
122+
var phasesAfter:Set[String] = Set.empty
109123
nextDenotTransformerId = new Array[Int](phases.length)
110124
denotTransformers = new Array[DenotTransformer](phases.length)
111125
var i = 0
112126
while (i < phases.length) {
113127
phases(i).init(this, i)
128+
val unmetPreceedeRequirements = phases(i).runsAfter -- phasesAfter
129+
assert(unmetPreceedeRequirements.isEmpty,
130+
s"phase ${phases(i)} has unmet requirement: ${unmetPreceedeRequirements.mkString(", ")} should precede this phase")
131+
phasesAfter += phases(i).name
114132
i += 1
115133
}
116134
var lastTransformerId = i
@@ -170,6 +188,9 @@ object Phases {
170188

171189
def name: String
172190

191+
/** List of names of phases that should precede this phase */
192+
def runsAfter: Set[String] = Set.empty
193+
173194
def run(implicit ctx: Context): Unit
174195

175196
def runOn(units: List[CompilationUnit])(implicit ctx: Context): Unit =

src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ class Erasure extends Phase with DenotTransformer {
2727

2828
override def name: String = "erasure"
2929

30+
/** List of names of phases that should precede this phase */
31+
override def runsAfter: Set[String] = Set("typeTestsCasts", "intercepted", "splitter")
32+
3033
def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref match {
3134
case ref: SymDenotation =>
3235
assert(ctx.phase == this, s"transforming $ref at ${ctx.phase}")

src/dotty/tools/dotc/transform/LazyVals.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,17 @@ class LazyValTranformContext {
6363

6464
override def name: String = "LazyVals"
6565

66+
/** List of names of phases that should have finished their processing of all compilation units
67+
* before this phase starts */
68+
override def runsAfterGroupsOf: Set[String] = Set("lazyValsModules")
69+
/** List of names of phases that should have finished their processing of all compilation units
70+
* before this phase starts */
71+
override def runsAfter: Set[String] = Set("lazyValsModules")
72+
73+
/** List of names of phases that should have finished processing of tree
74+
* before this phase starts processing same tree */
75+
// override def ensureAfter: Set[String] = Set("mixin")
76+
6677
def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = {
6778
ref match {
6879
case ref: SymDenotation if ref.symbol.isClass =>

src/dotty/tools/dotc/transform/TreeTransform.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ object TreeTransforms {
5353
/** id of this treeTransform in group */
5454
var idx: Int = _
5555

56+
/** List of names of phases that should have finished their processing of all compilation units
57+
* before this phase starts */
58+
def runsAfterGroupsOf: Set[String] = Set.empty
59+
5660
def prepareForIdent(tree: Ident)(implicit ctx: Context) = this
5761
def prepareForSelect(tree: Select)(implicit ctx: Context) = this
5862
def prepareForThis(tree: This)(implicit ctx: Context) = this

0 commit comments

Comments
 (0)