diff options
-rw-r--r-- | src/dotty/tools/dotc/core/Phases.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/Erasure.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/LazyVals.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeTransform.scala | 4 |
4 files changed, 40 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index eb3b1d7fc..f76b83db6 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -74,12 +74,24 @@ object Phases { */ private def squashPhases(phasess: List[List[Phase]]): Array[Phase] = { val squashedPhases = ListBuffer[Phase]() + var prevPhases: Set[String] = Set.empty var postTyperEmmited = false var i = 0 while (i < phasess.length) { if (phasess(i).length > 1) { - assert(phasess(i).forall(x => x.isInstanceOf[TreeTransform]), "Only tree transforms can be squashed") + val phasesInBlock: Set[String] = phasess(i).map(_.name).toSet + for(phase<-phasess(i)) { + phase match { + case p: TreeTransform => + val unmetRequirements = p.runsAfterGroupsOf &~ prevPhases + assert(unmetRequirements.isEmpty, + s"${phase.name} requires ${unmetRequirements.mkString(", ")} to be in different TreeTransformer") + + case _ => + assert(false, s"Only tree transforms can be squashed, ${phase.name} can not be squashed") + } + } val transforms = phasess(i).asInstanceOf[List[TreeTransform]] val block = if (!postTyperEmmited) { @@ -93,6 +105,7 @@ object Phases { override def transformations: Array[TreeTransform] = transforms.toArray } squashedPhases += block + prevPhases ++= phasess(i).map(_.name) block.init(this, phasess(i).head.id, phasess(i).last.id) } else squashedPhases += phasess(i).head i += 1 @@ -106,11 +119,16 @@ object Phases { */ def usePhases(phasess: List[List[Phase]], squash: Boolean = true) = { phases = (NoPhase :: phasess.flatten ::: new TerminalPhase :: Nil).toArray + var phasesAfter:Set[String] = Set.empty nextDenotTransformerId = new Array[Int](phases.length) denotTransformers = new Array[DenotTransformer](phases.length) var i = 0 while (i < phases.length) { phases(i).init(this, i) + val unmetPreceedeRequirements = phases(i).runsAfter -- phasesAfter + assert(unmetPreceedeRequirements.isEmpty, + s"phase ${phases(i)} has unmet requirement: ${unmetPreceedeRequirements.mkString(", ")} should precede this phase") + phasesAfter += phases(i).name i += 1 } var lastTransformerId = i @@ -170,6 +188,9 @@ object Phases { def name: String + /** List of names of phases that should precede this phase */ + def runsAfter: Set[String] = Set.empty + def run(implicit ctx: Context): Unit def runOn(units: List[CompilationUnit])(implicit ctx: Context): Unit = diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index d4156e1d7..f6faf3301 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -25,6 +25,9 @@ class Erasure extends Phase with DenotTransformer { override def name: String = "erasure" + /** List of names of phases that should precede this phase */ + override def runsAfter: Set[String] = Set("typeTestsCasts", "intercepted", "splitter") + def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref match { case ref: SymDenotation => assert(ctx.phase == this, s"transforming $ref at ${ctx.phase}") diff --git a/src/dotty/tools/dotc/transform/LazyVals.scala b/src/dotty/tools/dotc/transform/LazyVals.scala index 8ed09b4b2..561f240b1 100644 --- a/src/dotty/tools/dotc/transform/LazyVals.scala +++ b/src/dotty/tools/dotc/transform/LazyVals.scala @@ -63,6 +63,17 @@ class LazyValTranformContext { override def name: String = "LazyVals" + /** List of names of phases that should have finished their processing of all compilation units + * before this phase starts */ + override def runsAfterGroupsOf: Set[String] = Set("lazyValsModules") + /** List of names of phases that should have finished their processing of all compilation units + * before this phase starts */ + override def runsAfter: Set[String] = Set("lazyValsModules") + + /** List of names of phases that should have finished processing of tree + * before this phase starts processing same tree */ + // override def ensureAfter: Set[String] = Set("mixin") + def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = { ref match { case ref: SymDenotation if ref.symbol.isClass => diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala index 0e182a99a..4ed2ebde7 100644 --- a/src/dotty/tools/dotc/transform/TreeTransform.scala +++ b/src/dotty/tools/dotc/transform/TreeTransform.scala @@ -51,6 +51,10 @@ object TreeTransforms { /** id of this treeTransform in group */ var idx: Int = _ + /** List of names of phases that should have finished their processing of all compilation units + * before this phase starts */ + def runsAfterGroupsOf: Set[String] = Set.empty + def prepareForIdent(tree: Ident)(implicit ctx: Context) = this def prepareForSelect(tree: Select)(implicit ctx: Context) = this def prepareForThis(tree: This)(implicit ctx: Context) = this |