aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/Phases.scala23
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala3
-rw-r--r--src/dotty/tools/dotc/transform/LazyVals.scala11
-rw-r--r--src/dotty/tools/dotc/transform/TreeTransform.scala4
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