From bbad484141e591899f95327e572031ba0de155ec Mon Sep 17 00:00:00 2001 From: Dmitry Petrashko Date: Thu, 3 Apr 2014 11:13:55 +0200 Subject: Allow phases to give restrictions on pipeline position. Phases can now specify which phases should it follow. Tree transforms can additionally specify which TreeTransforms should have finished their processing of compilation units entirely. --- src/dotty/tools/dotc/core/Phases.scala | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src/dotty/tools/dotc/core/Phases.scala') 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 = -- cgit v1.2.3