aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Phases.scala
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2014-04-03 11:13:55 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-04-09 16:38:52 +0200
commitbbad484141e591899f95327e572031ba0de155ec (patch)
tree5fc13db5632d21d2ab0aa4d8561e94501abbbd99 /src/dotty/tools/dotc/core/Phases.scala
parentc8feb0ccb543b01ac27da788050b12c0a0221e36 (diff)
downloaddotty-bbad484141e591899f95327e572031ba0de155ec.tar.gz
dotty-bbad484141e591899f95327e572031ba0de155ec.tar.bz2
dotty-bbad484141e591899f95327e572031ba0de155ec.zip
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.
Diffstat (limited to 'src/dotty/tools/dotc/core/Phases.scala')
-rw-r--r--src/dotty/tools/dotc/core/Phases.scala23
1 files changed, 22 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 =