aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/TreeTransform.scala
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2014-03-17 22:25:47 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-03-19 15:53:47 +0100
commit09d02bd3670b947da147aec40835822d894b17b0 (patch)
tree01e81ad97df8b0e3e59cb72b3b77893e1d6f1070 /src/dotty/tools/dotc/transform/TreeTransform.scala
parent5cbd2fbc8409b446f8751792b006693e1d091055 (diff)
downloaddotty-09d02bd3670b947da147aec40835822d894b17b0.tar.gz
dotty-09d02bd3670b947da147aec40835822d894b17b0.tar.bz2
dotty-09d02bd3670b947da147aec40835822d894b17b0.zip
Allow MiniPhase to be DenotTransformer
All MiniPhases now as are full-fledged phases, and are given their own periods and can register DenotTransformers. MiniPhases belonging to same group(list) will be squashed to single phase.
Diffstat (limited to 'src/dotty/tools/dotc/transform/TreeTransform.scala')
-rw-r--r--src/dotty/tools/dotc/transform/TreeTransform.scala148
1 files changed, 104 insertions, 44 deletions
diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala
index 3e29af0e4..6455b6062 100644
--- a/src/dotty/tools/dotc/transform/TreeTransform.scala
+++ b/src/dotty/tools/dotc/transform/TreeTransform.scala
@@ -46,7 +46,10 @@ object TreeTransforms {
* (4) chain 7 out of 20 transformations over the resulting tree node. I believe the current algorithm is suitable
* for achieving this goal, but there can be no wasted cycles anywhere.
*/
- class TreeTransform(group: TreeTransformer, idx: Int) {
+ abstract class TreeTransform extends Phase {
+
+ /** id of this treeTransform in group */
+ var idx: Int = _
def prepareForIdent(tree: Ident) = this
def prepareForSelect(tree: Select) = this
@@ -100,7 +103,7 @@ object TreeTransforms {
def transformTry(tree: Try)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformThrow(tree: Throw)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformSeqLiteral(tree: SeqLiteral)(implicit ctx: Context, info: TransformerInfo): Tree = tree
- def transformTypeTree(tree: TypeTree)(implicit ctx: Context): Tree = tree
+ def transformTypeTree(tree: TypeTree)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformSelectFromTypeTree(tree: SelectFromTypeTree)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformBind(tree: Bind)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformAlternative(tree: Alternative)(implicit ctx: Context, info: TransformerInfo): Tree = tree
@@ -113,23 +116,42 @@ object TreeTransforms {
def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] = trees
/** Transform tree using all transforms of current group (including this one) */
- def transform(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = group.transform(tree, info, 0)
+ def transform(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = info.group.transform(tree, info, 0)
/** Transform subtree using all transforms following the current one in this group */
- def transformFollowingDeep(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = group.transform(tree, info, idx + 1)
+ def transformFollowingDeep(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = info.group.transform(tree, info, idx + 1)
/** Transform single node using all transforms following the current one in this group */
- def transformFollowing(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = group.transformSingle(tree, idx + 1)
+ def transformFollowing(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = info.group.transformSingle(tree, idx + 1)
/** perform context-dependant initialization */
- def init(implicit ctx:Context): Unit = {}
+ def init(implicit ctx:Context, info: TransformerInfo): Unit = {}
+
+ protected def mkTreeTransformer = new TreeTransformer {
+ override def name: String = TreeTransform.this.name
+ override protected def transformations = Array(TreeTransform.this)
+ }
+
+ override def run(implicit ctx: Context): Unit = {
+ mkTreeTransformer.run
+ }
}
- val NoTransform = new TreeTransform(null, -1)
+ val NoTransform = new TreeTransform {
+ override def name: String = "NoTransform"
+ idx = -1
+ }
+
+ class Separator extends TreeTransform {
+ override def name: String = "Separator"
+ idx = -1
+ }
type Mutator[T] = (TreeTransform, T) => TreeTransform
- class TransformerInfo(val transformers: Array[TreeTransform], val nx: NXTransformations) {}
+ class TransformerInfo(val transformers: Array[TreeTransform], val nx: NXTransformations, val group:TreeTransformer, val contexts:Array[Context]) {
+ assert(transformers.size == contexts.size)
+ }
/**
* This class maintains track of which methods are redefined in MiniPhases and creates execution plans for transformXXX and prepareXXX
@@ -392,7 +414,7 @@ object TreeTransforms {
/** A group of tree transforms that are applied in sequence during the same phase */
abstract class TreeTransformer extends Phase {
- protected def transformations: Array[(TreeTransformer, Int) => TreeTransform]
+ protected def transformations: Array[TreeTransform]
override def run(implicit ctx: Context): Unit = {
val curTree = ctx.compilationUnit.tpdTree
@@ -425,7 +447,7 @@ object TreeTransforms {
}
if (allDone) null
else if (!transformersCopied) info
- else new TransformerInfo(result, resultNX)
+ else new TransformerInfo(result, resultNX, info.group, info.contexts)
}
val prepForIdent: Mutator[Ident] = (trans, tree) => trans.prepareForIdent(tree)
@@ -461,15 +483,23 @@ object TreeTransforms {
val prepForStats: Mutator[List[Tree]]= (trans, trees) => trans.prepareForStats(trees)
def transform(t: Tree)(implicit ctx: Context): Tree = {
- val initialTransformations = transformations.zipWithIndex.map(x => x._1(this, x._2))
- initialTransformations.foreach(_.init)
- transform(t, new TransformerInfo(initialTransformations, new NXTransformations(initialTransformations)), 0)
+ val initialTransformations = transformations
+ val contexts = initialTransformations.map(tr => ctx.fresh.withPhase(tr).ctx)
+ val info = new TransformerInfo(initialTransformations, new NXTransformations(initialTransformations), this, contexts)
+ initialTransformations.zipWithIndex.foreach{
+ case (transform, id) =>
+ transform.idx = id
+ transform.init(ctx, info)
+ }
+ transform(t, info, 0)
}
@tailrec
final private[TreeTransforms] def goIdent(tree: Ident, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformIdent(tree) match {
+ val trans = info.transformers(cur)
+
+ trans.transformIdent(tree)(info.contexts(cur), info) match {
case t: Ident => goIdent(t, info.nx.nxTransIdent(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -479,7 +509,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goSelect(tree: Select, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformSelect(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformSelect(tree)(info.contexts(cur), info) match {
case t: Select => goSelect(t, info.nx.nxTransSelect(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -489,7 +520,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goThis(tree: This, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformThis(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformThis(tree)(info.contexts(cur), info) match {
case t: This => goThis(t, info.nx.nxTransThis(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -499,7 +531,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goSuper(tree: Super, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformSuper(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformSuper(tree)(info.contexts(cur), info) match {
case t: Super => goSuper(t, info.nx.nxTransSuper(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -509,7 +542,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goApply(tree: Apply, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformApply(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformApply(tree)(info.contexts(cur), info) match {
case t: Apply => goApply(t, info.nx.nxTransApply(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -519,7 +553,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTypeApply(tree: TypeApply, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTypeApply(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTypeApply(tree)(info.contexts(cur), info) match {
case t: TypeApply => goTypeApply(t, info.nx.nxTransTypeApply(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -529,7 +564,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goNew(tree: New, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformNew(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformNew(tree)(info.contexts(cur), info) match {
case t: New => goNew(t, info.nx.nxTransNew(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -539,7 +575,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goPair(tree: Pair, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformPair(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformPair(tree)(info.contexts(cur), info) match {
case t: Pair => goPair(t, info.nx.nxTransPair(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -549,7 +586,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTyped(tree: Typed, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTyped(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTyped(tree)(info.contexts(cur), info) match {
case t: Typed => goTyped(t, info.nx.nxTransTyped(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -559,7 +597,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goAssign(tree: Assign, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformAssign(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformAssign(tree)(info.contexts(cur), info) match {
case t: Assign => goAssign(t, info.nx.nxTransAssign(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -569,7 +608,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goLiteral(tree: Literal, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformLiteral(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformLiteral(tree)(info.contexts(cur), info) match {
case t: Literal => goLiteral(t, info.nx.nxTransLiteral(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -579,7 +619,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goBlock(tree: Block, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformBlock(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformBlock(tree)(info.contexts(cur), info) match {
case t: Block => goBlock(t, info.nx.nxTransBlock(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -589,7 +630,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goIf(tree: If, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformIf(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformIf(tree)(info.contexts(cur), info) match {
case t: If => goIf(t, info.nx.nxTransIf(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -599,7 +641,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goClosure(tree: Closure, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformClosure(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformClosure(tree)(info.contexts(cur), info) match {
case t: Closure => goClosure(t, info.nx.nxTransClosure(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -609,7 +652,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goMatch(tree: Match, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformMatch(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformMatch(tree)(info.contexts(cur), info) match {
case t: Match => goMatch(t, info.nx.nxTransMatch(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -619,7 +663,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goCaseDef(tree: CaseDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformCaseDef(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformCaseDef(tree)(info.contexts(cur), info) match {
case t: CaseDef => goCaseDef(t, info.nx.nxTransCaseDef(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -629,7 +674,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goReturn(tree: Return, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformReturn(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformReturn(tree)(info.contexts(cur), info) match {
case t: Return => goReturn(t, info.nx.nxTransReturn(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -639,7 +685,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTry(tree: Try, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTry(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTry(tree)(info.contexts(cur), info) match {
case t: Try => goTry(t, info.nx.nxTransTry(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -649,7 +696,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goThrow(tree: Throw, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformThrow(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformThrow(tree)(info.contexts(cur), info) match {
case t: Throw => goThrow(t, info.nx.nxTransThrow(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -659,7 +707,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goSeqLiteral(tree: SeqLiteral, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformSeqLiteral(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformSeqLiteral(tree)(info.contexts(cur), info) match {
case t: SeqLiteral => goSeqLiteral(t, info.nx.nxTransSeqLiteral(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -669,7 +718,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTypeTree(tree: TypeTree, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTypeTree(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTypeTree(tree)(info.contexts(cur), info) match {
case t: TypeTree => goTypeTree(t, info.nx.nxTransTypeTree(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -679,7 +729,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goSelectFromTypeTree(tree: SelectFromTypeTree, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformSelectFromTypeTree(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformSelectFromTypeTree(tree)(info.contexts(cur), info) match {
case t: SelectFromTypeTree => goSelectFromTypeTree(t, info.nx.nxTransSelectFromTypeTree(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -689,7 +740,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goBind(tree: Bind, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformBind(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformBind(tree)(info.contexts(cur), info) match {
case t: Bind => goBind(t, info.nx.nxTransBind(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -699,7 +751,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goAlternative(tree: Alternative, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformAlternative(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformAlternative(tree)(info.contexts(cur), info) match {
case t: Alternative => goAlternative(t, info.nx.nxTransAlternative(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -709,7 +762,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goValDef(tree: ValDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformValDef(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformValDef(tree)(info.contexts(cur), info) match {
case t: ValDef => goValDef(t, info.nx.nxTransValDef(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -719,7 +773,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goDefDef(tree: DefDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformDefDef(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformDefDef(tree)(info.contexts(cur), info) match {
case t: DefDef => goDefDef(t, info.nx.nxTransDefDef(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -729,7 +784,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goUnApply(tree: UnApply, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformUnApply(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformUnApply(tree)(info.contexts(cur), info) match {
case t: UnApply => goUnApply(t, info.nx.nxTransUnApply(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -739,7 +795,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTypeDef(tree: TypeDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTypeDef(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTypeDef(tree)(info.contexts(cur), info) match {
case t: TypeDef => goTypeDef(t, info.nx.nxTransTypeDef(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -749,7 +806,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTemplate(tree: Template, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTemplate(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTemplate(tree)(info.contexts(cur), info) match {
case t: Template => goTemplate(t, info.nx.nxTransTemplate(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -759,7 +817,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goPackageDef(tree: PackageDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformPackageDef(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformPackageDef(tree)(info.contexts(cur), info) match {
case t: PackageDef => goPackageDef(t, info.nx.nxTransPackageDef(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -1069,7 +1128,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goStats(trees: List[Tree], cur: Int)(implicit ctx: Context, info: TransformerInfo): List[Tree] = {
if (cur < info.transformers.length) {
- val stats = info.transformers(cur).transformStats(trees)
+ val trans = info.transformers(cur)
+ val stats = trans.transformStats(trees)
goStats(stats, info.nx.nxTransStats(cur + 1))
} else trees
}