diff options
author | Martin Odersky <odersky@gmail.com> | 2014-08-09 13:45:29 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-08-09 13:45:29 +0200 |
commit | 57c6c85cbc953a3489ee8d16bb5b7be862183924 (patch) | |
tree | b00bc4ac442e376b9a8da38ca9d5a4039e7630b6 /src | |
parent | 9024f25e78a9fe5d27dd2c30aa24999d8901dab6 (diff) | |
download | dotty-57c6c85cbc953a3489ee8d16bb5b7be862183924.tar.gz dotty-57c6c85cbc953a3489ee8d16bb5b7be862183924.tar.bz2 dotty-57c6c85cbc953a3489ee8d16bb5b7be862183924.zip |
Disentangle phases from treetransforms
TreeTransforms are no longer phases. This allows to generate
new transforms in prepare... methods without running into the
problem that thee new transforms are undefined as phases.
It also makes for a cleaner separation of concerns.
Diffstat (limited to 'src')
18 files changed, 159 insertions, 140 deletions
diff --git a/src/dotty/tools/dotc/ElimLocals.scala b/src/dotty/tools/dotc/ElimLocals.scala index cc971f05c..98da95f61 100644 --- a/src/dotty/tools/dotc/ElimLocals.scala +++ b/src/dotty/tools/dotc/ElimLocals.scala @@ -6,11 +6,11 @@ import DenotTransformers.SymTransformer import Phases.Phase import Contexts.Context import SymDenotations.SymDenotation -import TreeTransforms.TreeTransform +import TreeTransforms.MiniPhaseTransform import Flags.Local /** Widens all private[this] and protected[this] qualifiers to just private/protected */ -class ElimLocals extends TreeTransform with SymTransformer { thisTransformer => +class ElimLocals extends MiniPhaseTransform with SymTransformer { thisTransformer => override def name = "elimlocals" def transformSym(ref: SymDenotation)(implicit ctx: Context) = diff --git a/src/dotty/tools/dotc/core/Decorators.scala b/src/dotty/tools/dotc/core/Decorators.scala index cd7b46896..c96f1ba31 100644 --- a/src/dotty/tools/dotc/core/Decorators.scala +++ b/src/dotty/tools/dotc/core/Decorators.scala @@ -130,7 +130,7 @@ object Decorators { */ implicit class PhaseListDecorator(val names: List[String]) extends AnyVal { def containsPhase(phase: Phase): Boolean = phase match { - case phase: TreeTransformer => phase.transformations.exists(containsPhase) + case phase: TreeTransformer => phase.transformations.exists(trans => containsPhase(trans.phase)) case _ => names exists (n => n == "all" || phase.name.startsWith(n)) } } diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index 5c569bc7f..cecc5d1d7 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -8,7 +8,7 @@ import DenotTransformers._ import Denotations._ import config.Printers._ import scala.collection.mutable.{ListBuffer, ArrayBuffer} -import dotty.tools.dotc.transform.TreeTransforms.{TreeTransformer, TreeTransform} +import dotty.tools.dotc.transform.TreeTransforms.{TreeTransformer, MiniPhase, TreeTransform} import dotty.tools.dotc.transform.TreeTransforms import Periods._ @@ -80,7 +80,7 @@ object Phases { val phasesInBlock: Set[String] = phasess(i).map(_.name).toSet for(phase<-phasess(i)) { phase match { - case p: TreeTransform => + case p: MiniPhase => val unmetRequirements = p.runsAfterGroupsOf &~ prevPhases assert(unmetRequirements.isEmpty, @@ -90,9 +90,9 @@ object Phases { assert(false, s"Only tree transforms can be squashed, ${phase.name} can not be squashed") } } - val transforms = phasess(i).asInstanceOf[List[TreeTransform]] + val transforms = phasess(i).asInstanceOf[List[MiniPhase]].map(_.treeTransform) val block = new TreeTransformer { - override def name: String = transformations.map(_.name).mkString("TreeTransform:{", ", ", "}") + override def name: String = transformations.map(_.phase.name).mkString("TreeTransform:{", ", ", "}") override def transformations: Array[TreeTransform] = transforms.toArray } squashedPhases += block diff --git a/src/dotty/tools/dotc/transform/CollectEntryPoints.scala b/src/dotty/tools/dotc/transform/CollectEntryPoints.scala index 0e9f98e79..d5ae90840 100644 --- a/src/dotty/tools/dotc/transform/CollectEntryPoints.scala +++ b/src/dotty/tools/dotc/transform/CollectEntryPoints.scala @@ -1,6 +1,6 @@ package dotty.tools.dotc.transform -import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform, TreeTransformer} +import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform, TreeTransformer, MiniPhaseTransform} import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Contexts.Context import scala.collection.mutable.ListBuffer @@ -23,7 +23,7 @@ import StdNames._ import dotty.tools.dotc.util.Positions.Position import dotty.tools.dotc.config.JavaPlatform -class CollectEntryPoints extends TreeTransform { +class CollectEntryPoints extends MiniPhaseTransform { /** perform context-dependant initialization */ override def init(implicit ctx: Context, info: TransformerInfo): Unit = { diff --git a/src/dotty/tools/dotc/transform/Constructors.scala b/src/dotty/tools/dotc/transform/Constructors.scala index 4bef41d8f..33d742a17 100644 --- a/src/dotty/tools/dotc/transform/Constructors.scala +++ b/src/dotty/tools/dotc/transform/Constructors.scala @@ -9,7 +9,7 @@ import dotty.tools.dotc.core.StdNames._ * Right now it's a dummy. * Awaiting for real implemetation */ -class Constructors extends TreeTransform { +class Constructors extends MiniPhaseTransform { override def name: String = "constructors" override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = { diff --git a/src/dotty/tools/dotc/transform/ElimRepeated.scala b/src/dotty/tools/dotc/transform/ElimRepeated.scala index 30396eb83..3635a8741 100644 --- a/src/dotty/tools/dotc/transform/ElimRepeated.scala +++ b/src/dotty/tools/dotc/transform/ElimRepeated.scala @@ -4,7 +4,7 @@ package transform import core._ import Names._ import Types._ -import TreeTransforms.{TransformerInfo, TreeTransform, TreeTransformer} +import TreeTransforms.{TransformerInfo, MiniPhaseTransform, TreeTransformer} import ast.Trees.flatten import Flags._ import Contexts.Context @@ -20,7 +20,7 @@ import TypeUtils._ /** A transformer that removes repeated parameters (T*) from all types, replacing * them with Seq types. */ -class ElimRepeated extends TreeTransform with InfoTransformer { thisTransformer => +class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransformer => import ast.tpd._ override def name = "elimrepeated" diff --git a/src/dotty/tools/dotc/transform/FirstTransform.scala b/src/dotty/tools/dotc/transform/FirstTransform.scala index d7010e821..39791918b 100644 --- a/src/dotty/tools/dotc/transform/FirstTransform.scala +++ b/src/dotty/tools/dotc/transform/FirstTransform.scala @@ -3,7 +3,7 @@ package transform import core._ import Names._ -import TreeTransforms.{TransformerInfo, TreeTransform, TreeTransformer} +import TreeTransforms.{TransformerInfo, MiniPhaseTransform, TreeTransformer} import ast.Trees._ import Flags._ import Types._ @@ -23,7 +23,7 @@ import NameOps._ * - checks the bounds of AppliedTypeTrees * - stubs out native methods */ -class FirstTransform extends TreeTransform with IdentityDenotTransformer { thisTransformer => +class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer { thisTransformer => import ast.tpd._ override def name = "companions" diff --git a/src/dotty/tools/dotc/transform/InterceptedMethods.scala b/src/dotty/tools/dotc/transform/InterceptedMethods.scala index 6dd66ec75..a8ca754de 100644 --- a/src/dotty/tools/dotc/transform/InterceptedMethods.scala +++ b/src/dotty/tools/dotc/transform/InterceptedMethods.scala @@ -40,7 +40,7 @@ import StdNames._ * using the most precise overload available * - `x.getClass` for getClass in primitives becomes `x.getClass` with getClass in class Object. */ -class InterceptedMethods extends TreeTransform { +class InterceptedMethods extends MiniPhaseTransform { import tpd._ diff --git a/src/dotty/tools/dotc/transform/LazyVals.scala b/src/dotty/tools/dotc/transform/LazyVals.scala index 02e5ed5a7..75fc7ef2e 100644 --- a/src/dotty/tools/dotc/transform/LazyVals.scala +++ b/src/dotty/tools/dotc/transform/LazyVals.scala @@ -8,7 +8,7 @@ import Symbols._ import Decorators._ import NameOps._ import StdNames.nme -import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransformer, TreeTransform} +import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransformer, MiniPhaseTransform} import dotty.tools.dotc.ast.Trees._ import dotty.tools.dotc.ast.{untpd, tpd} import dotty.tools.dotc.core.Constants.Constant @@ -43,7 +43,7 @@ class LazyValTranformContext { } } - class LazyValsTransform extends TreeTransform with DenotTransformer { + class LazyValsTransform extends MiniPhaseTransform with DenotTransformer { override def name: String = "LazyVals" diff --git a/src/dotty/tools/dotc/transform/Literalize.scala b/src/dotty/tools/dotc/transform/Literalize.scala index 14ce8fd05..03b2b9978 100644 --- a/src/dotty/tools/dotc/transform/Literalize.scala +++ b/src/dotty/tools/dotc/transform/Literalize.scala @@ -15,7 +15,7 @@ import ast.Trees._ * The constant types are eliminated by erasure, so we need to keep * the info about constantness in the trees. */ -class Literalize extends TreeTransform { +class Literalize extends MiniPhaseTransform { import ast.tpd._ override def name: String = "literalize" diff --git a/src/dotty/tools/dotc/transform/Nullarify.scala b/src/dotty/tools/dotc/transform/Nullarify.scala index 8d967cc1a..5756d848a 100644 --- a/src/dotty/tools/dotc/transform/Nullarify.scala +++ b/src/dotty/tools/dotc/transform/Nullarify.scala @@ -34,7 +34,7 @@ import ast.Trees._ * expr ==> () => expr if other expr is an argument to a call-by-name parameter * */ -class Nullarify extends TreeTransform with InfoTransformer { +class Nullarify extends MiniPhaseTransform with InfoTransformer { import ast.tpd._ override def name: String = "nullarify" diff --git a/src/dotty/tools/dotc/transform/PatternMatcher.scala b/src/dotty/tools/dotc/transform/PatternMatcher.scala index 40a157483..373fae12f 100644 --- a/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -16,7 +16,7 @@ import ast.Trees._ /** This transform eliminates patterns. Right now it's a dummy. * Awaiting the real pattern matcher. */ -class PatternMatcher extends TreeTransform { +class PatternMatcher extends MiniPhaseTransform { import ast.tpd._ override def name: String = "patternMatcher" diff --git a/src/dotty/tools/dotc/transform/Splitter.scala b/src/dotty/tools/dotc/transform/Splitter.scala index 921aa1916..6def41419 100644 --- a/src/dotty/tools/dotc/transform/Splitter.scala +++ b/src/dotty/tools/dotc/transform/Splitter.scala @@ -12,7 +12,7 @@ import Contexts._, Types._, Decorators._, Denotations._, Symbols._, SymDenotatio * * For now, only self references are treated. */ -class Splitter extends TreeTransform { +class Splitter extends MiniPhaseTransform { import ast.tpd._ override def name: String = "splitter" diff --git a/src/dotty/tools/dotc/transform/TailRec.scala b/src/dotty/tools/dotc/transform/TailRec.scala index d3bec6f90..e69dd229c 100644 --- a/src/dotty/tools/dotc/transform/TailRec.scala +++ b/src/dotty/tools/dotc/transform/TailRec.scala @@ -10,7 +10,7 @@ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.core._ import dotty.tools.dotc.transform.TailRec._ -import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform} +import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, MiniPhaseTransform} /** * A Tail Rec Transformer @@ -62,7 +62,7 @@ import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform * self recursive functions, that's why it's renamed to tailrec * </p> */ -class TailRec extends TreeTransform with DenotTransformer with FullParameterization { +class TailRec extends MiniPhaseTransform with DenotTransformer with FullParameterization { import dotty.tools.dotc.ast.tpd._ diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala index c39ca90cc..129553264 100644 --- a/src/dotty/tools/dotc/transform/TreeTransform.scala +++ b/src/dotty/tools/dotc/transform/TreeTransform.scala @@ -9,6 +9,7 @@ import dotty.tools.dotc.core.Flags.PackageVal import dotty.tools.dotc.typer.Mode import dotty.tools.dotc.ast.Trees._ import dotty.tools.dotc.core.Decorators._ +import dotty.tools.dotc.util.DotClass import scala.annotation.tailrec import config.Printers.transforms @@ -50,16 +51,13 @@ 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. */ - abstract class TreeTransform extends Phase { + abstract class TreeTransform extends DotClass { + + def phase: MiniPhase /** 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 @@ -136,10 +134,20 @@ object TreeTransforms { /** perform context-dependant initialization */ def init(implicit ctx: Context, info: TransformerInfo): Unit = {} + } + + /** A phase that defines a TreeTransform to be used in a group */ + trait MiniPhase extends Phase { thisPhase => + def treeTransform: TreeTransform + + /** 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 protected def mkTreeTransformer = new TreeTransformer { - override def name: String = TreeTransform.this.name - override def transformations = Array(TreeTransform.this) + override def name: String = thisPhase.name + override def transformations = Array(treeTransform) } override def run(implicit ctx: Context): Unit = { @@ -147,16 +155,23 @@ object TreeTransforms { } } + /** A mini phase that is its own tree transform */ + abstract class MiniPhaseTransform extends TreeTransform with MiniPhase { + def treeTransform = this + def phase = this + } + val NoTransform = new TreeTransform { - override def name: String = "NoTransform" + def phase = unsupported("phase") idx = -1 } - class Separator extends TreeTransform { - override def name: String = "Separator" +/* disabled; not needed anywhere + class Separator extends TreeTransform(phaseId) { + //override def name: String = "Separator" idx = -1 } - +*/ type Mutator[T] = (TreeTransform, T, Context) => TreeTransform class TransformerInfo(val transformers: Array[TreeTransform], val nx: NXTransformations, val group: TreeTransformer) @@ -446,7 +461,7 @@ object TreeTransforms { var allDone = i < l while (i < l) { val oldTransform = result(i) - val newTransform = mutator(oldTransform, tree, ctx.withPhase(oldTransform)) + val newTransform = mutator(oldTransform, tree, ctx.withPhase(oldTransform.phase)) allDone = allDone && (newTransform eq NoTransform) if (!(oldTransform eq newTransform)) { if (!transformersCopied) result = result.clone() @@ -511,7 +526,7 @@ object TreeTransforms { final private[TreeTransforms] def goIdent(tree: Ident, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformIdent(tree)(ctx.withPhase(trans), info) match { + trans.transformIdent(tree)(ctx.withPhase(trans.phase), info) match { case t: Ident => goIdent(t, info.nx.nxTransIdent(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -522,7 +537,7 @@ object TreeTransforms { final private[TreeTransforms] def goSelect(tree: Select, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformSelect(tree)(ctx.withPhase(trans), info) match { + trans.transformSelect(tree)(ctx.withPhase(trans.phase), info) match { case t: Select => goSelect(t, info.nx.nxTransSelect(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -533,7 +548,7 @@ object TreeTransforms { final private[TreeTransforms] def goThis(tree: This, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformThis(tree)(ctx.withPhase(trans), info) match { + trans.transformThis(tree)(ctx.withPhase(trans.phase), info) match { case t: This => goThis(t, info.nx.nxTransThis(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -544,7 +559,7 @@ object TreeTransforms { final private[TreeTransforms] def goSuper(tree: Super, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformSuper(tree)(ctx.withPhase(trans), info) match { + trans.transformSuper(tree)(ctx.withPhase(trans.phase), info) match { case t: Super => goSuper(t, info.nx.nxTransSuper(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -555,7 +570,7 @@ object TreeTransforms { final private[TreeTransforms] def goApply(tree: Apply, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformApply(tree)(ctx.withPhase(trans), info) match { + trans.transformApply(tree)(ctx.withPhase(trans.phase), info) match { case t: Apply => goApply(t, info.nx.nxTransApply(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -566,7 +581,7 @@ object TreeTransforms { final private[TreeTransforms] def goTypeApply(tree: TypeApply, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformTypeApply(tree)(ctx.withPhase(trans), info) match { + trans.transformTypeApply(tree)(ctx.withPhase(trans.phase), info) match { case t: TypeApply => goTypeApply(t, info.nx.nxTransTypeApply(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -577,7 +592,7 @@ object TreeTransforms { final private[TreeTransforms] def goNew(tree: New, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformNew(tree)(ctx.withPhase(trans), info) match { + trans.transformNew(tree)(ctx.withPhase(trans.phase), info) match { case t: New => goNew(t, info.nx.nxTransNew(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -588,7 +603,7 @@ object TreeTransforms { final private[TreeTransforms] def goPair(tree: Pair, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformPair(tree)(ctx.withPhase(trans), info) match { + trans.transformPair(tree)(ctx.withPhase(trans.phase), info) match { case t: Pair => goPair(t, info.nx.nxTransPair(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -599,7 +614,7 @@ object TreeTransforms { final private[TreeTransforms] def goTyped(tree: Typed, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformTyped(tree)(ctx.withPhase(trans), info) match { + trans.transformTyped(tree)(ctx.withPhase(trans.phase), info) match { case t: Typed => goTyped(t, info.nx.nxTransTyped(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -610,7 +625,7 @@ object TreeTransforms { final private[TreeTransforms] def goAssign(tree: Assign, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformAssign(tree)(ctx.withPhase(trans), info) match { + trans.transformAssign(tree)(ctx.withPhase(trans.phase), info) match { case t: Assign => goAssign(t, info.nx.nxTransAssign(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -621,7 +636,7 @@ object TreeTransforms { final private[TreeTransforms] def goLiteral(tree: Literal, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformLiteral(tree)(ctx.withPhase(trans), info) match { + trans.transformLiteral(tree)(ctx.withPhase(trans.phase), info) match { case t: Literal => goLiteral(t, info.nx.nxTransLiteral(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -632,7 +647,7 @@ object TreeTransforms { final private[TreeTransforms] def goBlock(tree: Block, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformBlock(tree)(ctx.withPhase(trans), info) match { + trans.transformBlock(tree)(ctx.withPhase(trans.phase), info) match { case t: Block => goBlock(t, info.nx.nxTransBlock(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -643,7 +658,7 @@ object TreeTransforms { final private[TreeTransforms] def goIf(tree: If, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformIf(tree)(ctx.withPhase(trans), info) match { + trans.transformIf(tree)(ctx.withPhase(trans.phase), info) match { case t: If => goIf(t, info.nx.nxTransIf(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -654,7 +669,7 @@ object TreeTransforms { final private[TreeTransforms] def goClosure(tree: Closure, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformClosure(tree)(ctx.withPhase(trans), info) match { + trans.transformClosure(tree)(ctx.withPhase(trans.phase), info) match { case t: Closure => goClosure(t, info.nx.nxTransClosure(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -665,7 +680,7 @@ object TreeTransforms { final private[TreeTransforms] def goMatch(tree: Match, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformMatch(tree)(ctx.withPhase(trans), info) match { + trans.transformMatch(tree)(ctx.withPhase(trans.phase), info) match { case t: Match => goMatch(t, info.nx.nxTransMatch(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -676,7 +691,7 @@ object TreeTransforms { final private[TreeTransforms] def goCaseDef(tree: CaseDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformCaseDef(tree)(ctx.withPhase(trans), info) match { + trans.transformCaseDef(tree)(ctx.withPhase(trans.phase), info) match { case t: CaseDef => goCaseDef(t, info.nx.nxTransCaseDef(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -687,7 +702,7 @@ object TreeTransforms { final private[TreeTransforms] def goReturn(tree: Return, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformReturn(tree)(ctx.withPhase(trans), info) match { + trans.transformReturn(tree)(ctx.withPhase(trans.phase), info) match { case t: Return => goReturn(t, info.nx.nxTransReturn(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -698,7 +713,7 @@ object TreeTransforms { final private[TreeTransforms] def goTry(tree: Try, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformTry(tree)(ctx.withPhase(trans), info) match { + trans.transformTry(tree)(ctx.withPhase(trans.phase), info) match { case t: Try => goTry(t, info.nx.nxTransTry(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -709,7 +724,7 @@ object TreeTransforms { final private[TreeTransforms] def goThrow(tree: Throw, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformThrow(tree)(ctx.withPhase(trans), info) match { + trans.transformThrow(tree)(ctx.withPhase(trans.phase), info) match { case t: Throw => goThrow(t, info.nx.nxTransThrow(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -720,7 +735,7 @@ object TreeTransforms { final private[TreeTransforms] def goSeqLiteral(tree: SeqLiteral, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformSeqLiteral(tree)(ctx.withPhase(trans), info) match { + trans.transformSeqLiteral(tree)(ctx.withPhase(trans.phase), info) match { case t: SeqLiteral => goSeqLiteral(t, info.nx.nxTransSeqLiteral(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -731,7 +746,7 @@ object TreeTransforms { final private[TreeTransforms] def goTypeTree(tree: TypeTree, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformTypeTree(tree)(ctx.withPhase(trans), info) match { + trans.transformTypeTree(tree)(ctx.withPhase(trans.phase), info) match { case t: TypeTree => goTypeTree(t, info.nx.nxTransTypeTree(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -742,7 +757,7 @@ object TreeTransforms { final private[TreeTransforms] def goSelectFromTypeTree(tree: SelectFromTypeTree, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformSelectFromTypeTree(tree)(ctx.withPhase(trans), info) match { + trans.transformSelectFromTypeTree(tree)(ctx.withPhase(trans.phase), info) match { case t: SelectFromTypeTree => goSelectFromTypeTree(t, info.nx.nxTransSelectFromTypeTree(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -753,7 +768,7 @@ object TreeTransforms { final private[TreeTransforms] def goBind(tree: Bind, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformBind(tree)(ctx.withPhase(trans), info) match { + trans.transformBind(tree)(ctx.withPhase(trans.phase), info) match { case t: Bind => goBind(t, info.nx.nxTransBind(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -764,7 +779,7 @@ object TreeTransforms { final private[TreeTransforms] def goAlternative(tree: Alternative, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformAlternative(tree)(ctx.withPhase(trans), info) match { + trans.transformAlternative(tree)(ctx.withPhase(trans.phase), info) match { case t: Alternative => goAlternative(t, info.nx.nxTransAlternative(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -775,7 +790,7 @@ object TreeTransforms { final private[TreeTransforms] def goValDef(tree: ValDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformValDef(tree)(ctx.withPhase(trans), info) match { + trans.transformValDef(tree)(ctx.withPhase(trans.phase), info) match { case t: ValDef => goValDef(t, info.nx.nxTransValDef(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -786,7 +801,7 @@ object TreeTransforms { final private[TreeTransforms] def goDefDef(tree: DefDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformDefDef(tree)(ctx.withPhase(trans), info) match { + trans.transformDefDef(tree)(ctx.withPhase(trans.phase), info) match { case t: DefDef => goDefDef(t, info.nx.nxTransDefDef(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -797,7 +812,7 @@ object TreeTransforms { final private[TreeTransforms] def goUnApply(tree: UnApply, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformUnApply(tree)(ctx.withPhase(trans), info) match { + trans.transformUnApply(tree)(ctx.withPhase(trans.phase), info) match { case t: UnApply => goUnApply(t, info.nx.nxTransUnApply(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -808,7 +823,7 @@ object TreeTransforms { final private[TreeTransforms] def goTypeDef(tree: TypeDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformTypeDef(tree)(ctx.withPhase(trans), info) match { + trans.transformTypeDef(tree)(ctx.withPhase(trans.phase), info) match { case t: TypeDef => goTypeDef(t, info.nx.nxTransTypeDef(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -819,7 +834,7 @@ object TreeTransforms { final private[TreeTransforms] def goTemplate(tree: Template, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformTemplate(tree)(ctx.withPhase(trans), info) match { + trans.transformTemplate(tree)(ctx.withPhase(trans.phase), info) match { case t: Template => goTemplate(t, info.nx.nxTransTemplate(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -830,7 +845,7 @@ object TreeTransforms { final private[TreeTransforms] def goPackageDef(tree: PackageDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - trans.transformPackageDef(tree)(ctx.withPhase(trans), info) match { + trans.transformPackageDef(tree)(ctx.withPhase(trans.phase), info) match { case t: PackageDef => goPackageDef(t, info.nx.nxTransPackageDef(cur + 1)) case t => transformSingle(t, cur + 1) } @@ -840,7 +855,7 @@ object TreeTransforms { final private[TreeTransforms] def goOther(tree: Tree, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = { if (cur < info.transformers.length) { val trans = info.transformers(cur) - val t = trans.transformOther(tree)(ctx.withPhase(trans), info) + val t = trans.transformOther(tree)(ctx.withPhase(trans.phase), info) transformSingle(t, cur + 1) } else tree } @@ -1151,8 +1166,8 @@ object TreeTransforms { def transform(tree: Tree, info: TransformerInfo, cur: Int)(implicit ctx: Context): Tree = ctx.traceIndented(s"transforming ${tree.show} at ${ctx.phase}", transforms, show = true) { if (cur < info.transformers.length) { // if cur > 0 then some of the symbols can be created by already performed transformations - // this means that their denotations could not exists in previous periods - val pctx = ctx.withPhase(info.transformers(cur)) + // this means that their denotations could not exists in previous period + val pctx = ctx.withPhase(info.transformers(cur).phase) tree match { //split one big match into 2 smaller ones case tree: NameTree => transformNamed(tree, info, cur)(pctx) diff --git a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index b209f7647..dbdb5c902 100644 --- a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -21,7 +21,7 @@ import Erasure.Boxing.box * - have a reference type as receiver * - can be translated directly to machine instructions */ -class TypeTestsCasts extends TreeTransform { +class TypeTestsCasts extends MiniPhaseTransform { import ast.tpd._ override def name: String = "typeTestsCasts" diff --git a/src/dotty/tools/dotc/transform/UncurryTreeTransform.scala b/src/dotty/tools/dotc/transform/UncurryTreeTransform.scala index ccfaaa0dc..f2d8d4d4a 100644 --- a/src/dotty/tools/dotc/transform/UncurryTreeTransform.scala +++ b/src/dotty/tools/dotc/transform/UncurryTreeTransform.scala @@ -11,7 +11,7 @@ import core.Symbols._ import ast.Trees._ import ast.tpd.{Apply, Tree, cpy} -class UncurryTreeTransform extends TreeTransform with InfoTransformer { +class UncurryTreeTransform extends MiniPhaseTransform with InfoTransformer { override def name: String = "uncurry" override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = diff --git a/src/dotty/tools/dotc/typer/RefChecks.scala b/src/dotty/tools/dotc/typer/RefChecks.scala index a9b0f41ae..23a810638 100644 --- a/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/src/dotty/tools/dotc/typer/RefChecks.scala @@ -665,92 +665,96 @@ import RefChecks._ * if (false) A else B --> B * - macro definitions are eliminated. */ -class RefChecks(currentLevel: RefChecks.OptLevelInfo = RefChecks.NoLevelInfo) extends TreeTransform with IdentityDenotTransformer { thisTransformer => +class RefChecks extends MiniPhase with IdentityDenotTransformer { thisTransformer => import tpd._ - /** the following two members override abstract members in Transform */ val name: String = "refchecks" - override def prepareForStats(trees: List[Tree])(implicit ctx: Context) = { - println(i"preparing for $trees%; %, owner = ${ctx.owner}") - if (ctx.owner.isTerm) new RefChecks(new LevelInfo(currentLevel.levelAndIndex, trees)) - else this - } + val treeTransform = new Transform(NoLevelInfo) - override def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] = trees + class Transform(currentLevel: RefChecks.OptLevelInfo = RefChecks.NoLevelInfo) extends TreeTransform { + def phase = thisTransformer + override def prepareForStats(trees: List[Tree])(implicit ctx: Context) = { + println(i"preparing for $trees%; %, owner = ${ctx.owner}") + if (ctx.owner.isTerm) new Transform(new LevelInfo(currentLevel.levelAndIndex, trees)) + else this + } - override def transformValDef(tree: ValDef)(implicit ctx: Context, info: TransformerInfo) = { - checkDeprecatedOvers(tree) - val sym = tree.symbol - if (sym.exists && sym.owner.isTerm && !sym.is(Lazy)) - currentLevel.levelAndIndex.get(sym) match { - case Some((level, symIdx)) if symIdx < level.maxIndex => - ctx.debuglog("refsym = " + level.refSym) - ctx.error(s"forward reference extends over definition of $sym", level.refPos) - case _ => - } - tree - } + override def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] = trees - override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo) = { - checkDeprecatedOvers(tree) - if (tree.symbol is Macro) EmptyTree else tree - } + override def transformValDef(tree: ValDef)(implicit ctx: Context, info: TransformerInfo) = { + checkDeprecatedOvers(tree) + val sym = tree.symbol + if (sym.exists && sym.owner.isTerm && !sym.is(Lazy)) + currentLevel.levelAndIndex.get(sym) match { + case Some((level, symIdx)) if symIdx < level.maxIndex => + ctx.debuglog("refsym = " + level.refSym) + ctx.error(s"forward reference extends over definition of $sym", level.refPos) + case _ => + } + tree + } - override def transformTemplate(tree: Template)(implicit ctx: Context, info: TransformerInfo) = { - val cls = ctx.owner - checkOverloadedRestrictions(cls) - checkAllOverrides(cls) - checkAnyValSubclass(cls) - if (cls.isDerivedValueClass) - cls.primaryConstructor.makeNotPrivateAfter(NoSymbol, thisTransformer) // SI-6601, must be done *after* pickler! - tree - } + override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo) = { + checkDeprecatedOvers(tree) + if (tree.symbol is Macro) EmptyTree else tree + } - override def transformTypeTree(tree: TypeTree)(implicit ctx: Context, info: TransformerInfo) = { - if (!tree.original.isEmpty) - tree.tpe.foreachPart { - case tp: NamedType => checkUndesiredProperties(tp.symbol, tree.pos) - case _ => - } - tree - } + override def transformTemplate(tree: Template)(implicit ctx: Context, info: TransformerInfo) = { + val cls = ctx.owner + checkOverloadedRestrictions(cls) + checkAllOverrides(cls) + checkAnyValSubclass(cls) + if (cls.isDerivedValueClass) + cls.primaryConstructor.makeNotPrivateAfter(NoSymbol, thisTransformer) // SI-6601, must be done *after* pickler! + tree + } - override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = { - assert(ctx.phase.exists) - checkUndesiredProperties(tree.symbol, tree.pos) - currentLevel.enterReference(tree.symbol, tree.pos) - tree - } + override def transformTypeTree(tree: TypeTree)(implicit ctx: Context, info: TransformerInfo) = { + if (!tree.original.isEmpty) + tree.tpe.foreachPart { + case tp: NamedType => checkUndesiredProperties(tp.symbol, tree.pos) + case _ => + } + tree + } - override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) = { - checkUndesiredProperties(tree.symbol, tree.pos) - tree - } + override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = { + assert(ctx.phase.exists) + checkUndesiredProperties(tree.symbol, tree.pos) + currentLevel.enterReference(tree.symbol, tree.pos) + tree + } - override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo) = { - if (isSelfConstrCall(tree)) { - assert(currentLevel.isInstanceOf[LevelInfo], ctx.owner+"/"+i"$tree") - val level = currentLevel.asInstanceOf[LevelInfo] - if (level.maxIndex > 0) { - // An implementation restriction to avoid VerifyErrors and lazyvals mishaps; see SI-4717 - ctx.debuglog("refsym = " + level.refSym) - ctx.error("forward reference not allowed from self constructor invocation", level.refPos) - } + override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) = { + checkUndesiredProperties(tree.symbol, tree.pos) + tree } - tree - } - override def transformIf(tree: If)(implicit ctx: Context, info: TransformerInfo) = - tree.cond.tpe match { - case ConstantType(value) => if (value.booleanValue) tree.thenp else tree.elsep - case _ => tree + override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo) = { + if (isSelfConstrCall(tree)) { + assert(currentLevel.isInstanceOf[LevelInfo], ctx.owner + "/" + i"$tree") + val level = currentLevel.asInstanceOf[LevelInfo] + if (level.maxIndex > 0) { + // An implementation restriction to avoid VerifyErrors and lazyvals mishaps; see SI-4717 + ctx.debuglog("refsym = " + level.refSym) + ctx.error("forward reference not allowed from self constructor invocation", level.refPos) + } + } + tree } - override def transformNew(tree: New)(implicit ctx: Context, info: TransformerInfo) = { - currentLevel.enterReference(tree.tpe.typeSymbol, tree.pos) - tree + override def transformIf(tree: If)(implicit ctx: Context, info: TransformerInfo) = + tree.cond.tpe match { + case ConstantType(value) => if (value.booleanValue) tree.thenp else tree.elsep + case _ => tree + } + + override def transformNew(tree: New)(implicit ctx: Context, info: TransformerInfo) = { + currentLevel.enterReference(tree.tpe.typeSymbol, tree.pos) + tree + } } } |