aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
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
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')
-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