diff --git a/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala b/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala
index bd3a1894c2cc..41b7e549d2f5 100644
--- a/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala
+++ b/compiler/src/dotty/tools/backend/jvm/CollectEntryPoints.scala
@@ -3,7 +3,7 @@ package dotty.tools.backend.jvm
import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Types
-import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform, MiniPhase, MiniPhaseTransform}
+import dotty.tools.dotc.transform.MegaPhase._
import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc
import dotty.tools.dotc.backend.jvm.DottyPrimitives
@@ -35,10 +35,10 @@ import StdNames.nme
/**
* Created by dark on 26/11/14.
*/
-class CollectEntryPoints extends MiniPhaseTransform {
+class CollectEntryPoints extends MiniPhase {
def phaseName: String = "Collect entry points"
- override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = {
if ((tree.symbol ne NoSymbol) && CollectEntryPoints.isJavaEntryPoint(tree.symbol)) {
ctx.genBCodePhase.asInstanceOf[GenBCode].registerEntryPoint(tree.symbol)
}
diff --git a/compiler/src/dotty/tools/backend/jvm/CollectSuperCalls.scala b/compiler/src/dotty/tools/backend/jvm/CollectSuperCalls.scala
index 8285bfe4b5e9..cabc51c394bf 100644
--- a/compiler/src/dotty/tools/backend/jvm/CollectSuperCalls.scala
+++ b/compiler/src/dotty/tools/backend/jvm/CollectSuperCalls.scala
@@ -5,7 +5,7 @@ import dotty.tools.dotc.ast.Trees._
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Symbols._
import dotty.tools.dotc.core.Flags.Trait
-import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import dotty.tools.dotc.transform.MegaPhase.MiniPhase
/** Collect all super calls to trait members.
*
@@ -17,12 +17,12 @@ import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, Transforme
* methods in a redundant mixin class could be implemented with a default abstract method,
* the redundant mixin class could be required as a parent by the JVM.
*/
-class CollectSuperCalls extends MiniPhaseTransform {
+class CollectSuperCalls extends MiniPhase {
import tpd._
def phaseName: String = "collectSuperCalls"
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformSelect(tree: Select)(implicit ctx: Context): Tree = {
tree.qualifier match {
case sup: Super =>
if (tree.symbol.owner.is(Trait))
diff --git a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala
index eabe1d3b0c3b..a70953ab478f 100644
--- a/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala
+++ b/compiler/src/dotty/tools/backend/jvm/LabelDefs.scala
@@ -4,7 +4,7 @@ import dotty.tools.dotc.ast.Trees.Thicket
import dotty.tools.dotc.ast.{Trees, tpd}
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Types
-import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform, MiniPhase, MiniPhaseTransform}
+import dotty.tools.dotc.transform.MegaPhase._
import dotty.tools.dotc
import dotty.tools.dotc.backend.jvm.DottyPrimitives
import dotty.tools.dotc.core.Flags.FlagSet
@@ -81,14 +81,14 @@ import StdNames.nme
*
* @author Dmitry Petrashko
*/
-class LabelDefs extends MiniPhaseTransform {
+class LabelDefs extends MiniPhase {
def phaseName: String = "labelDef"
val queue = new ArrayBuffer[Tree]()
val beingAppended = new mutable.HashSet[Symbol]()
var labelLevel = 0
- override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = {
if (tree.symbol is Flags.Label) tree
else {
collectLabelDefs.clear
diff --git a/compiler/src/dotty/tools/dotc/Compiler.scala b/compiler/src/dotty/tools/dotc/Compiler.scala
index f80e01a00d91..09e0741c7524 100644
--- a/compiler/src/dotty/tools/dotc/Compiler.scala
+++ b/compiler/src/dotty/tools/dotc/Compiler.scala
@@ -12,7 +12,6 @@ import reporting.{Reporter, ConsoleReporter}
import Phases.Phase
import transform._
import util.FreshNameCreator
-import transform.TreeTransforms.{TreeTransform, TreeTransformer}
import core.DenotTransformers.DenotTransformer
import core.Denotations.SingleDenotation
diff --git a/compiler/src/dotty/tools/dotc/Run.scala b/compiler/src/dotty/tools/dotc/Run.scala
index 28b74b1b38c6..3ebd3a408781 100644
--- a/compiler/src/dotty/tools/dotc/Run.scala
+++ b/compiler/src/dotty/tools/dotc/Run.scala
@@ -10,7 +10,6 @@ import Types._
import Scopes._
import typer.{FrontEnd, Typer, ImportInfo, RefChecks}
import Decorators._
-import dotty.tools.dotc.transform.TreeTransforms.TreeTransformer
import io.PlainFile
import scala.io.Codec
import util._
@@ -116,23 +115,30 @@ class Run(comp: Compiler, ictx: Context) {
val phases = ctx.squashPhases(ctx.phasePlan,
ctx.settings.Yskip.value, ctx.settings.YstopBefore.value, stopAfter, ctx.settings.Ycheck.value)
ctx.usePhases(phases)
- var lastPrintedTree: PrintedTree = NoPrintedTree
- for (phase <- ctx.allPhases)
- if (phase.isRunnable)
- Stats.trackTime(s"$phase ms ") {
- val start = System.currentTimeMillis
- units = phase.runOn(units)
- if (ctx.settings.Xprint.value.containsPhase(phase)) {
- for (unit <- units) {
- lastPrintedTree =
- printTree(lastPrintedTree)(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
+
+ def runPhases(implicit ctx: Context) = {
+ var lastPrintedTree: PrintedTree = NoPrintedTree
+ for (phase <- ctx.allPhases)
+ if (phase.isRunnable)
+ Stats.trackTime(s"$phase ms ") {
+ val start = System.currentTimeMillis
+ units = phase.runOn(units)
+ if (ctx.settings.Xprint.value.containsPhase(phase)) {
+ for (unit <- units) {
+ lastPrintedTree =
+ printTree(lastPrintedTree)(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
+ }
}
+ ctx.informTime(s"$phase ", start)
+ Stats.record(s"total trees at end of $phase", ast.Trees.ntrees)
+ for (unit <- units)
+ Stats.record(s"retained typed trees at end of $phase", unit.tpdTree.treeSize)
}
- ctx.informTime(s"$phase ", start)
- Stats.record(s"total trees at end of $phase", ast.Trees.ntrees)
- for (unit <- units)
- Stats.record(s"retained typed trees at end of $phase", unit.tpdTree.treeSize)
- }
+ }
+
+ val runCtx = ctx.fresh
+ ctx.phases.foreach(_.initContext(runCtx))
+ runPhases(runCtx)
if (!ctx.reporter.hasErrors) Rewrites.writeBack()
}
diff --git a/compiler/src/dotty/tools/dotc/ast/Trees.scala b/compiler/src/dotty/tools/dotc/ast/Trees.scala
index 0fb504f62d12..0453f65dabdb 100644
--- a/compiler/src/dotty/tools/dotc/ast/Trees.scala
+++ b/compiler/src/dotty/tools/dotc/ast/Trees.scala
@@ -19,6 +19,82 @@ import language.implicitConversions
object Trees {
+ type TreeTag = Int
+
+ object Tag {
+ final val Ident = 0
+ final val Select = 1
+ final val This = 2
+ final val Super = 3
+ final val Apply = 4
+ final val TypeApply = 5
+ final val Literal = 6
+ final val New = 7
+ final val Typed = 8
+ final val NamedArg = 9
+ final val Assign = 10
+ final val Block = 11
+ final val If = 12
+ final val Closure = 13
+ final val Match = 14
+ final val CaseDef = 15
+ final val Return = 16
+ final val Try = 17
+ final val SeqLiteral = 18
+ final val Inlined = 19
+ final val TypeTree = 20
+ final val Bind = 21
+ final val Alternative = 22
+ final val UnApply = 23
+ final val ValDef = 24
+ final val DefDef = 25
+ final val TypeDef = 26
+ final val Template = 27
+ final val Import = 28
+ final val PackageDef = 29
+ final val Thicket = 30
+
+ /** The highest tree tag that can appear in a picked tree + 1 */
+ final val NumPickledTreeTags = 31
+
+ final val Annotated = 31
+ final val SingletonTypeTree = 32
+ final val AndTypeTree = 33
+ final val OrTypeTree = 34
+ final val RefinedTypeTree = 35
+ final val AppliedTypeTree = 36
+ final val LambdaTypeTree = 37
+ final val ByNameTypeTree = 38
+ final val TypeBoundsTree = 39
+
+ /** The highest tree tag that can appear in a typed tree + 1 */
+ final val NumTypedTreeTags = 40
+
+ final val TypedSplice = 40
+ final val ModuleDef = 41
+ final val ParsedTry = 42
+ final val SymbolLit = 43
+ final val InterpolatedString = 44
+ final val Function = 45
+ final val InfixOp = 46
+ final val PostfixOp = 47
+ final val PrefixOp = 48
+ final val Parens = 49
+ final val Tuple = 50
+ final val Throw = 51
+ final val WhileDo = 42
+ final val DoWhile = 43
+ final val ForYield = 44
+ final val ForDo = 45
+ final val GenFrom = 46
+ final val GenAlias = 47
+ final val ContextBounds = 48
+ final val PatDef = 49
+
+ /** The highest tree tag + 1 */
+ final val NumTags = 50
+ }
+
// Note: it would be more logical to make Untyped = Nothing.
// However, this interacts in a bad way with Scala's current type inference.
// In fact, we cannot write something like Select(pre, name), where pre is
@@ -78,6 +154,8 @@ object Trees {
/** The type constructor at the root of the tree */
type ThisTree[T >: Untyped] <: Tree[T]
+ def tag: TreeTag
+
private[this] var myTpe: T = _
/** Destructively set the type of the tree. This should be called only when it is known that
@@ -357,6 +435,7 @@ object Trees {
case class Ident[-T >: Untyped] private[ast] (name: Name)
extends RefTree[T] {
type ThisTree[-T >: Untyped] = Ident[T]
+ final def tag = Tag.Ident
def qualifier: Tree[T] = genericEmptyTree
/** Is this a `BackquotedIdent` ? */
@@ -374,6 +453,7 @@ object Trees {
case class Select[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name)
extends RefTree[T] {
type ThisTree[-T >: Untyped] = Select[T]
+ final def tag = Tag.Select
}
class SelectWithSig[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name, val sig: Signature)
@@ -385,6 +465,7 @@ object Trees {
case class This[-T >: Untyped] private[ast] (qual: untpd.Ident)
extends DenotingTree[T] with TermTree[T] {
type ThisTree[-T >: Untyped] = This[T]
+ final def tag = Tag.This
// Denotation of a This tree is always the underlying class; needs correction for modules.
override def denot(implicit ctx: Context): Denotation = {
typeOpt match {
@@ -400,6 +481,7 @@ object Trees {
case class Super[-T >: Untyped] private[ast] (qual: Tree[T], mix: untpd.Ident)
extends ProxyTree[T] with TermTree[T] {
type ThisTree[-T >: Untyped] = Super[T]
+ final def tag = Tag.Super
def forwardTo = qual
}
@@ -414,30 +496,35 @@ object Trees {
case class Apply[-T >: Untyped] private[ast] (fun: Tree[T], args: List[Tree[T]])
extends GenericApply[T] {
type ThisTree[-T >: Untyped] = Apply[T]
+ final def tag = Tag.Apply
}
/** fun[args] */
case class TypeApply[-T >: Untyped] private[ast] (fun: Tree[T], args: List[Tree[T]])
extends GenericApply[T] {
type ThisTree[-T >: Untyped] = TypeApply[T]
+ final def tag = Tag.TypeApply
}
/** const */
case class Literal[-T >: Untyped] private[ast] (const: Constant)
extends TermTree[T] {
type ThisTree[-T >: Untyped] = Literal[T]
+ final def tag = Tag.Literal
}
/** new tpt, but no constructor call */
case class New[-T >: Untyped] private[ast] (tpt: Tree[T])
extends TermTree[T] {
type ThisTree[-T >: Untyped] = New[T]
+ final def tag = Tag.New
}
/** expr : tpt */
case class Typed[-T >: Untyped] private[ast] (expr: Tree[T], tpt: Tree[T])
extends ProxyTree[T] with TermTree[T] {
type ThisTree[-T >: Untyped] = Typed[T]
+ final def tag = Tag.Typed
def forwardTo = expr
}
@@ -445,24 +532,28 @@ object Trees {
case class NamedArg[-T >: Untyped] private[ast] (name: Name, arg: Tree[T])
extends Tree[T] {
type ThisTree[-T >: Untyped] = NamedArg[T]
+ final def tag = Tag.NamedArg
}
/** name = arg, outside a parameter list */
case class Assign[-T >: Untyped] private[ast] (lhs: Tree[T], rhs: Tree[T])
extends TermTree[T] {
type ThisTree[-T >: Untyped] = Assign[T]
+ final def tag = Tag.Assign
}
/** { stats; expr } */
case class Block[-T >: Untyped] private[ast] (stats: List[Tree[T]], expr: Tree[T])
extends TermTree[T] {
type ThisTree[-T >: Untyped] = Block[T]
+ final def tag = Tag.Block
}
/** if cond then thenp else elsep */
case class If[-T >: Untyped] private[ast] (cond: Tree[T], thenp: Tree[T], elsep: Tree[T])
extends TermTree[T] {
type ThisTree[-T >: Untyped] = If[T]
+ final def tag = Tag.If
}
/** A closure with an environment and a reference to a method.
@@ -477,18 +568,21 @@ object Trees {
case class Closure[-T >: Untyped] private[ast] (env: List[Tree[T]], meth: Tree[T], tpt: Tree[T])
extends TermTree[T] {
type ThisTree[-T >: Untyped] = Closure[T]
+ final def tag = Tag.Closure
}
/** selector match { cases } */
case class Match[-T >: Untyped] private[ast] (selector: Tree[T], cases: List[CaseDef[T]])
extends TermTree[T] {
type ThisTree[-T >: Untyped] = Match[T]
+ final def tag = Tag.Match
}
/** case pat if guard => body; only appears as child of a Match */
case class CaseDef[-T >: Untyped] private[ast] (pat: Tree[T], guard: Tree[T], body: Tree[T])
extends Tree[T] {
type ThisTree[-T >: Untyped] = CaseDef[T]
+ final def tag = Tag.CaseDef
}
/** return expr
@@ -499,6 +593,7 @@ object Trees {
case class Return[-T >: Untyped] private[ast] (expr: Tree[T], from: Tree[T] = genericEmptyTree)
extends TermTree[T] {
type ThisTree[-T >: Untyped] = Return[T]
+ final def tag = Tag.Return
}
/** try block catch handler finally finalizer
@@ -523,6 +618,7 @@ object Trees {
case class Try[-T >: Untyped] private[ast] (expr: Tree[T], cases: List[CaseDef[T]], finalizer: Tree[T])
extends TermTree[T] {
type ThisTree[-T >: Untyped] = Try[T]
+ final def tag = Tag.Try
}
/** Seq(elems)
@@ -531,6 +627,7 @@ object Trees {
case class SeqLiteral[-T >: Untyped] private[ast] (elems: List[Tree[T]], elemtpt: Tree[T])
extends Tree[T] {
type ThisTree[-T >: Untyped] = SeqLiteral[T]
+ final def tag = Tag.SeqLiteral
}
/** Array(elems) */
@@ -558,12 +655,14 @@ object Trees {
case class Inlined[-T >: Untyped] private[ast] (call: tpd.Tree, bindings: List[MemberDef[T]], expansion: Tree[T])
extends Tree[T] {
type ThisTree[-T >: Untyped] = Inlined[T]
+ final def tag = Tag.Inlined
}
/** A type tree that represents an existing or inferred type */
case class TypeTree[-T >: Untyped] ()
extends DenotingTree[T] with TypTree[T] {
type ThisTree[-T >: Untyped] = TypeTree[T]
+ final def tag = Tag.TypeTree
override def isEmpty = !hasType
override def toString =
s"TypeTree${if (hasType) s"[$typeOpt]" else ""}"
@@ -573,24 +672,28 @@ object Trees {
case class SingletonTypeTree[-T >: Untyped] private[ast] (ref: Tree[T])
extends DenotingTree[T] with TypTree[T] {
type ThisTree[-T >: Untyped] = SingletonTypeTree[T]
+ final def tag = Tag.SingletonTypeTree
}
/** left & right */
case class AndTypeTree[-T >: Untyped] private[ast] (left: Tree[T], right: Tree[T])
extends TypTree[T] {
type ThisTree[-T >: Untyped] = AndTypeTree[T]
+ final def tag = Tag.AndTypeTree
}
/** left | right */
case class OrTypeTree[-T >: Untyped] private[ast] (left: Tree[T], right: Tree[T])
extends TypTree[T] {
type ThisTree[-T >: Untyped] = OrTypeTree[T]
+ final def tag = Tag.OrTypeTree
}
/** tpt { refinements } */
case class RefinedTypeTree[-T >: Untyped] private[ast] (tpt: Tree[T], refinements: List[Tree[T]])
extends ProxyTree[T] with TypTree[T] {
type ThisTree[-T >: Untyped] = RefinedTypeTree[T]
+ final def tag = Tag.RefinedTypeTree
def forwardTo = tpt
}
@@ -598,6 +701,7 @@ object Trees {
case class AppliedTypeTree[-T >: Untyped] private[ast] (tpt: Tree[T], args: List[Tree[T]])
extends ProxyTree[T] with TypTree[T] {
type ThisTree[-T >: Untyped] = AppliedTypeTree[T]
+ final def tag = Tag.AppliedTypeTree
def forwardTo = tpt
}
@@ -605,24 +709,28 @@ object Trees {
case class LambdaTypeTree[-T >: Untyped] private[ast] (tparams: List[TypeDef[T]], body: Tree[T])
extends TypTree[T] {
type ThisTree[-T >: Untyped] = LambdaTypeTree[T]
+ final def tag = Tag.LambdaTypeTree
}
/** => T */
case class ByNameTypeTree[-T >: Untyped] private[ast] (result: Tree[T])
extends TypTree[T] {
type ThisTree[-T >: Untyped] = ByNameTypeTree[T]
+ final def tag = Tag.ByNameTypeTree
}
/** >: lo <: hi */
case class TypeBoundsTree[-T >: Untyped] private[ast] (lo: Tree[T], hi: Tree[T])
extends TypTree[T] {
type ThisTree[-T >: Untyped] = TypeBoundsTree[T]
+ final def tag = Tag.TypeBoundsTree
}
/** name @ body */
case class Bind[-T >: Untyped] private[ast] (name: Name, body: Tree[T])
extends NameTree[T] with DefTree[T] with PatternTree[T] {
type ThisTree[-T >: Untyped] = Bind[T]
+ final def tag = Tag.Bind
override def isType = name.isTypeName
override def isTerm = name.isTermName
}
@@ -631,6 +739,7 @@ object Trees {
case class Alternative[-T >: Untyped] private[ast] (trees: List[Tree[T]])
extends PatternTree[T] {
type ThisTree[-T >: Untyped] = Alternative[T]
+ final def tag = Tag.Alternative
}
/** The typed translation of `extractor(patterns)` in a pattern. The translation has the following
@@ -650,12 +759,14 @@ object Trees {
case class UnApply[-T >: Untyped] private[ast] (fun: Tree[T], implicits: List[Tree[T]], patterns: List[Tree[T]])
extends PatternTree[T] {
type ThisTree[-T >: Untyped] = UnApply[T]
+ final def tag = Tag.UnApply
}
/** mods val name: tpt = rhs */
case class ValDef[-T >: Untyped] private[ast] (name: TermName, tpt: Tree[T], private var preRhs: LazyTree)
extends ValOrDefDef[T] {
type ThisTree[-T >: Untyped] = ValDef[T]
+ final def tag = Tag.ValDef
assert(isEmpty || tpt != genericEmptyTree)
def unforced = preRhs
protected def force(x: AnyRef) = preRhs = x
@@ -666,6 +777,7 @@ object Trees {
vparamss: List[List[ValDef[T]]], tpt: Tree[T], private var preRhs: LazyTree)
extends ValOrDefDef[T] {
type ThisTree[-T >: Untyped] = DefDef[T]
+ final def tag = Tag.DefDef
assert(tpt != genericEmptyTree)
def unforced = preRhs
protected def force(x: AnyRef) = preRhs = x
@@ -679,6 +791,7 @@ object Trees {
case class TypeDef[-T >: Untyped] private[ast] (name: TypeName, rhs: Tree[T])
extends MemberDef[T] {
type ThisTree[-T >: Untyped] = TypeDef[T]
+ final def tag = Tag.TypeDef
/** Is this a definition of a class? */
def isClassDef = rhs.isInstanceOf[Template[_]]
@@ -688,6 +801,7 @@ object Trees {
case class Template[-T >: Untyped] private[ast] (constr: DefDef[T], parents: List[Tree[T]], self: ValDef[T], private var preBody: LazyTreeList)
extends DefTree[T] with WithLazyField[List[Tree[T]]] {
type ThisTree[-T >: Untyped] = Template[T]
+ final def tag = Tag.Template
def unforcedBody = unforced
def unforced = preBody
protected def force(x: AnyRef) = preBody = x
@@ -701,12 +815,14 @@ object Trees {
case class Import[-T >: Untyped] private[ast] (expr: Tree[T], selectors: List[Tree[Untyped]])
extends DenotingTree[T] {
type ThisTree[-T >: Untyped] = Import[T]
+ final def tag = Tag.Import
}
/** package pid { stats } */
case class PackageDef[-T >: Untyped] private[ast] (pid: RefTree[T], stats: List[Tree[T]])
extends ProxyTree[T] {
type ThisTree[-T >: Untyped] = PackageDef[T]
+ final def tag = Tag.PackageDef
def forwardTo = pid
}
@@ -714,6 +830,7 @@ object Trees {
case class Annotated[-T >: Untyped] private[ast] (arg: Tree[T], annot: Tree[T])
extends ProxyTree[T] {
type ThisTree[-T >: Untyped] = Annotated[T]
+ final def tag = Tag.Annotated
def forwardTo = arg
}
@@ -732,6 +849,7 @@ object Trees {
case class Thicket[-T >: Untyped](trees: List[Tree[T]])
extends Tree[T] with WithoutTypeOrPos[T] {
type ThisTree[-T >: Untyped] = Thicket[T]
+ final def tag = Tag.Thicket
override def isEmpty: Boolean = trees.isEmpty
override def toList: List[Tree[T]] = flatten(trees)
override def toString = if (isEmpty) "EmptyTree" else "Thicket(" + trees.mkString(", ") + ")"
diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala
index bf40539679ec..28ef978a5012 100644
--- a/compiler/src/dotty/tools/dotc/ast/untpd.scala
+++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala
@@ -25,6 +25,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
* @param owner The current owner at the time the tree was defined
*/
abstract case class TypedSplice(tree: tpd.Tree)(val owner: Symbol) extends ProxyTree {
+ final def tag = Tag.TypedSplice
def forwardTo = tree
}
@@ -37,20 +38,28 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case class ModuleDef(name: TermName, impl: Template)
extends MemberDef {
type ThisTree[-T >: Untyped] <: Trees.NameTree[T] with Trees.MemberDef[T] with ModuleDef
+ final def tag = Tag.ModuleDef
def withName(name: Name)(implicit ctx: Context) = cpy.ModuleDef(this)(name.toTermName, impl)
}
- case class ParsedTry(expr: Tree, handler: Tree, finalizer: Tree) extends TermTree
+ case class ParsedTry(expr: Tree, handler: Tree, finalizer: Tree) extends TermTree {
+ final def tag = Tag.ParsedTry
+ }
- case class SymbolLit(str: String) extends TermTree
+ case class SymbolLit(str: String) extends TermTree {
+ final def tag = Tag.SymbolLit
+ }
/** An interpolated string
* @param segments a list of two element tickets consisting of string literal and argument tree,
* possibly with a simple string literal as last element of the list
*/
- case class InterpolatedString(id: TermName, segments: List[Tree]) extends TermTree
+ case class InterpolatedString(id: TermName, segments: List[Tree]) extends TermTree {
+ final def tag = Tag.InterpolatedString
+ }
case class Function(args: List[Tree], body: Tree) extends Tree {
+ final def tag = Tag.Function
override def isTerm = body.isTerm
override def isType = body.isType
}
@@ -67,25 +76,51 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
*/
class WildcardFunction(placeholderParams: List[ValDef], body: Tree) extends Function(placeholderParams, body)
- case class InfixOp(left: Tree, op: Ident, right: Tree) extends OpTree
- case class PostfixOp(od: Tree, op: Ident) extends OpTree
- case class PrefixOp(op: Ident, od: Tree) extends OpTree
+ case class InfixOp(left: Tree, op: Ident, right: Tree) extends OpTree {
+ final def tag = Tag.InfixOp
+ }
+ case class PostfixOp(od: Tree, op: Ident) extends OpTree {
+ final def tag = Tag.PostfixOp
+ }
+ case class PrefixOp(op: Ident, od: Tree) extends OpTree {
+ final def tag = Tag.PrefixOp
+ }
case class Parens(t: Tree) extends ProxyTree {
+ final def tag = Tag.Parens
def forwardTo = t
}
case class Tuple(trees: List[Tree]) extends Tree {
+ final def tag = Tag.Tuple
override def isTerm = trees.isEmpty || trees.head.isTerm
override def isType = !isTerm
}
- case class Throw(expr: Tree) extends TermTree
- case class WhileDo(cond: Tree, body: Tree) extends TermTree
- case class DoWhile(body: Tree, cond: Tree) extends TermTree
- case class ForYield(enums: List[Tree], expr: Tree) extends TermTree
- case class ForDo(enums: List[Tree], body: Tree) extends TermTree
- case class GenFrom(pat: Tree, expr: Tree) extends Tree
- case class GenAlias(pat: Tree, expr: Tree) extends Tree
- case class ContextBounds(bounds: TypeBoundsTree, cxBounds: List[Tree]) extends TypTree
- case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends DefTree
+ case class Throw(expr: Tree) extends TermTree {
+ final def tag = Tag.Throw
+ }
+ case class WhileDo(cond: Tree, body: Tree) extends TermTree {
+ final def tag = Tag.WhileDo
+ }
+ case class DoWhile(body: Tree, cond: Tree) extends TermTree {
+ final def tag = Tag.DoWhile
+ }
+ case class ForYield(enums: List[Tree], expr: Tree) extends TermTree {
+ final def tag = Tag.ForYield
+ }
+ case class ForDo(enums: List[Tree], body: Tree) extends TermTree {
+ final def tag = Tag.ForDo
+ }
+ case class GenFrom(pat: Tree, expr: Tree) extends Tree {
+ final def tag = Tag.GenFrom
+ }
+ case class GenAlias(pat: Tree, expr: Tree) extends Tree {
+ final def tag = Tag.GenAlias
+ }
+ case class ContextBounds(bounds: TypeBoundsTree, cxBounds: List[Tree]) extends TypTree {
+ final def tag = Tag.ContextBounds
+ }
+ case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends DefTree {
+ final def tag = Tag.PatDef
+ }
@sharable object EmptyTypeIdent extends Ident(tpnme.EMPTY) with WithoutTypeOrPos[Untyped] {
override def isEmpty = true
diff --git a/compiler/src/dotty/tools/dotc/core/Contexts.scala b/compiler/src/dotty/tools/dotc/core/Contexts.scala
index 0fd08bf5649d..9b04542b6a59 100644
--- a/compiler/src/dotty/tools/dotc/core/Contexts.scala
+++ b/compiler/src/dotty/tools/dotc/core/Contexts.scala
@@ -31,6 +31,7 @@ import config.{Settings, ScalaSettings, Platform, JavaPlatform}
import language.implicitConversions
import DenotTransformers.DenotTransformer
import util.Property.Key
+import util.Store
import xsbti.AnalysisCallback
object Contexts {
@@ -157,13 +158,6 @@ object Contexts {
protected def runInfo_=(runInfo: RunInfo) = _runInfo = runInfo
def runInfo: RunInfo = _runInfo
- /** An optional diagostics buffer than is used by some checking code
- * to provide more information in the buffer if it exists.
- */
- private[this] var _diagnostics: Option[StringBuilder] = _
- protected def diagnostics_=(diagnostics: Option[StringBuilder]) = _diagnostics = diagnostics
- def diagnostics: Option[StringBuilder] = _diagnostics
-
/** The current bounds in force for type parameters appearing in a GADT */
private[this] var _gadt: GADTMap = _
protected def gadt_=(gadt: GADTMap) = _gadt = gadt
@@ -174,6 +168,11 @@ object Contexts {
protected def freshNames_=(freshNames: FreshNameCreator) = _freshNames = freshNames
def freshNames: FreshNameCreator = _freshNames
+ /** A store that can be used by sub-components */
+ private var _store: Store = _
+ protected def store_=(store: Store) = _store = store
+ def store: Store = _store
+
/** A map in which more contextual properties can be stored */
private[this] var _moreProperties: Map[Key[Any], Any] = _
protected def moreProperties_=(moreProperties: Map[Key[Any], Any]) = _moreProperties = moreProperties
@@ -300,13 +299,6 @@ object Contexts {
def isNonEmptyScopeContext: Boolean =
(this.scope ne outer.scope) && !this.scope.isEmpty
- /** Leave message in diagnostics buffer if it exists */
- def diagnose(str: => String) =
- for (sb <- diagnostics) {
- sb.setLength(0)
- sb.append(str)
- }
-
/** The next outer context whose tree is a template or package definition
* Note: Currently unused
def enclTemplate: Context = {
@@ -406,7 +398,6 @@ object Contexts {
.withSettings(sstate)
// tree is not preserved in condensed
.withRunInfo(runInfo)
- .withDiagnostics(diagnostics)
.withMoreProperties(moreProperties)
_condensed
}
@@ -474,12 +465,12 @@ object Contexts {
def setImportInfo(importInfo: ImportInfo): this.type = { this.importInfo = importInfo; this }
def setImplicits(implicits: ContextualImplicits): this.type = { this.implicitsCache = implicits; this }
def setRunInfo(runInfo: RunInfo): this.type = { this.runInfo = runInfo; this }
- def setDiagnostics(diagnostics: Option[StringBuilder]): this.type = { this.diagnostics = diagnostics; this }
def setGadt(gadt: GADTMap): this.type = { this.gadt = gadt; this }
def setFreshGADTBounds: this.type = setGadt(new GADTMap(gadt.bounds))
def setTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this }
def setSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this }
def setFreshNames(freshNames: FreshNameCreator): this.type = { this.freshNames = freshNames; this }
+ def setStore(store: Store): this.type = { this.store = store; this }
def setMoreProperties(moreProperties: Map[Key[Any], Any]): this.type = { this.moreProperties = moreProperties; this }
def setProperty[T](key: Key[T], value: T): this.type =
@@ -488,13 +479,27 @@ object Contexts {
def dropProperty(key: Key[_]): this.type =
setMoreProperties(moreProperties - key)
+ def addLocation[T](initial: T): Store.Location[T] = {
+ val (loc, store1) = store.newLocation(initial)
+ setStore(store1)
+ loc
+ }
+
+ def addLocation[T](): Store.Location[T] = {
+ val (loc, store1) = store.newLocation[T]()
+ setStore(store1)
+ loc
+ }
+
+ def updateStore[T](loc: Store.Location[T], value: T): this.type =
+ setStore(store.updated(loc, value))
+
def setPhase(pid: PhaseId): this.type = setPeriod(Period(runId, pid))
def setPhase(phase: Phase): this.type = setPeriod(Period(runId, phase.start, phase.end))
def setSetting[T](setting: Setting[T], value: T): this.type =
setSettings(setting.updateIn(sstate, value))
-
def setDebug = setSetting(base.settings.debug, true)
}
@@ -527,9 +532,9 @@ object Contexts {
tree = untpd.EmptyTree
typeAssigner = TypeAssigner
runInfo = new RunInfo(this)
- diagnostics = None
freshNames = new FreshNameCreator.Default
moreProperties = Map.empty
+ store = Store.empty
typeComparer = new TypeComparer(this)
searchHistory = new SearchHistory(0, Map())
gadt = EmptyGADTMap
@@ -643,7 +648,7 @@ object Contexts {
private[core] var phasesPlan: List[List[Phase]] = _
/** Phases by id */
- private[core] var phases: Array[Phase] = _
+ private[dotc] var phases: Array[Phase] = _
/** Phases with consecutive Transforms grouped into a single phase, Empty array if squashing is disabled */
private[core] var squashedPhases: Array[Phase] = Array.empty[Phase]
diff --git a/compiler/src/dotty/tools/dotc/core/Decorators.scala b/compiler/src/dotty/tools/dotc/core/Decorators.scala
index d721f97b44f5..53b2e19e5e12 100644
--- a/compiler/src/dotty/tools/dotc/core/Decorators.scala
+++ b/compiler/src/dotty/tools/dotc/core/Decorators.scala
@@ -6,7 +6,7 @@ import Symbols._
import Contexts._, Names._, Phases._, printing.Texts._, printing.Printer, printing.Showable
import util.Positions.Position, util.SourcePosition
import collection.mutable.ListBuffer
-import dotty.tools.dotc.transform.TreeTransforms._
+import dotty.tools.dotc.transform.MegaPhase
import ast.tpd._
import scala.language.implicitConversions
import printing.Formatting._
@@ -152,7 +152,7 @@ object Decorators {
*/
implicit class PhaseListDecorator(val names: List[String]) extends AnyVal {
def containsPhase(phase: Phase): Boolean = phase match {
- case phase: TreeTransformer => phase.miniPhases.exists(containsPhase)
+ case phase: MegaPhase => phase.miniPhases.exists(containsPhase)
case _ =>
names exists { name =>
name == "all" || {
diff --git a/compiler/src/dotty/tools/dotc/core/Phases.scala b/compiler/src/dotty/tools/dotc/core/Phases.scala
index 10c7b7416325..77f700454cad 100644
--- a/compiler/src/dotty/tools/dotc/core/Phases.scala
+++ b/compiler/src/dotty/tools/dotc/core/Phases.scala
@@ -11,7 +11,7 @@ import Denotations._
import Decorators._
import config.Printers.config
import scala.collection.mutable.{ListBuffer, ArrayBuffer}
-import dotty.tools.dotc.transform.TreeTransforms.{TreeTransformer, MiniPhase, TreeTransform}
+import dotty.tools.dotc.transform.MegaPhase._
import dotty.tools.dotc.transform._
import Periods._
import typer.{FrontEnd, RefChecks}
@@ -111,12 +111,9 @@ object Phases {
assert(false, s"Only tree transforms can be squashed, ${phase.phaseName} can not be squashed")
}
}
- val block = new TreeTransformer {
- override def phaseName: String = miniPhases.map(_.phaseName).mkString("TreeTransform:{", ", ", "}")
- override def miniPhases: Array[MiniPhase] = filteredPhaseBlock.asInstanceOf[List[MiniPhase]].toArray
- }
+ val superPhase = new MegaPhase(filteredPhaseBlock.asInstanceOf[List[MiniPhase]].toArray)
prevPhases ++= filteredPhaseBlock.map(_.getClazz)
- block
+ superPhase
} else { // block of a single phase, no squashing
val phase = filteredPhaseBlock.head
prevPhases += phase.getClazz
@@ -144,7 +141,7 @@ object Phases {
val flatPhases = collection.mutable.ListBuffer[Phase]()
phasess.foreach(p => p match {
- case t: TreeTransformer => flatPhases ++= t.miniPhases
+ case p: MegaPhase => flatPhases ++= p.miniPhases
case _ => flatPhases += p
})
@@ -172,12 +169,12 @@ object Phases {
while (i < phasess.length) {
val phase = phasess(i)
phase match {
- case t: TreeTransformer =>
- val miniPhases = t.miniPhases
+ case p: MegaPhase =>
+ val miniPhases = p.miniPhases
miniPhases.foreach{ phase =>
checkRequirements(phase)
phase.init(this, nextPhaseId)}
- t.init(this, miniPhases.head.id, miniPhases.last.id)
+ p.init(this, miniPhases.head.id, miniPhases.last.id)
case _ =>
phase.init(this, nextPhaseId)
checkRequirements(phase)
@@ -275,7 +272,11 @@ object Phases {
def isRunnable(implicit ctx: Context): Boolean =
!ctx.reporter.hasErrors
- /** List of names of phases that should precede this phase */
+ /** If set, allow missing or superfluous arguments in applications
+ * and type applications.
+ */
+ def relaxedTyping: Boolean = false
+ /** List of names of phases that should precede this phase */
def runsAfter: Set[Class[_ <: Phase]] = Set.empty
/** @pre `isRunnable` returns true */
@@ -313,6 +314,8 @@ object Phases {
def exists: Boolean = true
+ def initContext(ctx: FreshContext): Unit = ()
+
private[this] var myPeriod: Period = Periods.InvalidPeriod
private[this] var myBase: ContextBase = null
private[this] var myErasedTypes = false
@@ -345,7 +348,7 @@ object Phases {
final def sameParentsStartId = mySameParentsStartId
// id of first phase where all symbols are guaranteed to have the same parents as in this phase
- protected[Phases] def init(base: ContextBase, start: Int, end:Int): Unit = {
+ protected[Phases] def init(base: ContextBase, start: Int, end: Int): Unit = {
if (start >= FirstPhaseId)
assert(myPeriod == Periods.InvalidPeriod, s"phase $this has already been used once; cannot be reused")
assert(start <= Periods.MaxPossiblePhaseId, s"Too many phases, Period bits overflow")
diff --git a/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala b/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala
index 74213d332925..c7d02d53175b 100644
--- a/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ArrayConstructors.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package transform
import core._
-import TreeTransforms._
+import MegaPhase._
import Contexts.Context
import Flags._
import SymUtils._
@@ -29,12 +29,12 @@ import scala.collection.immutable.::
* It assummes that generic arrays have already been handled by typer(see Applications.convertNewGenericArray).
* Additionally it optimizes calls to scala.Array.ofDim functions by replacing them with calls to newArray with specific dimensions
*/
-class ArrayConstructors extends MiniPhaseTransform { thisTransform =>
+class ArrayConstructors extends MiniPhase {
import ast.tpd._
override def phaseName: String = "arrayConstructors"
- override def transformApply(tree: tpd.Apply)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformApply(tree: tpd.Apply)(implicit ctx: Context): tpd.Tree = {
def rewrite(elemType: Type, dims: List[Tree]) =
tpd.newArray(elemType, tree.tpe, tree.pos, JavaSeqLiteral(dims, TypeTree(defn.IntClass.typeRef)))
diff --git a/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala b/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
index c5226f756d63..e208902d3589 100644
--- a/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
+++ b/compiler/src/dotty/tools/dotc/transform/AugmentScala2Traits.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package transform
import core._
-import TreeTransforms._
+import MegaPhase._
import Contexts.Context
import Flags._
import SymUtils._
@@ -28,7 +28,7 @@ import ast.Trees._
* Furthermore, it expands the names of all private getters and setters as well as super accessors in the trait and makes
* them not-private.
*/
-class AugmentScala2Traits extends MiniPhaseTransform with IdentityDenotTransformer with FullParameterization { thisTransform =>
+class AugmentScala2Traits extends MiniPhase with IdentityDenotTransformer with FullParameterization { thisPhase =>
import ast.tpd._
override def changesMembers = true
@@ -37,7 +37,7 @@ class AugmentScala2Traits extends MiniPhaseTransform with IdentityDenotTransform
override def rewiredTarget(referenced: Symbol, derived: Symbol)(implicit ctx: Context) = NoSymbol
- override def transformTemplate(impl: Template)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformTemplate(impl: Template)(implicit ctx: Context) = {
val cls = impl.symbol.owner.asClass
for (mixin <- cls.mixins)
if (mixin.is(Scala2x))
@@ -49,7 +49,7 @@ class AugmentScala2Traits extends MiniPhaseTransform with IdentityDenotTransform
if (mixin.implClass.is(Scala2x)) () // nothing to do, mixin was already augmented
else {
//println(i"creating new implclass for $mixin ${mixin.implClass}")
- val ops = new MixinOps(cls, thisTransform)
+ val ops = new MixinOps(cls, thisPhase)
import ops._
val implClass = ctx.newCompleteClassSymbol(
@@ -57,7 +57,7 @@ class AugmentScala2Traits extends MiniPhaseTransform with IdentityDenotTransform
name = mixin.name.implClassName,
flags = Abstract | Scala2x | ImplClass,
parents = defn.ObjectType :: Nil,
- assocFile = mixin.assocFile).enteredAfter(thisTransform)
+ assocFile = mixin.assocFile).enteredAfter(thisPhase)
def implMethod(meth: TermSymbol): Symbol = {
val mold =
@@ -91,11 +91,11 @@ class AugmentScala2Traits extends MiniPhaseTransform with IdentityDenotTransform
}
else if (!sym.is(Deferred) && !sym.setter.exists &&
!sym.info.resultType.isInstanceOf[ConstantType])
- traitSetter(sym.asTerm).enteredAfter(thisTransform)
+ traitSetter(sym.asTerm).enteredAfter(thisPhase)
if ((sym.is(PrivateAccessor) && !sym.name.is(ExpandedName) &&
(sym.isGetter || sym.isSetter)) // strangely, Scala 2 fields are also methods that have Accessor set.
|| sym.isSuperAccessor) // scala2 superaccessors are pickled as private, but are compiled as public expanded
- sym.ensureNotPrivate.installAfter(thisTransform)
+ sym.ensureNotPrivate.installAfter(thisPhase)
}
ctx.log(i"Scala2x trait decls of $mixin = ${mixin.info.decls.toList.map(_.showDcl)}%\n %")
ctx.log(i"Scala2x impl decls of $mixin = ${implClass.info.decls.toList.map(_.showDcl)}%\n %")
diff --git a/compiler/src/dotty/tools/dotc/transform/ByNameClosures.scala b/compiler/src/dotty/tools/dotc/transform/ByNameClosures.scala
index d8499369d051..c548fce4f9d1 100644
--- a/compiler/src/dotty/tools/dotc/transform/ByNameClosures.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ByNameClosures.scala
@@ -1,7 +1,6 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
import core._
import Symbols._
import SymDenotations._
@@ -24,7 +23,7 @@ import core.StdNames.nme
*
* is a synthetic method defined in Definitions. Erasure will later strip the wrappers.
*/
-class ByNameClosures extends TransformByNameApply with IdentityDenotTransformer { thisTransformer =>
+class ByNameClosures extends TransformByNameApply with IdentityDenotTransformer { thisPhase =>
import ast.tpd._
override def phaseName: String = "byNameClosures"
@@ -32,6 +31,6 @@ class ByNameClosures extends TransformByNameApply with IdentityDenotTransformer
override def mkByNameClosure(arg: Tree, argType: Type)(implicit ctx: Context): Tree = {
val meth = ctx.newSymbol(
ctx.owner, nme.ANON_FUN, Synthetic | Method, MethodType(Nil, Nil, argType))
- Closure(meth, _ => arg.changeOwnerAfter(ctx.owner, meth, thisTransformer))
+ Closure(meth, _ => arg.changeOwnerAfter(ctx.owner, meth, thisPhase))
}
}
diff --git a/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala b/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala
index f0e69330adab..55704e71ee3b 100644
--- a/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala
+++ b/compiler/src/dotty/tools/dotc/transform/CapturedVars.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core.DenotTransformers._
import core.Symbols._
import core.Contexts._
@@ -15,18 +15,24 @@ import core.NameOps._
import core.NameKinds.TempResultName
import ast.Trees._
import SymUtils._
+import util.Store
import collection.{ mutable, immutable }
import collection.mutable.{ LinkedHashMap, LinkedHashSet, TreeSet }
/** This phase translates variables that are captured in closures to
* heap-allocated refs.
*/
-class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransform =>
+class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import ast.tpd._
/** the following two members override abstract members in Transform */
val phaseName: String = "capturedVars"
- val treeTransform = new Transform(Set())
+
+ private var Captured: Store.Location[collection.Set[Symbol]] = _
+ private def captured(implicit ctx: Context) = ctx.store(Captured)
+
+ override def initContext(ctx: FreshContext) =
+ Captured = ctx.addLocation(Set.empty)
private class RefInfo(implicit ctx: Context) {
/** The classes for which a Ref type exists. */
@@ -43,114 +49,110 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransfo
refClassKeys.flatMap(k => Set(refClass(k), volatileRefClass(k)))
}
- class Transform(captured: collection.Set[Symbol]) extends TreeTransform {
- def phase = thisTransform
-
- private[this] var myRefInfo: RefInfo = null
- private def refInfo(implicit ctx: Context) = {
- if (myRefInfo == null) myRefInfo = new RefInfo()
- myRefInfo
- }
+ private[this] var myRefInfo: RefInfo = null
+ private def refInfo(implicit ctx: Context) = {
+ if (myRefInfo == null) myRefInfo = new RefInfo()
+ myRefInfo
+ }
- private class CollectCaptured extends TreeTraverser {
- private val captured = mutable.HashSet[Symbol]()
- def traverse(tree: Tree)(implicit ctx: Context) = tree match {
- case id: Ident =>
- val sym = id.symbol
- if (sym.is(Mutable, butNot = Method) && sym.owner.isTerm) {
- val enclMeth = ctx.owner.enclosingMethod
- if (sym.enclosingMethod != enclMeth) {
- ctx.log(i"capturing $sym in ${sym.enclosingMethod}, referenced from $enclMeth")
- captured += sym
- }
+ private class CollectCaptured extends TreeTraverser {
+ private val captured = mutable.HashSet[Symbol]()
+ def traverse(tree: Tree)(implicit ctx: Context) = tree match {
+ case id: Ident =>
+ val sym = id.symbol
+ if (sym.is(Mutable, butNot = Method) && sym.owner.isTerm) {
+ val enclMeth = ctx.owner.enclosingMethod
+ if (sym.enclosingMethod != enclMeth) {
+ ctx.log(i"capturing $sym in ${sym.enclosingMethod}, referenced from $enclMeth")
+ captured += sym
}
- case _ =>
- traverseChildren(tree)
- }
- def runOver(tree: Tree)(implicit ctx: Context): collection.Set[Symbol] = {
- traverse(tree)
- captured
- }
+ }
+ case _ =>
+ traverseChildren(tree)
}
-
- override def prepareForUnit(tree: Tree)(implicit ctx: Context) = {
- val captured = (new CollectCaptured)
- .runOver(ctx.compilationUnit.tpdTree)(ctx.withPhase(thisTransform))
- new Transform(captured)
+ def runOver(tree: Tree)(implicit ctx: Context): collection.Set[Symbol] = {
+ traverse(tree)
+ captured
}
+ }
- /** The {Volatile|}{Int|Double|...|Object}Ref class corresponding to the class `cls`,
- * depending on whether the reference should be @volatile
- */
- def refClass(cls: Symbol, isVolatile: Boolean)(implicit ctx: Context): Symbol = {
- val refMap = if (isVolatile) refInfo.volatileRefClass else refInfo.refClass
- if (cls.isClass) {
- refMap.getOrElse(cls, refMap(defn.ObjectClass))
- }
- else refMap(defn.ObjectClass)
- }
+ override def prepareForUnit(tree: Tree)(implicit ctx: Context) = {
+ val captured = (new CollectCaptured)
+ .runOver(ctx.compilationUnit.tpdTree)(ctx.withPhase(thisPhase))
+ ctx.fresh.updateStore(Captured, captured)
+ }
- override def prepareForValDef(vdef: ValDef)(implicit ctx: Context) = {
- val sym = vdef.symbol(ctx.withPhase(thisTransform))
- if (captured contains sym) {
- val newd = sym.denot(ctx.withPhase(thisTransform)).copySymDenotation(
- info = refClass(sym.info.classSymbol, sym.hasAnnotation(defn.VolatileAnnot)).typeRef,
- initFlags = sym.flags &~ Mutable)
- newd.removeAnnotation(defn.VolatileAnnot)
- newd.installAfter(thisTransform)
- }
- this
+ /** The {Volatile|}{Int|Double|...|Object}Ref class corresponding to the class `cls`,
+ * depending on whether the reference should be @volatile
+ */
+ def refClass(cls: Symbol, isVolatile: Boolean)(implicit ctx: Context): Symbol = {
+ val refMap = if (isVolatile) refInfo.volatileRefClass else refInfo.refClass
+ if (cls.isClass) {
+ refMap.getOrElse(cls, refMap(defn.ObjectClass))
}
+ else refMap(defn.ObjectClass)
+ }
- override def transformValDef(vdef: ValDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
- val vble = vdef.symbol
- if (captured contains vble) {
- def boxMethod(name: TermName): Tree =
- ref(vble.info.classSymbol.companionModule.info.member(name).symbol)
- cpy.ValDef(vdef)(
- rhs = vdef.rhs match {
- case EmptyTree => boxMethod(nme.zero).appliedToNone.withPos(vdef.pos)
- case arg => boxMethod(nme.create).appliedTo(arg)
- },
- tpt = TypeTree(vble.info).withPos(vdef.tpt.pos))
- } else vdef
+ override def prepareForValDef(vdef: ValDef)(implicit ctx: Context) = {
+ val sym = vdef.symbol(ctx.withPhase(thisPhase))
+ if (captured contains sym) {
+ val newd = sym.denot(ctx.withPhase(thisPhase)).copySymDenotation(
+ info = refClass(sym.info.classSymbol, sym.hasAnnotation(defn.VolatileAnnot)).typeRef,
+ initFlags = sym.flags &~ Mutable)
+ newd.removeAnnotation(defn.VolatileAnnot)
+ newd.installAfter(thisPhase)
}
+ ctx
+ }
- override def transformIdent(id: Ident)(implicit ctx: Context, info: TransformerInfo): Tree = {
- val vble = id.symbol
- if (captured(vble))
- id.select(nme.elem).ensureConforms(vble.denot(ctx.withPhase(thisTransform)).info)
- else id
- }
+ override def transformValDef(vdef: ValDef)(implicit ctx: Context): Tree = {
+ val vble = vdef.symbol
+ if (captured.contains(vble)) {
+ def boxMethod(name: TermName): Tree =
+ ref(vble.info.classSymbol.companionModule.info.member(name).symbol)
+ cpy.ValDef(vdef)(
+ rhs = vdef.rhs match {
+ case EmptyTree => boxMethod(nme.zero).appliedToNone.withPos(vdef.pos)
+ case arg => boxMethod(nme.create).appliedTo(arg)
+ },
+ tpt = TypeTree(vble.info).withPos(vdef.tpt.pos))
+ } else vdef
+ }
+
+ override def transformIdent(id: Ident)(implicit ctx: Context): Tree = {
+ val vble = id.symbol
+ if (captured.contains(vble))
+ id.select(nme.elem).ensureConforms(vble.denot(ctx.withPhase(thisPhase)).info)
+ else id
+ }
- /** If assignment is to a boxed ref type, e.g.
- *
- * intRef.elem = expr
- *
- * rewrite using a temporary var to
- *
- * val ev$n = expr
- * intRef.elem = ev$n
- *
- * That way, we avoid the problem that `expr` might contain a `try` that would
- * run on a non-empty stack (which is illegal under JVM rules). Note that LiftTry
- * has already run before, so such `try`s would not be eliminated.
- *
- * Also: If the ref type lhs is followed by a cast (can be an artifact of nested translation),
- * drop the cast.
- */
- override def transformAssign(tree: Assign)(implicit ctx: Context, info: TransformerInfo): Tree = {
- def recur(lhs: Tree): Tree = lhs match {
- case TypeApply(Select(qual, nme.asInstanceOf_), _) =>
- val Select(_, nme.elem) = qual
- recur(qual)
- case Select(_, nme.elem) if refInfo.boxedRefClasses.contains(lhs.symbol.maybeOwner) =>
- val tempDef = transformFollowing(SyntheticValDef(TempResultName.fresh(), tree.rhs))
- transformFollowing(Block(tempDef :: Nil, cpy.Assign(tree)(lhs, ref(tempDef.symbol))))
- case _ =>
- tree
- }
- recur(tree.lhs)
+ /** If assignment is to a boxed ref type, e.g.
+ *
+ * intRef.elem = expr
+ *
+ * rewrite using a temporary var to
+ *
+ * val ev$n = expr
+ * intRef.elem = ev$n
+ *
+ * That way, we avoid the problem that `expr` might contain a `try` that would
+ * run on a non-empty stack (which is illegal under JVM rules). Note that LiftTry
+ * has already run before, so such `try`s would not be eliminated.
+ *
+ * Also: If the ref type lhs is followed by a cast (can be an artifact of nested translation),
+ * drop the cast.
+ */
+ override def transformAssign(tree: Assign)(implicit ctx: Context): Tree = {
+ def recur(lhs: Tree): Tree = lhs match {
+ case TypeApply(Select(qual, nme.asInstanceOf_), _) =>
+ val Select(_, nme.elem) = qual
+ recur(qual)
+ case Select(_, nme.elem) if refInfo.boxedRefClasses.contains(lhs.symbol.maybeOwner) =>
+ val tempDef = transformFollowing(SyntheticValDef(TempResultName.fresh(), tree.rhs))
+ transformFollowing(Block(tempDef :: Nil, cpy.Assign(tree)(lhs, ref(tempDef.symbol))))
+ case _ =>
+ tree
}
+ recur(tree.lhs)
}
}
diff --git a/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala b/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala
index 92228b9a8463..cdb72fd429d8 100644
--- a/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala
+++ b/compiler/src/dotty/tools/dotc/transform/CheckReentrant.scala
@@ -3,7 +3,7 @@ package transform
import core._
import Names._
-import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, MiniPhaseTransform, TreeTransformer}
+import dotty.tools.dotc.transform.MegaPhase._
import ast.Trees._
import Flags._
import Types._
@@ -40,7 +40,7 @@ import StdNames._
* in an immutable way anyway. To do better, it would be helpful to have a type
* for immutable array.
*/
-class CheckReentrant extends MiniPhaseTransform { thisTransformer =>
+class CheckReentrant extends MiniPhase {
import ast.tpd._
override def phaseName = "checkReentrant"
@@ -87,7 +87,7 @@ class CheckReentrant extends MiniPhaseTransform { thisTransformer =>
}
}
- override def transformTemplate(tree: Template)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformTemplate(tree: Template)(implicit ctx: Context): Tree = {
if (ctx.settings.YcheckReentrant.value && tree.symbol.owner.isStaticOwner)
addVars(tree.symbol.owner.asClass)
tree
diff --git a/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala b/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala
index b1dc3b578f41..16efc0cfe52c 100644
--- a/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala
+++ b/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala
@@ -5,7 +5,7 @@ import core._
import Names._
import StdNames.nme
import Types._
-import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, MiniPhaseTransform, TreeTransformer}
+import dotty.tools.dotc.transform.MegaPhase._
import ast.Trees._
import Flags._
import Contexts.Context
@@ -34,12 +34,12 @@ import TypeUtils._
* Java8 supports those, but not vars, and JavaScript does not have interfaces at all.
* 6. `@static` Lazy vals are currently unsupported.
*/
-class CheckStatic extends MiniPhaseTransform { thisTransformer =>
+class CheckStatic extends MiniPhase {
import ast.tpd._
override def phaseName = "checkStatic"
- override def transformTemplate(tree: tpd.Template)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformTemplate(tree: tpd.Template)(implicit ctx: Context): tpd.Tree = {
val defns = tree.body.collect{case t: ValOrDefDef => t}
var hadNonStaticField = false
for(defn <- defns) {
@@ -72,7 +72,7 @@ class CheckStatic extends MiniPhaseTransform { thisTransformer =>
tree
}
- override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformSelect(tree: tpd.Select)(implicit ctx: Context): tpd.Tree = {
if (tree.symbol.hasAnnotation(defn.ScalaStaticAnnot)) {
val symbolWhitelist = tree.symbol.ownersIterator.flatMap(x => if (x.is(Flags.Module)) List(x, x.companionModule) else List(x)).toSet
def isSafeQual(t: Tree): Boolean = { // follow the desugared paths created by typer
diff --git a/compiler/src/dotty/tools/dotc/transform/ClassOf.scala b/compiler/src/dotty/tools/dotc/transform/ClassOf.scala
index e7b6977c7b5b..493ff8df638d 100644
--- a/compiler/src/dotty/tools/dotc/transform/ClassOf.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ClassOf.scala
@@ -7,7 +7,7 @@ import core.Contexts.Context
import core.StdNames.nme
import core.Symbols.{defn,TermSymbol}
import core.TypeErasure
-import TreeTransforms.{MiniPhaseTransform, TransformerInfo, TreeTransform}
+import MegaPhase._
/** Rewrite `classOf` calls as follow:
*
@@ -16,12 +16,12 @@ import TreeTransforms.{MiniPhaseTransform, TransformerInfo, TreeTransform}
* For every non-primitive class D:
* classOf[D] -> Literal(Constant(erasure(D)))
*/
-class ClassOf extends MiniPhaseTransform {
+class ClassOf extends MiniPhase {
import tpd._
override def phaseName: String = "classOf"
- override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context): Tree =
if (tree.symbol eq defn.Predef_classOf) {
val targ = tree.args.head.tpe
clsOf(targ).ensureConforms(tree.tpe).withPos(tree.pos)
diff --git a/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala b/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala
index 893e79ce0282..071b41444bfc 100644
--- a/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala
+++ b/compiler/src/dotty/tools/dotc/transform/CollectEntryPoints.scala
@@ -1,6 +1,5 @@
package dotty.tools.dotc.transform
-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
@@ -9,7 +8,7 @@ import dotty.tools.dotc.core.Symbols.NoSymbol
import scala.annotation.tailrec
import dotty.tools.dotc.core._
import Symbols._
-import dotty.tools.dotc.transform.TreeTransforms.{NXTransformations, TransformerInfo, TreeTransform, TreeTransformer}
+import dotty.tools.dotc.transform.MegaPhase._
import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Contexts.Context
import scala.collection.mutable
@@ -22,13 +21,13 @@ import StdNames._
import dotty.tools.dotc.util.Positions.Position
import dotty.tools.dotc.config.JavaPlatform
-class CollectEntryPoints extends MiniPhaseTransform {
+class CollectEntryPoints extends MiniPhase {
/** perform context-dependant initialization */
override def prepareForUnit(tree: tpd.Tree)(implicit ctx: Context) = {
entryPoints = collection.immutable.TreeSet.empty[Symbol](new SymbolOrdering())
assert(ctx.platform.isInstanceOf[JavaPlatform], "Java platform specific phase")
- this
+ ctx
}
private[this] var entryPoints: Set[Symbol] = _
@@ -36,7 +35,7 @@ class CollectEntryPoints extends MiniPhaseTransform {
def getEntryPoints = entryPoints.toList
override def phaseName: String = "collectEntryPoints"
- override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = {
if (tree.symbol.owner.isClass && isJavaEntryPoint(tree.symbol)) {
// collecting symbols for entry points here (as opposed to GenBCode where they are used)
// has the advantage of saving an additional pass over all ClassDefs.
diff --git a/compiler/src/dotty/tools/dotc/transform/Constructors.scala b/compiler/src/dotty/tools/dotc/transform/Constructors.scala
index 969f4f548a07..4954c143590f 100644
--- a/compiler/src/dotty/tools/dotc/transform/Constructors.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Constructors.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package transform
import core._
-import TreeTransforms._
+import MegaPhase._
import dotty.tools.dotc.ast.tpd._
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.StdNames._
@@ -26,7 +26,7 @@ import collection.mutable
* - also moves private fields that are accessed only from constructor
* into the constructor if possible.
*/
-class Constructors extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+class Constructors extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import tpd._
override def phaseName: String = "constructors"
@@ -78,17 +78,17 @@ class Constructors extends MiniPhaseTransform with IdentityDenotTransformer { th
}
}
- override def transformIdent(tree: tpd.Ident)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformIdent(tree: tpd.Ident)(implicit ctx: Context): tpd.Tree = {
markUsedPrivateSymbols(tree)
tree
}
- override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformSelect(tree: tpd.Select)(implicit ctx: Context): tpd.Tree = {
markUsedPrivateSymbols(tree)
tree
}
- override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context): tpd.Tree = {
if (mightBeDropped(tree.symbol)) seenPrivateVals += tree.symbol
tree
}
@@ -121,7 +121,7 @@ class Constructors extends MiniPhaseTransform with IdentityDenotTransformer { th
private final val MutableParamAccessor = allOf(Mutable, ParamAccessor)
- override def transformTemplate(tree: Template)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformTemplate(tree: Template)(implicit ctx: Context): Tree = {
val cls = ctx.owner.asClass
val constr @ DefDef(nme.CONSTRUCTOR, Nil, vparams :: Nil, _, EmptyTree) = tree.constr
@@ -158,7 +158,7 @@ class Constructors extends MiniPhaseTransform with IdentityDenotTransformer { th
}
def apply(tree: Tree, prevOwner: Symbol)(implicit ctx: Context): Tree = {
- transform(tree).changeOwnerAfter(prevOwner, constr.symbol, thisTransform)
+ transform(tree).changeOwnerAfter(prevOwner, constr.symbol, thisPhase)
}
}
@@ -200,7 +200,7 @@ class Constructors extends MiniPhaseTransform with IdentityDenotTransformer { th
dropped += sym
sym.copySymDenotation(
initFlags = sym.flags &~ Private,
- owner = constr.symbol).installAfter(thisTransform)
+ owner = constr.symbol).installAfter(thisPhase)
constrStats += intoConstr(stat, sym)
}
case DefDef(nme.CONSTRUCTOR, _, ((outerParam @ ValDef(nme.OUTER, _, _)) :: _) :: Nil, _, _) =>
diff --git a/compiler/src/dotty/tools/dotc/transform/CrossCastAnd.scala b/compiler/src/dotty/tools/dotc/transform/CrossCastAnd.scala
index 838286e81181..a50b8cb01e97 100644
--- a/compiler/src/dotty/tools/dotc/transform/CrossCastAnd.scala
+++ b/compiler/src/dotty/tools/dotc/transform/CrossCastAnd.scala
@@ -4,7 +4,7 @@ import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Flags
import dotty.tools.dotc.core.Types.{NoType, Type, AndType}
-import dotty.tools.dotc.transform.TreeTransforms._
+import dotty.tools.dotc.transform.MegaPhase._
import tpd._
import scala.collection.mutable.ListBuffer
@@ -15,11 +15,11 @@ import scala.collection.mutable.ListBuffer
* AndTypes are performed from the first component of AndType.
* This is needed for correctness of erasure. See `tests/run/PrivateAnd.scala`
*/
-class CrossCastAnd extends MiniPhaseTransform { thisTransform =>
+class CrossCastAnd extends MiniPhase {
override def phaseName: String = "crossCast"
- override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformSelect(tree: tpd.Select)(implicit ctx: Context): tpd.Tree = {
lazy val qtype = tree.qualifier.tpe.widen
val sym = tree.symbol
diff --git a/compiler/src/dotty/tools/dotc/transform/DropEmptyCompanions.scala.disabled b/compiler/src/dotty/tools/dotc/transform/DropEmptyCompanions.scala.disabled
index 7b37c5881dc9..559ce68947a0 100644
--- a/compiler/src/dotty/tools/dotc/transform/DropEmptyCompanions.scala.disabled
+++ b/compiler/src/dotty/tools/dotc/transform/DropEmptyCompanions.scala.disabled
@@ -12,8 +12,8 @@ import ast.Trees._
import collection.mutable
import Decorators._
import NameOps._
-import TreeTransforms.MiniPhaseTransform
-import dotty.tools.dotc.transform.TreeTransforms.TransformerInfo
+import MegaPhase.MiniPhase
+import dotty.tools.dotc.transform.MegaPhase.TransformerInfo
/** Remove companion objects that are empty
* Lots of constraints here:
@@ -28,12 +28,12 @@ import dotty.tools.dotc.transform.TreeTransforms.TransformerInfo
* level, so we know that all objects moved by LambdaLift and Flatten have arrived
* at their destination.
*/
-class DropEmptyCompanions extends MiniPhaseTransform { thisTransform =>
+class DropEmptyCompanions extends MiniPhase { thisTransform =>
import ast.tpd._
override def phaseName = "dropEmptyCompanions"
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Flatten])
- override def transformPackageDef(pdef: PackageDef)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformPackageDef(pdef: PackageDef)(implicit ctx: Context) = {
/** Is `tree` an empty companion object? */
def isEmptyCompanion(tree: Tree) = tree match {
diff --git a/compiler/src/dotty/tools/dotc/transform/DropInlined.scala b/compiler/src/dotty/tools/dotc/transform/DropInlined.scala
index 775663b5c261..55dec8628a48 100644
--- a/compiler/src/dotty/tools/dotc/transform/DropInlined.scala
+++ b/compiler/src/dotty/tools/dotc/transform/DropInlined.scala
@@ -3,13 +3,13 @@ package transform
import typer.Inliner
import core.Contexts.Context
-import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import MegaPhase.MiniPhase
/** Drop Inlined nodes */
-class DropInlined extends MiniPhaseTransform {
+class DropInlined extends MiniPhase {
import ast.tpd._
override def phaseName = "dropInlined"
- override def transformInlined(tree: Inlined)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformInlined(tree: Inlined)(implicit ctx: Context): Tree =
Inliner.dropInlined(tree)
}
diff --git a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala
index 4202b9f91bb4..36c22f2e2068 100644
--- a/compiler/src/dotty/tools/dotc/transform/ElimByName.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ElimByName.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core._
import DenotTransformers.InfoTransformer
import Symbols._
@@ -37,7 +37,7 @@ import ast.Trees._
* Option 2: Merge ElimByName with erasure, or have it run immediately before. This has not been
* tried yet.
*/
-class ElimByName extends TransformByNameApply with InfoTransformer { thisTransformer =>
+class ElimByName extends TransformByNameApply with InfoTransformer {
import ast.tpd._
override def phaseName: String = "elimByName"
@@ -51,13 +51,13 @@ class ElimByName extends TransformByNameApply with InfoTransformer { thisTransfo
ctx.atPhase(next) { implicit ctx => tree.select(defn.Function0_apply).appliedToNone }
else tree
- override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformIdent(tree: Ident)(implicit ctx: Context): Tree =
applyIfFunction(tree, tree)
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformSelect(tree: Select)(implicit ctx: Context): Tree =
applyIfFunction(tree, tree)
- override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
+ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context): Tree = tree match {
case TypeApply(Select(_, nme.asInstanceOf_), arg :: Nil) =>
// tree might be of form e.asInstanceOf[x.type] where x becomes a function.
// See pos/t296.scala
@@ -65,7 +65,7 @@ class ElimByName extends TransformByNameApply with InfoTransformer { thisTransfo
case _ => tree
}
- override def transformValDef(tree: ValDef)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformValDef(tree: ValDef)(implicit ctx: Context): Tree =
ctx.atPhase(next) { implicit ctx =>
if (exprBecomesFunction(tree.symbol))
cpy.ValDef(tree)(tpt = tree.tpt.withType(tree.symbol.info))
diff --git a/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala b/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala
index 913264081207..3de005fac34b 100644
--- a/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala
@@ -3,7 +3,7 @@ package transform
import ast.{Trees, tpd}
import core._, core.Decorators._
-import TreeTransforms._, Phases.Phase
+import MegaPhase._, Phases.Phase
import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTransformers._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
import TypeErasure.ErasedValueType, ValueClasses._
@@ -15,7 +15,7 @@ import TypeErasure.ErasedValueType, ValueClasses._
* of methods that now have the same signature but were not considered matching
* before erasure.
*/
-class ElimErasedValueType extends MiniPhaseTransform with InfoTransformer {
+class ElimErasedValueType extends MiniPhase with InfoTransformer {
import tpd._
@@ -57,7 +57,7 @@ class ElimErasedValueType extends MiniPhaseTransform with InfoTransformer {
def transformTypeOfTree(tree: Tree)(implicit ctx: Context): Tree =
tree.withType(elimEVT(tree.tpe))
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformApply(tree: Apply)(implicit ctx: Context): Tree = {
val Apply(fun, args) = tree
// The casts to and from ErasedValueType are no longer needed once ErasedValueType
@@ -117,23 +117,23 @@ class ElimErasedValueType extends MiniPhaseTransform with InfoTransformer {
}
}
- override def transformTypeDef(tree: TypeDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformTypeDef(tree: TypeDef)(implicit ctx: Context): Tree = {
checkNoClashes(tree.symbol)
tree
}
- override def transformInlined(tree: Inlined)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformInlined(tree: Inlined)(implicit ctx: Context): Tree =
transformTypeOfTree(tree)
// FIXME: transformIf and transformBlock won't be required anymore once #444 is fixed.
- override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformIdent(tree: Ident)(implicit ctx: Context): Tree =
transformTypeOfTree(tree)
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformSelect(tree: Select)(implicit ctx: Context): Tree =
transformTypeOfTree(tree)
- override def transformBlock(tree: Block)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformBlock(tree: Block)(implicit ctx: Context): Tree =
transformTypeOfTree(tree)
- override def transformIf(tree: If)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformIf(tree: If)(implicit ctx: Context): Tree =
transformTypeOfTree(tree)
- override def transformTypeTree(tree: TypeTree)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformTypeTree(tree: TypeTree)(implicit ctx: Context): Tree =
transformTypeOfTree(tree)
}
diff --git a/compiler/src/dotty/tools/dotc/transform/ElimJavaPackages.scala b/compiler/src/dotty/tools/dotc/transform/ElimJavaPackages.scala
index 237760c35fc3..a823ce4d7ed7 100644
--- a/compiler/src/dotty/tools/dotc/transform/ElimJavaPackages.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ElimJavaPackages.scala
@@ -4,17 +4,17 @@ import dotty.tools.dotc.ast.tpd._
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.Flags._
import dotty.tools.dotc.core.Types.{Type, TypeRef}
-import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import dotty.tools.dotc.transform.MegaPhase.MiniPhase
/**
* Eliminates syntactic references to Java packages, so that there's no chance
* they accidentally end up in the backend.
*/
-class ElimJavaPackages extends MiniPhaseTransform {
+class ElimJavaPackages extends MiniPhase {
override def phaseName: String = "elimJavaPackages"
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformSelect(tree: Select)(implicit ctx: Context): Tree = {
if (isJavaPackage(tree)) {
assert(tree.tpe.isInstanceOf[TypeRef], s"Expected tree with type TypeRef, but got ${tree.tpe.show}")
Ident(tree.tpe.asInstanceOf[TypeRef])
diff --git a/compiler/src/dotty/tools/dotc/transform/ElimOuterSelect.scala b/compiler/src/dotty/tools/dotc/transform/ElimOuterSelect.scala
index 2ef5c8192bff..cec86c88e651 100644
--- a/compiler/src/dotty/tools/dotc/transform/ElimOuterSelect.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ElimOuterSelect.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package transform
import core._
-import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import MegaPhase.MiniPhase
import Contexts.Context
import Types._
import Decorators._
@@ -12,7 +12,7 @@ import ast.Trees._
/** This phase rewrites outer selects `E.n_` which were introduced by
* inlining to outer paths.
*/
-class ElimOuterSelect extends MiniPhaseTransform { thisTransform =>
+class ElimOuterSelect extends MiniPhase {
import ast.tpd._
override def phaseName: String = "elimOuterSelect"
@@ -24,7 +24,7 @@ class ElimOuterSelect extends MiniPhaseTransform { thisTransform =>
/** Convert a selection of the form `qual.n_` to an outer path from `qual` of
* length `n`.
*/
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformSelect(tree: Select)(implicit ctx: Context) =
tree.name match {
case OuterSelectName(_, nhops) =>
val SkolemType(tp) = tree.tpe
diff --git a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala
index b4b274031b84..6ad1edfaa31e 100644
--- a/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala
@@ -5,7 +5,7 @@ import core._
import Names._
import StdNames.nme
import Types._
-import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, MiniPhaseTransform, TreeTransformer}
+import dotty.tools.dotc.transform.MegaPhase._
import ast.Trees._
import Flags._
import Contexts.Context
@@ -25,7 +25,7 @@ import TypeUtils._
/** A transformer that removes repeated parameters (T*) from all types, replacing
* them with Seq types.
*/
-class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransformer =>
+class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
import ast.tpd._
override def phaseName = "elimRepeated"
@@ -67,15 +67,15 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransfo
def transformTypeOfTree(tree: Tree)(implicit ctx: Context): Tree =
tree.withType(elimRepeated(tree.tpe))
- override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformIdent(tree: Ident)(implicit ctx: Context): Tree =
transformTypeOfTree(tree)
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformSelect(tree: Select)(implicit ctx: Context): Tree =
transformTypeOfTree(tree)
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformApply(tree: Apply)(implicit ctx: Context): Tree = {
val formals =
- ctx.atPhase(thisTransformer) { implicit ctx =>
+ ctx.atPhase(thisPhase) { implicit ctx =>
tree.fun.tpe.widen.asInstanceOf[MethodType].paramInfos
}
val args1 = tree.args.zipWithConserve(formals) { (arg, formal) =>
@@ -106,14 +106,14 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransfo
// Because of phantomclasses, the Java array's type might not conform to the return type
}
- override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context): Tree =
transformTypeOfTree(tree)
/** If method overrides a Java varargs method, add a varargs bridge.
* Also transform trees inside method annotation
*/
- override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree =
- ctx.atPhase(thisTransformer) { implicit ctx =>
+ override def transformDefDef(tree: DefDef)(implicit ctx: Context): Tree =
+ ctx.atPhase(thisPhase) { implicit ctx =>
if (tree.symbol.info.isVarArgsMethod && overridesJava(tree.symbol))
addVarArgsBridge(tree)
else
@@ -131,7 +131,7 @@ class ElimRepeated extends MiniPhaseTransform with InfoTransformer { thisTransfo
val original = ddef.symbol.asTerm
val bridge = original.copy(
flags = ddef.symbol.flags &~ Private | Artifact,
- info = toJavaVarArgs(ddef.symbol.info)).enteredAfter(thisTransformer).asTerm
+ info = toJavaVarArgs(ddef.symbol.info)).enteredAfter(thisPhase).asTerm
val bridgeDef = polyDefDef(bridge, trefs => vrefss => {
val (vrefs :+ varArgRef) :: vrefss1 = vrefss
val elemtp = varArgRef.tpe.widen.argTypes.head
diff --git a/compiler/src/dotty/tools/dotc/transform/ElimStaticThis.scala b/compiler/src/dotty/tools/dotc/transform/ElimStaticThis.scala
index 49a1df32a9e8..662e5d5c55bd 100644
--- a/compiler/src/dotty/tools/dotc/transform/ElimStaticThis.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ElimStaticThis.scala
@@ -7,24 +7,24 @@ import Flags._
import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.StdNames._
import dotty.tools.dotc.core.SymDenotations.SymDenotation
-import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import MegaPhase.MiniPhase
import dotty.tools.dotc.core.Types.{ThisType, TermRef}
/** Replace This references to module classes in static methods by global identifiers to the
* corresponding modules.
*/
-class ElimStaticThis extends MiniPhaseTransform {
+class ElimStaticThis extends MiniPhase {
import ast.tpd._
def phaseName: String = "elimStaticThis"
- override def transformThis(tree: This)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformThis(tree: This)(implicit ctx: Context): Tree =
if (!tree.symbol.is(Package) && ctx.owner.enclosingMethod.is(JavaStatic)) {
assert(tree.symbol.is(ModuleClass))
ref(tree.symbol.sourceModule)
}
else tree
- override def transformIdent(tree: tpd.Ident)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformIdent(tree: tpd.Ident)(implicit ctx: Context): tpd.Tree = {
if (ctx.owner.enclosingMethod.is(JavaStatic)) {
tree.tpe match {
case TermRef(thiz: ThisType, _) if thiz.cls.is(ModuleClass, JavaDefined) =>
diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
index 7545b36246a4..ecb40b52a910 100644
--- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
@@ -31,7 +31,7 @@ import core.Mode
import core.PhantomErasure
import reporting.trace
-class Erasure extends Phase with DenotTransformer { thisTransformer =>
+class Erasure extends Phase with DenotTransformer {
override def phaseName: String = "erasure"
diff --git a/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala b/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala
index 04b574d6fbbd..f49495c80d3f 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExpandPrivate.scala
@@ -13,10 +13,9 @@ import SymDenotations._
import Types._
import collection.mutable
-import TreeTransforms._
import Decorators._
import ast.Trees._
-import TreeTransforms._
+import MegaPhase._
import java.io.File.separatorChar
import ValueClasses._
@@ -36,7 +35,7 @@ import dotty.tools.dotc.core.Phases.Phase
* See discussion in https://github.com/lampepfl/dotty/pull/784
* and https://github.com/lampepfl/dotty/issues/783
*/
-class ExpandPrivate extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+class ExpandPrivate extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import ast.tpd._
override def phaseName: String = "expandPrivate"
@@ -74,7 +73,7 @@ class ExpandPrivate extends MiniPhaseTransform with IdentityDenotTransformer { t
*/
private def ensurePrivateAccessible(d: SymDenotation)(implicit ctx: Context) =
if (isVCPrivateParamAccessor(d))
- d.ensureNotPrivate.installAfter(thisTransform)
+ d.ensureNotPrivate.installAfter(thisPhase)
else if (d.is(PrivateTerm) && !d.owner.is(Package) && d.owner != ctx.owner.enclosingClass) {
// Paths `p1` and `p2` are similar if they have a common suffix that follows
// possibly different directory paths. That is, their common suffix extends
@@ -93,28 +92,28 @@ class ExpandPrivate extends MiniPhaseTransform with IdentityDenotTransformer { t
assert(d.symbol.sourceFile != null &&
isSimilar(d.symbol.sourceFile.path, ctx.source.file.path),
s"private ${d.symbol.showLocated} in ${d.symbol.sourceFile} accessed from ${ctx.owner.showLocated} in ${ctx.source.file}")
- d.ensureNotPrivate.installAfter(thisTransform)
+ d.ensureNotPrivate.installAfter(thisPhase)
}
- override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformIdent(tree: Ident)(implicit ctx: Context) = {
ensurePrivateAccessible(tree.symbol)
tree
}
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformSelect(tree: Select)(implicit ctx: Context) = {
ensurePrivateAccessible(tree.symbol)
tree
}
- override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformDefDef(tree: DefDef)(implicit ctx: Context) = {
val sym = tree.symbol
tree.rhs match {
case Apply(sel @ Select(_: Super, _), _)
if sym.is(PrivateParamAccessor) && sel.symbol.is(ParamAccessor) && sym.name == sel.symbol.name =>
- sym.ensureNotPrivate.installAfter(thisTransform)
+ sym.ensureNotPrivate.installAfter(thisPhase)
case _ =>
if (isVCPrivateParamAccessor(sym))
- sym.ensureNotPrivate.installAfter(thisTransform)
+ sym.ensureNotPrivate.installAfter(thisPhase)
}
tree
}
diff --git a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala
index 76ba7245d6c8..ef1aca47af89 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExpandSAMs.scala
@@ -4,7 +4,7 @@ package transform
import core._
import Contexts._, Symbols._, Types._, Flags._, Decorators._, StdNames._, Constants._
import SymDenotations.SymDenotation
-import TreeTransforms._
+import MegaPhase._
import SymUtils._
import ast.untpd
import ast.Trees._
@@ -21,7 +21,7 @@ import dotty.tools.dotc.util.Positions.Position
* 5. Closures that get synthesized abstract methods in the transformation pipeline. These methods can be
* (1) superaccessors, (2) outer references, (3) accessors for fields.
*/
-class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
+class ExpandSAMs extends MiniPhase {
override def phaseName = "expandSAMs"
import ast.tpd._
@@ -30,7 +30,7 @@ class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
def isPlatformSam(cls: ClassSymbol)(implicit ctx: Context): Boolean =
ctx.platform.isSam(cls)
- override def transformBlock(tree: Block)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
+ override def transformBlock(tree: Block)(implicit ctx: Context): Tree = tree match {
case Block(stats @ (fn: DefDef) :: Nil, Closure(_, fnRef, tpt)) if fnRef.symbol == fn.symbol =>
tpt.tpe match {
case NoType => tree // it's a plain function
@@ -50,7 +50,7 @@ class ExpandSAMs extends MiniPhaseTransform { thisTransformer =>
tree
}
- private def toPartialFunction(tree: Block)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ private def toPartialFunction(tree: Block)(implicit ctx: Context): Tree = {
val Block(
(applyDef @ DefDef(nme.ANON_FUN, Nil, List(List(param)), _, _)) :: Nil,
Closure(_, _, tpt)) = tree
diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
index 54e474888654..268123b0d3fe 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExplicitOuter.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core.DenotTransformers._
import core.Symbols._
import core.Contexts._
@@ -34,7 +34,7 @@ import scala.annotation.tailrec
* replacement of outer this by outer paths is done in Erasure.
* needs to run after pattern matcher as it can add outer checks and force creation of $outer
*/
-class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransformer =>
+class ExplicitOuter extends MiniPhase with InfoTransformer { thisPhase =>
import ExplicitOuter._
import ast.tpd._
@@ -72,7 +72,7 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf
* a separate phase which needs to run after erasure. However, we make sure here
* that the super class constructor is indeed a New, and not just a type.
*/
- override def transformTemplate(impl: Template)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformTemplate(impl: Template)(implicit ctx: Context): Tree = {
val cls = ctx.owner.asClass
val isTrait = cls.is(Trait)
if (needsOuterIfReferenced(cls) &&
@@ -97,7 +97,7 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf
for (parentTrait <- cls.mixins) {
if (needsOuterIfReferenced(parentTrait)) {
val parentTp = cls.denot.thisType.baseType(parentTrait)
- val outerAccImpl = newOuterAccessor(cls, parentTrait).enteredAfter(thisTransformer)
+ val outerAccImpl = newOuterAccessor(cls, parentTrait).enteredAfter(thisPhase)
newDefs += DefDef(outerAccImpl, singleton(fixThis(outerPrefix(parentTp))))
}
}
@@ -118,7 +118,7 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf
else impl
}
- override def transformClosure(tree: Closure)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformClosure(tree: Closure)(implicit ctx: Context): tpd.Tree = {
if (tree.tpt ne EmptyTree) {
val cls = tree.tpt.asInstanceOf[TypeTree].tpe.classSymbol
if (cls.exists && hasOuter(cls.asClass))
diff --git a/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala b/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala
index 3592471823ff..307b8ea56854 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExplicitSelf.scala
@@ -4,7 +4,7 @@ package transform
import core._
import Contexts.Context
import Types._
-import TreeTransforms._
+import MegaPhase._
import Decorators._
import ast.Trees._
import Flags._
@@ -23,19 +23,19 @@ import Flags._
*
* Also replaces idents referring to the self type with ThisTypes.
*/
-class ExplicitSelf extends MiniPhaseTransform { thisTransform =>
+class ExplicitSelf extends MiniPhase {
import ast.tpd._
override def phaseName = "explicitSelf"
- override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = tree.tpe match {
+ override def transformIdent(tree: Ident)(implicit ctx: Context) = tree.tpe match {
case tp: ThisType =>
ctx.debuglog(s"owner = ${ctx.owner}, context = ${ctx}")
This(tp.cls) withPos tree.pos
case _ => tree
}
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
+ override def transformSelect(tree: Select)(implicit ctx: Context): Tree = tree match {
case Select(thiz: This, name) if name.isTermName =>
val cls = thiz.symbol.asClass
if (cls.givenSelfType.exists && !cls.derivesFrom(tree.symbol.owner))
diff --git a/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
index d1ff4b72c938..6bb2b29ee522 100644
--- a/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ExtensionMethods.scala
@@ -5,7 +5,7 @@
package dotty.tools.dotc
package transform
-import dotty.tools.dotc.transform.TreeTransforms._
+import dotty.tools.dotc.transform.MegaPhase._
import ValueClasses._
import dotty.tools.dotc.ast.{Trees, tpd}
import scala.collection.{ mutable, immutable }
@@ -37,7 +37,7 @@ import SymUtils._
* Finally, if the constructor of a value class is private pr protected
* it is widened to public.
*/
-class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with FullParameterization { thisTransformer =>
+class ExtensionMethods extends MiniPhase with DenotTransformer with FullParameterization { thisPhase =>
import tpd._
import ExtensionMethods._
@@ -61,17 +61,17 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful
var newSuperClass: Type = null
- ctx.atPhase(thisTransformer.next) { implicit ctx =>
+ ctx.atPhase(thisPhase.next) { implicit ctx =>
// In Scala 2, extension methods are added before pickling so we should
// not generate them again.
- if (!(valueClass is Scala2x)) ctx.atPhase(thisTransformer) { implicit ctx =>
+ if (!(valueClass is Scala2x)) ctx.atPhase(thisPhase) { implicit ctx =>
for (decl <- valueClass.classInfo.decls) {
if (isMethodWithExtension(decl)) {
val meth = createExtensionMethod(decl, moduleClassSym.symbol)
decls1.enter(meth)
// Workaround #1895: force denotation of `meth` to be
// at phase where `meth` is entered into the decls of a class
- meth.denot(ctx.withPhase(thisTransformer.next))
+ meth.denot(ctx.withPhase(thisPhase.next))
}
}
}
@@ -134,7 +134,7 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful
(imeth.flags | Final) &~ (Override | Protected | AbsOverride),
fullyParameterizedType(imeth.info, imeth.owner.asClass),
privateWithin = imeth.privateWithin, coord = imeth.coord)
- extensionMeth.addAnnotations(imeth.annotations)(ctx.withPhase(thisTransformer))
+ extensionMeth.addAnnotations(imeth.annotations)(ctx.withPhase(thisPhase))
// need to change phase to add tailrec annotation which gets removed from original method in the same phase.
extensionMeth
}
@@ -143,7 +143,7 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful
// TODO: this is state and should be per-run
// todo: check that when transformation finished map is empty
- override def transformTemplate(tree: tpd.Template)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformTemplate(tree: tpd.Template)(implicit ctx: Context): tpd.Tree = {
if (isDerivedValueClass(ctx.owner)) {
/* This is currently redundant since value classes may not
wrap over other value classes anyway.
@@ -160,7 +160,7 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful
} else tree
}
- override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = {
if (isMethodWithExtension(tree.symbol)) {
val origMeth = tree.symbol
val origClass = ctx.owner.asClass
diff --git a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
index 35e2d8653d0e..e935da998cb1 100644
--- a/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
+++ b/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
@@ -5,7 +5,7 @@ import core._
import Names._
import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Phases.NeedsCompanions
-import dotty.tools.dotc.transform.TreeTransforms._
+import dotty.tools.dotc.transform.MegaPhase._
import ast.Trees._
import Flags._
import Types._
@@ -35,7 +35,7 @@ import StdNames._
* if (true) A else B ==> A
* if (false) A else B ==> B
*/
-class FirstTransform extends MiniPhaseTransform with InfoTransformer { thisTransformer =>
+class FirstTransform extends MiniPhase with InfoTransformer { thisPhase =>
import ast.tpd._
override def phaseName = "firstTransform"
@@ -47,9 +47,9 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer { thisTrans
def needsCompanion(cls: ClassSymbol)(implicit ctx: Context) =
addCompanionPhases.exists(_.isCompanionNeeded(cls))
- override def prepareForUnit(tree: tpd.Tree)(implicit ctx: Context): TreeTransform = {
+ override def prepareForUnit(tree: Tree)(implicit ctx: Context) = {
addCompanionPhases = ctx.phasePlan.flatMap(_ collect { case p: NeedsCompanions => p })
- this
+ ctx
}
/** eliminate self symbol in ClassInfo */
@@ -123,9 +123,9 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer { thisTrans
def registerCompanion(name: TermName, forClass: Symbol): TermSymbol = {
val (modul, mcCompanion, classCompanion) = newCompanion(name, forClass)
- if (ctx.owner.isClass) modul.enteredAfter(thisTransformer)
- mcCompanion.enteredAfter(thisTransformer)
- classCompanion.enteredAfter(thisTransformer)
+ if (ctx.owner.isClass) modul.enteredAfter(thisPhase)
+ mcCompanion.enteredAfter(thisPhase)
+ classCompanion.enteredAfter(thisPhase)
modul
}
@@ -157,15 +157,15 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer { thisTrans
}
/** elimiate self in Template */
- override def transformTemplate(impl: Template)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformTemplate(impl: Template)(implicit ctx: Context): Tree = {
cpy.Template(impl)(self = EmptyValDef)
}
/** Eliminate empty package definitions that may have been stored in the TASTY trees */
- override def transformPackageDef(tree: PackageDef)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformPackageDef(tree: PackageDef)(implicit ctx: Context): Tree =
if (tree.stats.isEmpty) EmptyTree else tree
- override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformDefDef(ddef: DefDef)(implicit ctx: Context) = {
if (ddef.symbol.hasAnnotation(defn.NativeAnnot)) {
ddef.symbol.resetFlag(Deferred)
DefDef(ddef.symbol.asTerm,
@@ -174,7 +174,7 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer { thisTrans
} else ddef
}
- override def transformValDef(vdef: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformValDef(vdef: tpd.ValDef)(implicit ctx: Context): tpd.Tree = {
if (vdef.tpt.tpe.isPhantom) {
if (vdef.symbol.is(Mutable)) ctx.error("var fields cannot have Phantom types", vdef.pos)
else if (vdef.symbol.hasAnnotation(defn.VolatileAnnot)) ctx.error("Phantom fields cannot be @volatile", vdef.pos)
@@ -182,36 +182,36 @@ class FirstTransform extends MiniPhaseTransform with InfoTransformer { thisTrans
vdef
}
- override def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] =
- ast.Trees.flatten(reorderAndComplete(trees)(ctx.withPhase(thisTransformer.next)))
+ override def transformStats(trees: List[Tree])(implicit ctx: Context): List[Tree] =
+ ast.Trees.flatten(reorderAndComplete(trees)(ctx.withPhase(thisPhase.next)))
- override def transformOther(tree: Tree)(implicit ctx: Context, info: TransformerInfo) = tree match {
+ override def transformOther(tree: Tree)(implicit ctx: Context) = tree match {
case tree: Import => EmptyTree
- case tree: NamedArg => transform(tree.arg)
+ case tree: NamedArg => transformAllDeep(tree.arg)
case tree => if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos) else tree
}
- override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformIdent(tree: Ident)(implicit ctx: Context) =
if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos)
else constToLiteral(tree)
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformSelect(tree: Select)(implicit ctx: Context) =
if (tree.isType) TypeTree(tree.tpe).withPos(tree.pos)
else constToLiteral(tree)
- override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context) =
constToLiteral(tree)
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformApply(tree: Apply)(implicit ctx: Context) =
constToLiteral(foldCondition(tree))
- override def transformTyped(tree: Typed)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformTyped(tree: Typed)(implicit ctx: Context) =
constToLiteral(tree)
- override def transformBlock(tree: Block)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformBlock(tree: Block)(implicit ctx: Context) =
constToLiteral(tree)
- override def transformIf(tree: If)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformIf(tree: If)(implicit ctx: Context) =
tree.cond match {
case Literal(Constant(c: Boolean)) => if (c) tree.thenp else tree.elsep
case _ => tree
diff --git a/compiler/src/dotty/tools/dotc/transform/Flatten.scala b/compiler/src/dotty/tools/dotc/transform/Flatten.scala
index 49261cc5276a..8633391ce175 100644
--- a/compiler/src/dotty/tools/dotc/transform/Flatten.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Flatten.scala
@@ -4,20 +4,27 @@ package transform
import core._
import DenotTransformers.SymTransformer
import Phases.Phase
-import Contexts.Context
+import Contexts.{Context, FreshContext}
import Flags._
import SymDenotations.SymDenotation
import collection.mutable
-import TreeTransforms.MiniPhaseTransform
-import dotty.tools.dotc.transform.TreeTransforms.TransformerInfo
+import MegaPhase.MiniPhase
+import util.Store
/** Lift nested classes to toplevel */
-class Flatten extends MiniPhaseTransform with SymTransformer { thisTransform =>
+class Flatten extends MiniPhase with SymTransformer {
import ast.tpd._
+
override def phaseName = "flatten"
override def changesMembers = true // the phase removes inner classes
+ private var LiftedDefs: Store.Location[mutable.ListBuffer[Tree]] = _
+ private def liftedDefs(implicit ctx: Context) = ctx.store(LiftedDefs)
+
+ override def initContext(ctx: FreshContext) =
+ LiftedDefs = ctx.addLocation[mutable.ListBuffer[Tree]](null)
+
def transformSym(ref: SymDenotation)(implicit ctx: Context) = {
if (ref.isClass && !ref.is(Package) && !ref.owner.is(Package)) {
ref.copySymDenotation(
@@ -27,29 +34,17 @@ class Flatten extends MiniPhaseTransform with SymTransformer { thisTransform =>
else ref
}
- private[this] var liftedDefs = new mutable.ListBuffer[Tree]
- private[this] var liftedDefsQueue = List.empty[mutable.ListBuffer[Tree]]
-
- override def prepareForPackageDef(tree: PackageDef)(implicit ctx: Context) = {
- liftedDefsQueue = liftedDefs :: liftedDefsQueue
- liftedDefs = new mutable.ListBuffer[Tree]
- this
- }
-
- override def transformPackageDef(tree: PackageDef)(implicit ctx: Context, info: TransformerInfo) = {
- liftedDefs = liftedDefsQueue.head
- liftedDefsQueue = liftedDefsQueue.tail
- tree
- }
+ override def prepareForPackageDef(tree: PackageDef)(implicit ctx: Context) =
+ ctx.fresh.updateStore(LiftedDefs, new mutable.ListBuffer[Tree])
- private def liftIfNested(tree: Tree)(implicit ctx: Context, info: TransformerInfo) =
+ private def liftIfNested(tree: Tree)(implicit ctx: Context) =
if (ctx.owner is Package) tree
else {
transformFollowing(tree).foreachInThicket(liftedDefs += _)
EmptyTree
}
- override def transformStats(stats: List[Tree])(implicit ctx: Context, info: TransformerInfo) =
+ override def transformStats(stats: List[Tree])(implicit ctx: Context) =
if (ctx.owner is Package) {
val liftedStats = stats ++ liftedDefs
liftedDefs.clear()
@@ -57,6 +52,6 @@ class Flatten extends MiniPhaseTransform with SymTransformer { thisTransform =>
}
else stats
- override def transformTypeDef(tree: TypeDef)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformTypeDef(tree: TypeDef)(implicit ctx: Context) =
liftIfNested(tree)
}
diff --git a/compiler/src/dotty/tools/dotc/transform/FunctionXXLForwarders.scala b/compiler/src/dotty/tools/dotc/transform/FunctionXXLForwarders.scala
index e67247fd8e32..feacc647f917 100644
--- a/compiler/src/dotty/tools/dotc/transform/FunctionXXLForwarders.scala
+++ b/compiler/src/dotty/tools/dotc/transform/FunctionXXLForwarders.scala
@@ -9,7 +9,7 @@ import Definitions._
import DenotTransformers._
import StdNames._
import Symbols._
-import TreeTransforms._
+import MegaPhase._
import Types._
@@ -22,12 +22,12 @@ import Types._
* `def apply(xs: Array[Object]): R = this.apply(xs(0).asInstanceOf[T1], ..., xs(n-1).asInstanceOf[Tn]).asInstanceOf[R]`
* is generated.
*/
-class FunctionXXLForwarders extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+class FunctionXXLForwarders extends MiniPhase with IdentityDenotTransformer {
import ast.tpd._
override def phaseName: String = "functionXXLForwarders"
- override def transformTemplate(impl: Template)(implicit ctx: Context, info: TransformerInfo): Template = {
+ override def transformTemplate(impl: Template)(implicit ctx: Context): Template = {
def forwarderRhs(receiver: Tree, xsTree: Tree): Tree = {
val argsApply = ref(xsTree.symbol).select(nme.apply)
diff --git a/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala b/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala
index 8166e4f35675..228e73e1d5fa 100644
--- a/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala
+++ b/compiler/src/dotty/tools/dotc/transform/FunctionalInterfaces.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core.DenotTransformers._
import core.Symbols._
import core.Contexts._
@@ -21,7 +21,7 @@ import collection.mutable.{ LinkedHashMap, LinkedHashSet, TreeSet }
/**
* Rewires closures to implement more specific types of Functions.
*/
-class FunctionalInterfaces extends MiniPhaseTransform {
+class FunctionalInterfaces extends MiniPhase {
import tpd._
def phaseName: String = "functionalInterfaces"
@@ -29,7 +29,7 @@ class FunctionalInterfaces extends MiniPhaseTransform {
val functionName = "JFunction".toTermName
val functionPackage = "scala.compat.java8.".toTermName
- override def transformClosure(tree: Closure)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformClosure(tree: Closure)(implicit ctx: Context): Tree = {
val cls = tree.tpe.widen.classSymbol.asClass
val implType = tree.meth.tpe.widen
diff --git a/compiler/src/dotty/tools/dotc/transform/GetClass.scala b/compiler/src/dotty/tools/dotc/transform/GetClass.scala
index 6a9a5fda2019..e83363d3dea0 100644
--- a/compiler/src/dotty/tools/dotc/transform/GetClass.scala
+++ b/compiler/src/dotty/tools/dotc/transform/GetClass.scala
@@ -6,7 +6,7 @@ import core.Contexts.Context
import core.StdNames.nme
import core.Phases.Phase
import TypeUtils._
-import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import MegaPhase.MiniPhase
/** Rewrite `getClass` calls as follow:
*
@@ -15,7 +15,7 @@ import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
* For every instance of non-primitive class D:
* instanceD.getClass -> instanceD.getClass
*/
-class GetClass extends MiniPhaseTransform {
+class GetClass extends MiniPhase {
import tpd._
override def phaseName: String = "getClass"
@@ -23,7 +23,7 @@ class GetClass extends MiniPhaseTransform {
// getClass transformation should be applied to specialized methods
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Erasure], classOf[FunctionalInterfaces])
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformApply(tree: Apply)(implicit ctx: Context): Tree = {
import ast.Trees._
tree match {
case Apply(Select(qual, nme.getClass_), Nil) if qual.tpe.widen.isPrimitiveValueType =>
diff --git a/compiler/src/dotty/tools/dotc/transform/Getters.scala b/compiler/src/dotty/tools/dotc/transform/Getters.scala
index 31171dfabe5e..55e68d69ff11 100644
--- a/compiler/src/dotty/tools/dotc/transform/Getters.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Getters.scala
@@ -9,7 +9,7 @@ import Types._
import Symbols._
import SymUtils._
import Constants._
-import TreeTransforms._
+import MegaPhase._
import Flags._
import Decorators._
import ValueClasses._
@@ -46,7 +46,7 @@ import ValueClasses._
*
* No fields are generated yet. This is done later in phase Memoize.
*/
-class Getters extends MiniPhaseTransform with SymTransformer { thisTransform =>
+class Getters extends MiniPhase with SymTransformer {
import ast.tpd._
override def phaseName = "getters"
@@ -68,9 +68,9 @@ class Getters extends MiniPhaseTransform with SymTransformer { thisTransform =>
}
private val NoGetterNeeded = Method | Param | JavaDefined | JavaStatic
- override def transformValDef(tree: ValDef)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformValDef(tree: ValDef)(implicit ctx: Context): Tree =
if (tree.symbol is Method) DefDef(tree.symbol.asTerm, tree.rhs).withPos(tree.pos) else tree
- override def transformAssign(tree: Assign)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformAssign(tree: Assign)(implicit ctx: Context): Tree =
if (tree.lhs.symbol is Method) tree.lhs.becomes(tree.rhs).withPos(tree.pos) else tree
}
diff --git a/compiler/src/dotty/tools/dotc/transform/HoistSuperArgs.scala b/compiler/src/dotty/tools/dotc/transform/HoistSuperArgs.scala
index 9ef36a7caf56..d0d55d735329 100644
--- a/compiler/src/dotty/tools/dotc/transform/HoistSuperArgs.scala
+++ b/compiler/src/dotty/tools/dotc/transform/HoistSuperArgs.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core.DenotTransformers._
import core.Symbols._
import core.Contexts._
@@ -37,7 +37,7 @@ import SymUtils._
* as method parameters. The definition is installed in the scope enclosing the class,
* or, if that is a package, it is made a static method of the class itself.
*/
-class HoistSuperArgs extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+class HoistSuperArgs extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import ast.tpd._
def phaseName = "hoistSuperArgs"
@@ -94,7 +94,7 @@ class HoistSuperArgs extends MiniPhaseTransform with IdentityDenotTransformer {
flags = Synthetic | Private | Method | staticFlag,
info = replaceResult(constr.info, argTypeWrtConstr),
coord = constr.coord)
- if (methOwner.isClass) meth.enteredAfter(thisTransform) else meth
+ if (methOwner.isClass) meth.enteredAfter(thisPhase) else meth
}
/** Type of a reference implies that it needs to be hoisted */
@@ -142,7 +142,7 @@ class HoistSuperArgs extends MiniPhaseTransform with IdentityDenotTransformer {
case tree =>
tree
})
- tmap(arg).changeOwnerAfter(constr, superMeth, thisTransform)
+ tmap(arg).changeOwnerAfter(constr, superMeth, thisPhase)
})
superArgDefs += superArgDef
def termParamRefs(tp: Type, params: List[Symbol]): List[List[Tree]] = tp match {
@@ -189,7 +189,7 @@ class HoistSuperArgs extends MiniPhaseTransform with IdentityDenotTransformer {
}
}
- override def transformTypeDef(tdef: TypeDef)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformTypeDef(tdef: TypeDef)(implicit ctx: Context): Tree =
tdef.rhs match {
case impl @ Template(cdef, superCall :: others, _, _) =>
val hoist = new Hoister(tdef.symbol)
diff --git a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala
index b1f384586a0b..dc14acf50f03 100644
--- a/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala
+++ b/compiler/src/dotty/tools/dotc/transform/InterceptedMethods.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core.Denotations._
import core.SymDenotations._
import core.Contexts._
@@ -16,7 +16,6 @@ import Contexts._
import Symbols._
import Decorators._
import NameOps._
-import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransformer, TreeTransform}
import dotty.tools.dotc.ast.Trees._
import dotty.tools.dotc.ast.{untpd, tpd}
import dotty.tools.dotc.core.Constants.Constant
@@ -36,9 +35,7 @@ import Phases.Phase
* using the most precise overload available
* - `x.getClass` for getClass in primitives becomes `x.getClass` with getClass in class Object.
*/
-class InterceptedMethods extends MiniPhaseTransform {
- thisTransform =>
-
+class InterceptedMethods extends MiniPhase {
import tpd._
override def phaseName: String = "intercepted"
@@ -51,11 +48,11 @@ class InterceptedMethods extends MiniPhaseTransform {
override def prepareForUnit(tree: Tree)(implicit ctx: Context) = {
this.Any_## = defn.Any_##
primitiveGetClassMethods = Set[Symbol]() ++ defn.ScalaValueClasses().map(x => x.requiredMethod(nme.getClass_))
- this
+ ctx
}
// this should be removed if we have guarantee that ## will get Apply node
- override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformSelect(tree: tpd.Select)(implicit ctx: Context): Tree = {
if (tree.symbol.isTerm && (Any_## eq tree.symbol.asTerm)) {
val rewrite = poundPoundValue(tree.qualifier)
ctx.log(s"$phaseName rewrote $tree to $rewrite")
@@ -78,7 +75,7 @@ class InterceptedMethods extends MiniPhaseTransform {
else staticsCall(nme.anyHash)
}
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformApply(tree: Apply)(implicit ctx: Context): Tree = {
def unknown = {
assert(false, s"The symbol '${tree.fun.symbol.showLocated}' was intercepted but didn't match any cases, " +
s"that means the intercepted methods set doesn't match the code")
diff --git a/compiler/src/dotty/tools/dotc/transform/IsInstanceOfEvaluator.scala b/compiler/src/dotty/tools/dotc/transform/IsInstanceOfEvaluator.scala
index 587ba1fbe398..4f6f8d3db3e4 100644
--- a/compiler/src/dotty/tools/dotc/transform/IsInstanceOfEvaluator.scala
+++ b/compiler/src/dotty/tools/dotc/transform/IsInstanceOfEvaluator.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package transform
import dotty.tools.dotc.util.Positions._
-import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import MegaPhase.MiniPhase
import core._
import Contexts.Context, Types._, Constants._, Decorators._, Symbols._
import TypeUtils._, TypeErasure._, Flags._
@@ -29,7 +29,7 @@ import TypeUtils._, TypeErasure._, Flags._
* - leave as is (`happens`)
* 2. Rewrite according to steps taken in 1
*/
-class IsInstanceOfEvaluator extends MiniPhaseTransform { thisTransformer =>
+class IsInstanceOfEvaluator extends MiniPhase {
import dotty.tools.dotc.ast.tpd._
@@ -38,7 +38,7 @@ class IsInstanceOfEvaluator extends MiniPhaseTransform { thisTransformer =>
/** Transforms a [TypeApply](dotty.tools.dotc.ast.Trees.TypeApply) in order to
* evaluate an `isInstanceOf` check according to the rules defined above.
*/
- override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context): Tree = {
val defn = ctx.definitions
/** Handles the four cases of statically known `isInstanceOf`s and gives
diff --git a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala
index f2645c5446cc..5573b8e080ec 100644
--- a/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala
+++ b/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core.DenotTransformers._
import core.Symbols._
import core.Contexts._
@@ -16,68 +16,22 @@ import core.Phases._
import ast.Trees._
import SymUtils._
import ExplicitOuter.outer
-import util.Attachment
+import util.Store
import util.Positions._
import collection.{ mutable, immutable }
import collection.mutable.{ HashMap, HashSet, LinkedHashMap, LinkedHashSet, TreeSet }
object LambdaLift {
- private class NoPath extends Exception
-}
-
-/** This phase performs the necessary rewritings to eliminate classes and methods
- * nested in other methods. In detail:
- * 1. It adds all free variables of local functions as additional parameters (proxies).
- * 2. It rebinds references to free variables to the corresponding proxies,
- * 3. It lifts all local functions and classes out as far as possible, but at least
- * to the enclosing class.
- * 4. It stores free variables of non-trait classes as additional fields of the class.
- * The fields serve as proxies for methods in the class, which avoids the need
- * of passing additional parameters to these methods.
- *
- * A particularly tricky case are local traits. These cannot store free variables
- * as field proxies, because LambdaLift runs after Mixin, so the fields cannot be
- * expanded anymore. Instead, methods of local traits get free variables of
- * the trait as additional proxy parameters. The difference between local classes
- * and local traits is illustrated by the two rewritings below.
- *
- * def f(x: Int) = { def f(x: Int) = new C(x).f2
- * class C { ==> class C(x$1: Int) {
- * def f2 = x def f2 = x$1
- * } }
- * new C().f2
- * }
- *
- * def f(x: Int) = { def f(x: Int) = new C().f2(x)
- * trait T { ==> trait T
- * def f2 = x def f2(x$1: Int) = x$1
- * } }
- * class C extends T class C extends T
- * new C().f2
- * }
- */
-class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform =>
- import LambdaLift._
import ast.tpd._
+ private class NoPath extends Exception
- /** the following two members override abstract members in Transform */
- val phaseName: String = "lambdaLift"
- val treeTransform = new LambdaLifter
-
- override def runsAfterGroupsOf: Set[Class[_ <: Phase]] = Set(classOf[Constructors], classOf[HoistSuperArgs])
- // Constructors has to happen before LambdaLift because the lambda lift logic
- // becomes simpler if it can assume that parameter accessors have already been
- // converted to parameters in super calls. Without this it is very hard to get
- // lambda lift for super calls right. Witness the implementation restrictions to
- // this effect in scalac.
-
- class LambdaLifter extends TreeTransform {
- override def phase = thisTransform
+ /** The core lambda lift functionality. */
+ class Lifter(thisPhase: MiniPhase with DenotTransformer)(implicit ctx: Context) {
private type SymSet = TreeSet[Symbol]
/** A map storing free variables of functions and classes */
- private val free = new LinkedHashMap[Symbol, SymSet]
+ val free = new LinkedHashMap[Symbol, SymSet]
/** A map storing the free variable proxies of functions and classes.
* For every function and class, this is a map from the free variables
@@ -104,7 +58,7 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
private val outerParam = new HashMap[Symbol, Symbol]
/** Buffers for lifted out classes and methods, indexed by owner */
- private val liftedDefs = new HashMap[Symbol, mutable.ListBuffer[Tree]]
+ val liftedDefs = new HashMap[Symbol, mutable.ListBuffer[Tree]]
/** A flag to indicate whether new free variables have been found */
private[this] var changedFreeVars: Boolean = _
@@ -350,7 +304,7 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
for (fv <- freeValues.toList) yield {
val proxyName = newName(fv)
val proxy = ctx.newSymbol(owner, proxyName.asTermName, newFlags, fv.info, coord = fv.coord)
- if (owner.isClass) proxy.enteredAfter(thisTransform)
+ if (owner.isClass) proxy.enteredAfter(thisPhase)
(fv, proxy)
}
}.toMap
@@ -389,28 +343,23 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
name = newName(local),
initFlags = local.flags &~ Module &~ Final | Private | maybeStatic,
// drop Module because class is no longer a singleton in the lifted context.
- info = liftedInfo(local)).installAfter(thisTransform)
+ info = liftedInfo(local)).installAfter(thisPhase)
}
for (local <- free.keys)
if (!liftedOwner.contains(local))
- local.copySymDenotation(info = liftedInfo(local)).installAfter(thisTransform)
+ local.copySymDenotation(info = liftedInfo(local)).installAfter(thisPhase)
}
- private def init(implicit ctx: Context) = {
+ // initialization
+ ctx.atPhase(thisPhase) { implicit ctx =>
(new CollectDependencies).traverse(ctx.compilationUnit.tpdTree)
computeFreeVars()
computeLiftedOwners()
- generateProxies()(ctx.withPhase(thisTransform.next))
- liftLocals()(ctx.withPhase(thisTransform.next))
+ generateProxies()(ctx.withPhase(thisPhase.next))
+ liftLocals()(ctx.withPhase(thisPhase.next))
}
- override def prepareForUnit(tree: Tree)(implicit ctx: Context) = {
- val lifter = new LambdaLifter
- lifter.init(ctx.withPhase(thisTransform))
- lifter
- }
-
- private def currentEnclosure(implicit ctx: Context) =
+ def currentEnclosure(implicit ctx: Context) =
ctx.owner.enclosingMethodOrClass
private def inCurrentOwner(sym: Symbol)(implicit ctx: Context) =
@@ -438,7 +387,7 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
if (inCurrentOwner(sym)) sym else searchIn(currentEnclosure)
}
- private def memberRef(sym: Symbol)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ def memberRef(sym: Symbol)(implicit ctx: Context): Tree = {
val clazz = sym.enclosingClass
val qual =
if (clazz.isStaticOwner || ctx.owner.enclosingClass == clazz)
@@ -449,28 +398,28 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
case _ => outer.path(toCls = clazz)
}
else outer.path(toCls = clazz)
- transformFollowingDeep(qual.select(sym))
+ thisPhase.transformFollowingDeep(qual.select(sym))
}
- private def proxyRef(sym: Symbol)(implicit ctx: Context, info: TransformerInfo): Tree = {
- val psym = proxy(sym)(ctx.withPhase(thisTransform))
- transformFollowingDeep(if (psym.owner.isTerm) ref(psym) else memberRef(psym))
+ def proxyRef(sym: Symbol)(implicit ctx: Context): Tree = {
+ val psym = proxy(sym)(ctx.withPhase(thisPhase))
+ thisPhase.transformFollowingDeep(if (psym.owner.isTerm) ref(psym) else memberRef(psym))
}
- private def addFreeArgs(sym: Symbol, args: List[Tree])(implicit ctx: Context, info: TransformerInfo) =
+ def addFreeArgs(sym: Symbol, args: List[Tree])(implicit ctx: Context) =
free get sym match {
case Some(fvs) => fvs.toList.map(proxyRef(_)) ++ args
case _ => args
}
- private def addFreeParams(tree: Tree, proxies: List[Symbol])(implicit ctx: Context, info: TransformerInfo): Tree = proxies match {
+ def addFreeParams(tree: Tree, proxies: List[Symbol])(implicit ctx: Context): Tree = proxies match {
case Nil => tree
case proxies =>
val sym = tree.symbol
val freeParamDefs = proxies.map(proxy =>
- transformFollowingDeep(ValDef(proxy.asTerm).withPos(tree.pos)).asInstanceOf[ValDef])
+ thisPhase.transformFollowingDeep(ValDef(proxy.asTerm).withPos(tree.pos)).asInstanceOf[ValDef])
def proxyInit(field: Symbol, param: Symbol) =
- transformFollowingDeep(memberRef(field).becomes(ref(param)))
+ thisPhase.transformFollowingDeep(memberRef(field).becomes(ref(param)))
/** Initialize proxy fields from proxy parameters and map `rhs` from fields to parameters */
def copyParams(rhs: Tree) = {
@@ -493,61 +442,121 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
}
}
- private def liftDef(tree: MemberDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ def liftDef(tree: MemberDef)(implicit ctx: Context): Tree = {
val buf = liftedDefs(tree.symbol.owner)
- transformFollowing(rename(tree, tree.symbol.name)).foreachInThicket(buf += _)
+ thisPhase.transformFollowing(rename(tree, tree.symbol.name)).foreachInThicket(buf += _)
EmptyTree
}
- private def needsLifting(sym: Symbol) = liftedOwner contains sym
-
- override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = {
- val sym = tree.symbol
- tree.tpe match {
- case tpe @ TermRef(prefix, _) =>
- if (prefix eq NoPrefix)
- if (sym.enclosure != currentEnclosure && !sym.isStatic)
- (if (sym is Method) memberRef(sym) else proxyRef(sym)).withPos(tree.pos)
- else if (sym.owner.isClass) // sym was lifted out
- ref(sym).withPos(tree.pos)
- else
- tree
- else if (!prefixIsElidable(tpe)) ref(tpe)
- else tree
- case _ =>
- tree
- }
- }
+ def needsLifting(sym: Symbol) = liftedOwner contains sym
+ }
+}
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo) =
- cpy.Apply(tree)(tree.fun, addFreeArgs(tree.symbol, tree.args)).withPos(tree.pos)
+/** This phase performs the necessary rewritings to eliminate classes and methods
+ * nested in other methods. In detail:
+ * 1. It adds all free variables of local functions as additional parameters (proxies).
+ * 2. It rebinds references to free variables to the corresponding proxies,
+ * 3. It lifts all local functions and classes out as far as possible, but at least
+ * to the enclosing class.
+ * 4. It stores free variables of non-trait classes as additional fields of the class.
+ * The fields serve as proxies for methods in the class, which avoids the need
+ * of passing additional parameters to these methods.
+ *
+ * A particularly tricky case are local traits. These cannot store free variables
+ * as field proxies, because LambdaLift runs after Mixin, so the fields cannot be
+ * expanded anymore. Instead, methods of local traits get free variables of
+ * the trait as additional proxy parameters. The difference between local classes
+ * and local traits is illustrated by the two rewritings below.
+ *
+ * def f(x: Int) = { def f(x: Int) = new C(x).f2
+ * class C { ==> class C(x$1: Int) {
+ * def f2 = x def f2 = x$1
+ * } }
+ * new C().f2
+ * }
+ *
+ * def f(x: Int) = { def f(x: Int) = new C().f2(x)
+ * trait T { ==> trait T
+ * def f2 = x def f2(x$1: Int) = x$1
+ * } }
+ * class C extends T class C extends T
+ * new C().f2
+ * }
+ */
+class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisPhase =>
+ import LambdaLift._
+ import ast.tpd._
- override def transformClosure(tree: Closure)(implicit ctx: Context, info: TransformerInfo) =
- cpy.Closure(tree)(env = addFreeArgs(tree.meth.symbol, tree.env))
+ /** the following two members override abstract members in Transform */
+ val phaseName: String = "lambdaLift"
- override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo) = {
- val sym = tree.symbol
- val paramsAdded =
- if (free.contains(sym)) addFreeParams(tree, proxies(sym)).asInstanceOf[DefDef]
- else tree
- if (needsLifting(sym)) liftDef(paramsAdded)
- else paramsAdded
- }
+ override def relaxedTypingInGroup = true
+
+ override def runsAfterGroupsOf: Set[Class[_ <: Phase]] = Set(classOf[Constructors], classOf[HoistSuperArgs])
+ // Constructors has to happen before LambdaLift because the lambda lift logic
+ // becomes simpler if it can assume that parameter accessors have already been
+ // converted to parameters in super calls. Without this it is very hard to get
+ // lambda lift for super calls right. Witness the implementation restrictions to
+ // this effect in scalac.
- override def transformReturn(tree: Return)(implicit ctx: Context, info: TransformerInfo) = tree.expr match {
- case Block(stats, value) =>
- Block(stats, Return(value, tree.from)).withPos(tree.pos)
+ private var Lifter: Store.Location[Lifter] = _
+ private def lifter(implicit ctx: Context) = ctx.store(Lifter)
+
+ override def initContext(ctx: FreshContext) =
+ Lifter = ctx.addLocation[Lifter]()
+
+ override def prepareForUnit(tree: Tree)(implicit ctx: Context) =
+ ctx.fresh.updateStore(Lifter, new Lifter(thisPhase))
+
+ override def transformIdent(tree: Ident)(implicit ctx: Context) = {
+ val sym = tree.symbol
+ tree.tpe match {
+ case tpe @ TermRef(prefix, _) =>
+ val lft = lifter
+ if (prefix eq NoPrefix)
+ if (sym.enclosure != lft.currentEnclosure && !sym.isStatic)
+ (if (sym is Method) lft.memberRef(sym) else lft.proxyRef(sym)).withPos(tree.pos)
+ else if (sym.owner.isClass) // sym was lifted out
+ ref(sym).withPos(tree.pos)
+ else
+ tree
+ else if (!prefixIsElidable(tpe)) ref(tpe)
+ else tree
case _ =>
tree
}
+ }
- override def transformTemplate(tree: Template)(implicit ctx: Context, info: TransformerInfo) = {
- val cls = ctx.owner
- val impl = addFreeParams(tree, proxies(cls)).asInstanceOf[Template]
- cpy.Template(impl)(body = impl.body ++ liftedDefs.remove(cls).get)
- }
+ override def transformApply(tree: Apply)(implicit ctx: Context) =
+ cpy.Apply(tree)(tree.fun, lifter.addFreeArgs(tree.symbol, tree.args)).withPos(tree.pos)
- override def transformTypeDef(tree: TypeDef)(implicit ctx: Context, info: TransformerInfo) =
- if (needsLifting(tree.symbol)) liftDef(tree) else tree
+ override def transformClosure(tree: Closure)(implicit ctx: Context) =
+ cpy.Closure(tree)(env = lifter.addFreeArgs(tree.meth.symbol, tree.env))
+
+ override def transformDefDef(tree: DefDef)(implicit ctx: Context) = {
+ val sym = tree.symbol
+ val lft = lifter
+ val paramsAdded =
+ if (lft.free.contains(sym)) lft.addFreeParams(tree, lft.proxies(sym)).asInstanceOf[DefDef]
+ else tree
+ if (lft.needsLifting(sym)) lft.liftDef(paramsAdded)
+ else paramsAdded
+ }
+
+ override def transformReturn(tree: Return)(implicit ctx: Context) = tree.expr match {
+ case Block(stats, value) =>
+ Block(stats, Return(value, tree.from)).withPos(tree.pos)
+ case _ =>
+ tree
}
+
+ override def transformTemplate(tree: Template)(implicit ctx: Context) = {
+ val cls = ctx.owner
+ val lft = lifter
+ val impl = lft.addFreeParams(tree, lft.proxies(cls)).asInstanceOf[Template]
+ cpy.Template(impl)(body = impl.body ++ lft.liftedDefs.remove(cls).get)
+ }
+
+ override def transformTypeDef(tree: TypeDef)(implicit ctx: Context) =
+ if (lifter.needsLifting(tree.symbol)) lifter.liftDef(tree) else tree
}
diff --git a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
index 94b046d317df..0f930b353e36 100644
--- a/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
+++ b/compiler/src/dotty/tools/dotc/transform/LazyVals.scala
@@ -14,7 +14,7 @@ import NameKinds._
import StdNames.nme
import rewrite.Rewrites.patch
import util.Positions.Position
-import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransformer, MiniPhaseTransform}
+import dotty.tools.dotc.transform.MegaPhase._
import dotty.tools.dotc.ast.Trees._
import dotty.tools.dotc.ast.{untpd, tpd}
import dotty.tools.dotc.core.Constants.Constant
@@ -27,7 +27,7 @@ import dotty.tools.dotc.core.SymDenotations.SymDenotation
import dotty.tools.dotc.core.DenotTransformers.{SymTransformer, IdentityDenotTransformer, DenotTransformer}
import Erasure.Boxing.adaptToType
-class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
+class LazyVals extends MiniPhase with IdentityDenotTransformer {
import LazyVals._
import tpd._
@@ -51,15 +51,15 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
val containerFlagsMask = Flags.Method | Flags.Lazy | Flags.Accessor | Flags.Module
- override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree =
+ override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree =
transformLazyVal(tree)
- override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context): tpd.Tree = {
transformLazyVal(tree)
}
- def transformLazyVal(tree: ValOrDefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ def transformLazyVal(tree: ValOrDefDef)(implicit ctx: Context): Tree = {
val sym = tree.symbol
if (!(sym is Flags.Lazy) || sym.owner.is(Flags.Trait) || (sym.isStatic && sym.is(Flags.Module))) tree
else {
@@ -85,7 +85,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
/** Append offset fields to companion objects
*/
- override def transformTemplate(template: tpd.Template)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformTemplate(template: tpd.Template)(implicit ctx: Context): tpd.Tree = {
val cls = ctx.owner.asClass
appendOffsetDefs.get(cls) match {
@@ -162,7 +162,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
}
- override def transformStats(trees: List[tpd.Tree])(implicit ctx: Context, info: TransformerInfo): List[tpd.Tree] = {
+ override def transformStats(trees: List[tpd.Tree])(implicit ctx: Context): List[tpd.Tree] = {
// backend requires field usage to be after field definition
// need to bring containers to start of method
val (holders, stats) =
diff --git a/compiler/src/dotty/tools/dotc/transform/LiftTry.scala b/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
index 278868131c20..f42131b88153 100644
--- a/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
+++ b/compiler/src/dotty/tools/dotc/transform/LiftTry.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core.DenotTransformers._
import core.Symbols._
import core.Contexts._
@@ -10,6 +10,7 @@ import core.Flags._
import core.Decorators._
import core.NameKinds.LiftedTreeName
import NonLocalReturns._
+import util.Store
/** Lifts try's that might be executed on non-empty expression stacks
* to their own methods. I.e.
@@ -20,48 +21,50 @@ import NonLocalReturns._
*
* { def liftedTree$n() = try body catch handler; liftedTree$n() }
*/
-class LiftTry extends MiniPhase with IdentityDenotTransformer { thisTransform =>
+class LiftTry extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import ast.tpd._
/** the following two members override abstract members in Transform */
val phaseName: String = "liftTry"
- val treeTransform = new Transform(needLift = false)
- val liftingTransform = new Transform(needLift = true)
+ private var NeedLift: Store.Location[Boolean] = _
+ private def needLift(implicit ctx: Context): Boolean = ctx.store(NeedLift)
- class Transform(needLift: Boolean) extends TreeTransform {
- def phase = thisTransform
+ override def initContext(ctx: FreshContext) =
+ NeedLift = ctx.addLocation(false)
- override def prepareForApply(tree: Apply)(implicit ctx: Context) =
- if (tree.fun.symbol.is(Label)) this
- else liftingTransform
+ private def liftingCtx(p: Boolean)(implicit ctx: Context) =
+ if (needLift == p) ctx else ctx.fresh.updateStore(NeedLift, p)
- override def prepareForValDef(tree: ValDef)(implicit ctx: Context) =
- if (!tree.symbol.exists ||
- tree.symbol.isSelfSym ||
- tree.symbol.owner == ctx.owner.enclosingMethod) this
- else liftingTransform
+ override def prepareForApply(tree: Apply)(implicit ctx: Context) =
+ if (tree.fun.symbol.is(Label)) ctx
+ else liftingCtx(true)
- override def prepareForAssign(tree: Assign)(implicit ctx: Context) =
- if (tree.lhs.symbol.maybeOwner == ctx.owner.enclosingMethod) this
- else liftingTransform
+ override def prepareForValDef(tree: ValDef)(implicit ctx: Context) =
+ if (!tree.symbol.exists ||
+ tree.symbol.isSelfSym ||
+ tree.symbol.owner == ctx.owner.enclosingMethod) ctx
+ else liftingCtx(true)
- override def prepareForReturn(tree: Return)(implicit ctx: Context) =
- if (!isNonLocalReturn(tree)) this
- else liftingTransform
+ override def prepareForAssign(tree: Assign)(implicit ctx: Context) =
+ if (tree.lhs.symbol.maybeOwner == ctx.owner.enclosingMethod) ctx
+ else liftingCtx(true)
- override def prepareForTemplate(tree: Template)(implicit ctx: Context) =
- treeTransform
+ override def prepareForReturn(tree: Return)(implicit ctx: Context) =
+ if (!isNonLocalReturn(tree)) ctx
+ else liftingCtx(true)
- override def transformTry(tree: Try)(implicit ctx: Context, info: TransformerInfo): Tree =
- if (needLift) {
- ctx.debuglog(i"lifting tree at ${tree.pos}, current owner = ${ctx.owner}")
- val fn = ctx.newSymbol(
- ctx.owner, LiftedTreeName.fresh(), Synthetic | Method,
- MethodType(Nil, tree.tpe.widenIfUnstable), coord = tree.pos)
- tree.changeOwnerAfter(ctx.owner, fn, thisTransform)
- Block(DefDef(fn, tree) :: Nil, ref(fn).appliedToNone)
- }
- else tree
- }
+ override def prepareForTemplate(tree: Template)(implicit ctx: Context) =
+ liftingCtx(false)
+
+ override def transformTry(tree: Try)(implicit ctx: Context): Tree =
+ if (needLift) {
+ ctx.debuglog(i"lifting tree at ${tree.pos}, current owner = ${ctx.owner}")
+ val fn = ctx.newSymbol(
+ ctx.owner, LiftedTreeName.fresh(), Synthetic | Method,
+ MethodType(Nil, tree.tpe.widenIfUnstable), coord = tree.pos)
+ tree.changeOwnerAfter(ctx.owner, fn, thisPhase)
+ Block(DefDef(fn, tree) :: Nil, ref(fn).appliedToNone)
+ }
+ else tree
}
diff --git a/compiler/src/dotty/tools/dotc/transform/LinkScala2Impls.scala b/compiler/src/dotty/tools/dotc/transform/LinkScala2Impls.scala
index 180e48e5f84b..4b1b93ab63f4 100644
--- a/compiler/src/dotty/tools/dotc/transform/LinkScala2Impls.scala
+++ b/compiler/src/dotty/tools/dotc/transform/LinkScala2Impls.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package transform
import core._
-import TreeTransforms._
+import MegaPhase._
import Contexts.Context
import Flags._
import SymUtils._
@@ -34,82 +34,77 @@ import collection.mutable
*
* where f is a static member of M.
*/
-class LinkScala2Impls extends MiniPhase with IdentityDenotTransformer { thisTransform =>
+class LinkScala2Impls extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import ast.tpd._
override def phaseName: String = "linkScala2Impls"
override def changesMembers = true
- val treeTransform = new Transform
override def runsAfterGroupsOf: Set[Class[_ <: Phase]] = Set(classOf[Mixin])
// Adds as a side effect static members to traits which can confuse Mixin,
// that's why it is runsAfterGroupOf
- class Transform extends TreeTransform {
- def phase = thisTransform
-
- /** Copy definitions from implementation class to trait itself */
- private def augmentScala_2_12_Trait(mixin: ClassSymbol)(implicit ctx: Context): Unit = {
- def info_2_12(sym: Symbol) = sym.info match {
- case mt @ MethodType(paramNames @ nme.SELF :: _) =>
- // 2.12 seems to always assume the enclsing mixin class as self type parameter,
- // whereas 2.11 used the self type of this class instead.
- val selfType :: otherParamTypes = mt.paramInfos
- MethodType(paramNames, mixin.typeRef :: otherParamTypes, mt.resType)
- case info => info
- }
- def newImpl(sym: TermSymbol): Symbol = sym.copy(
- owner = mixin,
- name = if (sym.isConstructor) sym.name else ImplMethName(sym.name),
- info = info_2_12(sym)
- )
- for (sym <- mixin.implClass.info.decls)
- newImpl(sym.asTerm).enteredAfter(thisTransform)
- }
-
- override def prepareForTemplate(impl: Template)(implicit ctx: Context) = {
- val cls = impl.symbol.owner.asClass
- for (mixin <- cls.mixins)
- if (mixin.is(Scala_2_12_Trait, butNot = Scala_2_12_Augmented)) {
- augmentScala_2_12_Trait(mixin)
- mixin.setFlag(Scala_2_12_Augmented)
- }
- this
+ /** Copy definitions from implementation class to trait itself */
+ private def augmentScala_2_12_Trait(mixin: ClassSymbol)(implicit ctx: Context): Unit = {
+ def info_2_12(sym: Symbol) = sym.info match {
+ case mt @ MethodType(paramNames @ nme.SELF :: _) =>
+ // 2.12 seems to always assume the enclsing mixin class as self type parameter,
+ // whereas 2.11 used the self type of this class instead.
+ val selfType :: otherParamTypes = mt.paramInfos
+ MethodType(paramNames, mixin.typeRef :: otherParamTypes, mt.resType)
+ case info => info
}
+ def newImpl(sym: TermSymbol): Symbol = sym.copy(
+ owner = mixin,
+ name = if (sym.isConstructor) sym.name else ImplMethName(sym.name),
+ info = info_2_12(sym)
+ )
+ for (sym <- mixin.implClass.info.decls)
+ newImpl(sym.asTerm).enteredAfter(thisPhase)
+ }
- override def transformApply(app: Apply)(implicit ctx: Context, info: TransformerInfo) = {
- def currentClass = ctx.owner.enclosingClass.asClass
- app match {
- case Apply(sel @ Select(Super(_, _), _), args)
- if sel.symbol.owner.is(Scala2xTrait) && currentClass.mixins.contains(sel.symbol.owner) =>
- val impl = implMethod(sel.symbol)
- if (impl.exists) Apply(ref(impl), This(currentClass) :: args).withPos(app.pos)
- else app // could have been an abstract method in a trait linked to from a super constructor
- case Apply(sel, args)
- if sel.symbol.maybeOwner.is(ImplClass) && sel.symbol.owner.traitOfImplClass.is(Scala_2_12_Trait) =>
- val impl = implMethod(sel.symbol)
- cpy.Apply(app)(ref(impl), args)
- case _ =>
- app
+ override def prepareForTemplate(impl: Template)(implicit ctx: Context) = {
+ val cls = impl.symbol.owner.asClass
+ for (mixin <- cls.mixins)
+ if (mixin.is(Scala_2_12_Trait, butNot = Scala_2_12_Augmented)) {
+ augmentScala_2_12_Trait(mixin)
+ mixin.setFlag(Scala_2_12_Augmented)
}
- }
+ ctx
+ }
- /** The 2.12 implementation method of a super call or implementation class target */
- private def implMethod(meth: Symbol)(implicit ctx: Context): Symbol = {
- val implName = ImplMethName(meth.name.asTermName)
- val cls = meth.owner
- if (cls.is(ImplClass))
- cls.traitOfImplClass.info.decl(implName).atSignature(meth.signature).symbol
- else if (cls.is(Scala_2_12_Trait))
- if (meth.isConstructor)
- cls.info.decl(nme.TRAIT_CONSTRUCTOR).symbol
- else
- cls.info.decl(implName)
- .suchThat(c => FullParameterization.memberSignature(c.info) == meth.signature)
- .symbol
- else throw new AssertionError(i"no impl method for $meth")
+ override def transformApply(app: Apply)(implicit ctx: Context) = {
+ def currentClass = ctx.owner.enclosingClass.asClass
+ app match {
+ case Apply(sel @ Select(Super(_, _), _), args)
+ if sel.symbol.owner.is(Scala2xTrait) && currentClass.mixins.contains(sel.symbol.owner) =>
+ val impl = implMethod(sel.symbol)
+ if (impl.exists) Apply(ref(impl), This(currentClass) :: args).withPos(app.pos)
+ else app // could have been an abstract method in a trait linked to from a super constructor
+ case Apply(sel, args)
+ if sel.symbol.maybeOwner.is(ImplClass) && sel.symbol.owner.traitOfImplClass.is(Scala_2_12_Trait) =>
+ val impl = implMethod(sel.symbol)
+ cpy.Apply(app)(ref(impl), args)
+ case _ =>
+ app
}
}
+ /** The 2.12 implementation method of a super call or implementation class target */
+ private def implMethod(meth: Symbol)(implicit ctx: Context): Symbol = {
+ val implName = ImplMethName(meth.name.asTermName)
+ val cls = meth.owner
+ if (cls.is(ImplClass))
+ cls.traitOfImplClass.info.decl(implName).atSignature(meth.signature).symbol
+ else if (cls.is(Scala_2_12_Trait))
+ if (meth.isConstructor)
+ cls.info.decl(nme.TRAIT_CONSTRUCTOR).symbol
+ else
+ cls.info.decl(implName)
+ .suchThat(c => FullParameterization.memberSignature(c.info) == meth.signature)
+ .symbol
+ else throw new AssertionError(i"no impl method for $meth")
+ }
+
private val Scala2xTrait = allOf(Scala2x, Trait)
}
diff --git a/compiler/src/dotty/tools/dotc/transform/Literalize.scala.disabled b/compiler/src/dotty/tools/dotc/transform/Literalize.scala.disabled
index f33baa52b810..8d2b06e24462 100644
--- a/compiler/src/dotty/tools/dotc/transform/Literalize.scala.disabled
+++ b/compiler/src/dotty/tools/dotc/transform/Literalize.scala.disabled
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core.DenotTransformers._
import core.Symbols._
import core.Contexts._
@@ -20,7 +20,7 @@ import dotty.tools.dotc.core.Constants._
* The phase also makes sure that the constant of a literal is the same as the constant
* in the type of the literal.
*/
-class Literalize extends MiniPhaseTransform { thisTransform =>
+class Literalize extends MiniPhase { thisTransform =>
import ast.tpd._
override def phaseName: String = "literalize"
@@ -60,19 +60,19 @@ class Literalize extends MiniPhaseTransform { thisTransform =>
recur(tree.tpe)
}
- override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformIdent(tree: Ident)(implicit ctx: Context): Tree =
literalize(tree)
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformSelect(tree: Select)(implicit ctx: Context): Tree =
literalize(tree)
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformApply(tree: Apply)(implicit ctx: Context): Tree =
literalize(tree)
- override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context): Tree =
literalize(tree)
- override def transformLiteral(tree: Literal)(implicit ctx: Context, info: TransformerInfo): Tree = tree.tpe match {
+ override def transformLiteral(tree: Literal)(implicit ctx: Context): Tree = tree.tpe match {
case ConstantType(const) if tree.const.value != const.value || (tree.const.tag != const.tag) => Literal(const)
case _ => tree
}
diff --git a/compiler/src/dotty/tools/dotc/transform/MegaPhase.scala b/compiler/src/dotty/tools/dotc/transform/MegaPhase.scala
new file mode 100644
index 000000000000..4c24eb0c6144
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/transform/MegaPhase.scala
@@ -0,0 +1,645 @@
+package dotty.tools
+package dotc
+package transform
+
+import core._
+import ast.Trees._
+import Contexts._, Phases._, Periods._, Symbols._, Decorators._
+import Flags.PackageVal
+import scala.annotation.tailrec
+import config.Printers.transforms
+import scala.util.control.NonFatal
+import reporting.trace
+import annotation.switch
+
+/** A MegaPhase combines a number of mini-phases which are all executed in
+ * a single tree traversal.
+ *
+ * This is an evolution of the previous "TreeTransformers.scala", which was written by @DarkDimius and
+ * is described in his thesis.
+ */
+object MegaPhase {
+ import ast.tpd._
+
+ /** The base class of tree transforms. For each kind of tree K, there are
+ * two methods which can be overridden:
+ *
+ * prepareForK: return a new Context which gets passed to the node and its children
+ * transformK // transform node of type K
+ *
+ * There are also prepare/transform hooks for
+ *
+ * - Stats: to prepare/transform a statement sequence in a block, template, or package def,
+ * - Unit : to prepare/transform a whole compilation unit
+ * - Other: to prepape/transform a tree that does not have a specific prepare/transform
+ * method pair.
+ */
+ abstract class MiniPhase extends Phase {
+
+ private[MegaPhase] var superPhase: MegaPhase = _
+ private[MegaPhase] var idxInGroup: Int = _
+
+ /** List of names of phases that should have finished their processing of all compilation units
+ * before this phase starts
+ */
+ def runsAfterGroupsOf: Set[Class[_ <: Phase]] = Set.empty
+
+ final override def relaxedTyping = superPhase.relaxedTyping
+
+ /** If set, use relaxed typing for all phases in group */
+ def relaxedTypingInGroup = false
+
+ val cpy: TypedTreeCopier = cpyBetweenPhases
+
+ def prepareForIdent(tree: Ident)(implicit ctx: Context): Context = ctx
+ def prepareForSelect(tree: Select)(implicit ctx: Context): Context = ctx
+ def prepareForThis(tree: This)(implicit ctx: Context) = ctx
+ def prepareForSuper(tree: Super)(implicit ctx: Context) = ctx
+ def prepareForApply(tree: Apply)(implicit ctx: Context) = ctx
+ def prepareForTypeApply(tree: TypeApply)(implicit ctx: Context) = ctx
+ def prepareForLiteral(tree: Literal)(implicit ctx: Context) = ctx
+ def prepareForNew(tree: New)(implicit ctx: Context) = ctx
+ def prepareForTyped(tree: Typed)(implicit ctx: Context) = ctx
+ def prepareForAssign(tree: Assign)(implicit ctx: Context) = ctx
+ def prepareForBlock(tree: Block)(implicit ctx: Context) = ctx
+ def prepareForIf(tree: If)(implicit ctx: Context) = ctx
+ def prepareForClosure(tree: Closure)(implicit ctx: Context) = ctx
+ def prepareForMatch(tree: Match)(implicit ctx: Context) = ctx
+ def prepareForCaseDef(tree: CaseDef)(implicit ctx: Context) = ctx
+ def prepareForReturn(tree: Return)(implicit ctx: Context) = ctx
+ def prepareForTry(tree: Try)(implicit ctx: Context) = ctx
+ def prepareForSeqLiteral(tree: SeqLiteral)(implicit ctx: Context) = ctx
+ def prepareForInlined(tree: Inlined)(implicit ctx: Context) = ctx
+ def prepareForTypeTree(tree: TypeTree)(implicit ctx: Context) = ctx
+ def prepareForBind(tree: Bind)(implicit ctx: Context) = ctx
+ def prepareForAlternative(tree: Alternative)(implicit ctx: Context) = ctx
+ def prepareForUnApply(tree: UnApply)(implicit ctx: Context) = ctx
+ def prepareForValDef(tree: ValDef)(implicit ctx: Context) = ctx
+ def prepareForDefDef(tree: DefDef)(implicit ctx: Context) = ctx
+ def prepareForTypeDef(tree: TypeDef)(implicit ctx: Context) = ctx
+ def prepareForTemplate(tree: Template)(implicit ctx: Context) = ctx
+ def prepareForPackageDef(tree: PackageDef)(implicit ctx: Context) = ctx
+ def prepareForStats(trees: List[Tree])(implicit ctx: Context) = ctx
+ def prepareForUnit(tree: Tree)(implicit ctx: Context) = ctx
+ def prepareForOther(tree: Tree)(implicit ctx: Context) = ctx
+
+ def transformIdent(tree: Ident)(implicit ctx: Context): Tree = tree
+ def transformSelect(tree: Select)(implicit ctx: Context): Tree = tree
+ def transformThis(tree: This)(implicit ctx: Context): Tree = tree
+ def transformSuper(tree: Super)(implicit ctx: Context): Tree = tree
+ def transformApply(tree: Apply)(implicit ctx: Context): Tree = tree
+ def transformTypeApply(tree: TypeApply)(implicit ctx: Context): Tree = tree
+ def transformLiteral(tree: Literal)(implicit ctx: Context): Tree = tree
+ def transformNew(tree: New)(implicit ctx: Context): Tree = tree
+ def transformTyped(tree: Typed)(implicit ctx: Context): Tree = tree
+ def transformAssign(tree: Assign)(implicit ctx: Context): Tree = tree
+ def transformBlock(tree: Block)(implicit ctx: Context): Tree = tree
+ def transformIf(tree: If)(implicit ctx: Context): Tree = tree
+ def transformClosure(tree: Closure)(implicit ctx: Context): Tree = tree
+ def transformMatch(tree: Match)(implicit ctx: Context): Tree = tree
+ def transformCaseDef(tree: CaseDef)(implicit ctx: Context): Tree = tree
+ def transformReturn(tree: Return)(implicit ctx: Context): Tree = tree
+ def transformTry(tree: Try)(implicit ctx: Context): Tree = tree
+ def transformSeqLiteral(tree: SeqLiteral)(implicit ctx: Context): Tree = tree
+ def transformInlined(tree: Inlined)(implicit ctx: Context): Tree = tree
+ def transformTypeTree(tree: TypeTree)(implicit ctx: Context): Tree = tree
+ def transformBind(tree: Bind)(implicit ctx: Context): Tree = tree
+ def transformAlternative(tree: Alternative)(implicit ctx: Context): Tree = tree
+ def transformUnApply(tree: UnApply)(implicit ctx: Context): Tree = tree
+ def transformValDef(tree: ValDef)(implicit ctx: Context): Tree = tree
+ def transformDefDef(tree: DefDef)(implicit ctx: Context): Tree = tree
+ def transformTypeDef(tree: TypeDef)(implicit ctx: Context): Tree = tree
+ def transformTemplate(tree: Template)(implicit ctx: Context): Tree = tree
+ def transformPackageDef(tree: PackageDef)(implicit ctx: Context): Tree = tree
+ def transformStats(trees: List[Tree])(implicit ctx: Context): List[Tree] = trees
+ def transformUnit(tree: Tree)(implicit ctx: Context): Tree = tree
+ def transformOther(tree: Tree)(implicit ctx: Context): Tree = tree
+
+ /** Transform tree using all transforms of current group (including this one) */
+ def transformAllDeep(tree: Tree)(implicit ctx: Context): Tree =
+ superPhase.transformTree(tree, 0)
+
+ /** Transform tree using all transforms following the current one in this group */
+ def transformFollowingDeep(tree: Tree)(implicit ctx: Context): Tree =
+ superPhase.transformTree(tree, idxInGroup + 1)
+
+ /** Transform single node using all transforms following the current one in this group */
+ def transformFollowing(tree: Tree)(implicit ctx: Context): Tree =
+ superPhase.transformNode(tree, idxInGroup + 1)
+
+ protected def singletonGroup = new MegaPhase(Array(this))
+
+ override def run(implicit ctx: Context): Unit =
+ singletonGroup.run
+ }
+
+ private type Transformer[-T, R] = (T, Context) => R
+ private type IndexedTransformer[-T, R] = MiniPhase => Transformer[T, R]
+
+ private val idNodeTransformer: Transformer[AnyRef, AnyRef] = (t, ctx) => t
+ private val idContextTransformer: Transformer[AnyRef, Context] = (t, ctx) => ctx
+}
+import MegaPhase._
+
+class MegaPhase(val miniPhases: Array[MiniPhase]) extends Phase {
+ import ast.tpd._
+
+ override val phaseName =
+ if (miniPhases.length == 1) miniPhases(0).phaseName
+ else miniPhases.map(_.phaseName).mkString("MegaPhase{", ", ", "}")
+
+ private var relaxedTypingCache: Boolean = _
+ private var relaxedTypingKnown = false
+
+ override final def relaxedTyping = {
+ if (!relaxedTypingKnown) {
+ relaxedTypingCache = miniPhases.exists(_.relaxedTypingInGroup)
+ relaxedTypingKnown = true
+ }
+ relaxedTypingCache
+ }
+
+ private val cpy: TypedTreeCopier = cpyBetweenPhases
+
+ /** Transform node using all phases in this group that have idxInGroup >= start */
+ def transformNode(tree: Tree, start: Int)(implicit ctx: Context) =
+ nodeTransformer(tree.tag)(start)(tree, ctx)
+
+ /** Transform full tree using all phases in this group that have idxInGroup >= start */
+ def transformTree(tree: Tree, start: Int)(implicit ctx: Context): Tree = {
+ val tag = tree.tag
+ val nestedCtx = contextTransformer(tag)(start)(tree, ctx)
+ val transformer = nodeTransformer(tag)(start)
+
+ def trans(tree: Tree)(implicit ctx: Context) = transformer(tree, ctx)
+
+ def localContext(implicit ctx: Context) = {
+ val sym = tree.symbol
+ val owner = if (sym is PackageVal) sym.moduleClass else sym
+ ctx.fresh.setOwner(owner)
+ }
+
+ { implicit val ctx = nestedCtx
+ (tag: @switch) match {
+ case Tag.Select =>
+ val tree1 = tree.asInstanceOf[Select]
+ val qual = transformTree(tree1.qualifier, start)
+ trans(cpy.Select(tree1)(qual, tree1.name))
+ case Tag.Super =>
+ val tree1 = tree.asInstanceOf[Super]
+ val qual = transformTree(tree1.qual, start)
+ trans(cpy.Super(tree1)(qual, tree1.mix))
+ case Tag.Apply =>
+ val tree1 = tree.asInstanceOf[Apply]
+ val fun = transformTree(tree1.fun, start)
+ val args = transformTrees(tree1.args, start)
+ trans(cpy.Apply(tree1)(fun, args))
+ case Tag.TypeApply =>
+ val tree1 = tree.asInstanceOf[TypeApply]
+ val fun = transformTree(tree1.fun, start)
+ val args = transformTrees(tree1.args, start)
+ trans(cpy.TypeApply(tree1)(fun, args))
+ case Tag.New =>
+ val tree1 = tree.asInstanceOf[New]
+ val tpt = transformTree(tree1.tpt, start)
+ trans(cpy.New(tree1)(tpt))
+ case Tag.Typed =>
+ val tree1 = tree.asInstanceOf[Typed]
+ val expr = transformTree(tree1.expr, start)
+ val tpt = transformTree(tree1.tpt, start)
+ trans(cpy.Typed(tree1)(expr, tpt))
+ case Tag.Assign =>
+ val tree1 = tree.asInstanceOf[Assign]
+ val lhs = transformTree(tree1.lhs, start)
+ val rhs = transformTree(tree1.rhs, start)
+ trans(cpy.Assign(tree1)(lhs, rhs))
+ case Tag.Block =>
+ val tree1 = tree.asInstanceOf[Block]
+ val stats = transformStats(tree1.stats, ctx.owner, start)
+ val expr = transformTree(tree1.expr, start)
+ trans(cpy.Block(tree1)(stats, expr))
+ case Tag.If =>
+ val tree1 = tree.asInstanceOf[If]
+ val cond = transformTree(tree1.cond, start)
+ val thenp = transformTree(tree1.thenp, start)
+ val elsep = transformTree(tree1.elsep, start)
+ trans(cpy.If(tree1)(cond, thenp, elsep))
+ case Tag.Closure =>
+ val tree1 = tree.asInstanceOf[Closure]
+ val env = transformTrees(tree1.env, start)
+ val meth = transformTree(tree1.meth, start)
+ val tpt = transformTree(tree1.tpt, start)
+ trans(cpy.Closure(tree1)(env, meth, tpt))
+ case Tag.Match =>
+ val tree1 = tree.asInstanceOf[Match]
+ val selector = transformTree(tree1.selector, start)
+ val cases = transformSpecificTrees(tree1.cases, start)
+ trans(cpy.Match(tree1)(selector, cases))
+ case Tag.CaseDef =>
+ val tree1 = tree.asInstanceOf[CaseDef]
+ val pat = transformTree(tree1.pat, start)(ctx.addMode(Mode.Pattern))
+ val guard = transformTree(tree1.guard, start)
+ val body = transformTree(tree1.body, start)
+ trans(cpy.CaseDef(tree1)(pat, guard, body))
+ case Tag.Return =>
+ val tree1 = tree.asInstanceOf[Return]
+ val expr = transformTree(tree1.expr, start)
+ trans(cpy.Return(tree1)(expr, tree1.from))
+ // don't transform `tree1.from`, as this is not a normal ident, but
+ // a pointer to the enclosing method.
+ case Tag.Try =>
+ val tree1 = tree.asInstanceOf[Try]
+ val expr = transformTree(tree1.expr, start)
+ val cases = transformSpecificTrees(tree1.cases, start)
+ val finalizer = transformTree(tree1.finalizer, start)
+ trans(cpy.Try(tree1)(expr, cases, finalizer))
+ case Tag.SeqLiteral =>
+ val tree1 = tree.asInstanceOf[SeqLiteral]
+ val elems = transformTrees(tree1.elems, start)
+ val elemtpt = transformTree(tree1.elemtpt, start)
+ trans(cpy.SeqLiteral(tree1)(elems, elemtpt))
+ case Tag.Inlined =>
+ val tree1 = tree.asInstanceOf[Inlined]
+ val bindings = transformSpecificTrees(tree1.bindings, start)
+ val expansion = transformTree(tree1.expansion, start)
+ trans(cpy.Inlined(tree1)(tree1.call, bindings, expansion))
+ case Tag.Bind =>
+ val tree1 = tree.asInstanceOf[Bind]
+ val body = transformTree(tree1.body, start)
+ trans(cpy.Bind(tree1)(tree1.name, body))
+ case Tag.Alternative =>
+ val tree1 = tree.asInstanceOf[Alternative]
+ val trees = transformTrees(tree1.trees, start)
+ trans(cpy.Alternative(tree1)(trees))
+ case Tag.UnApply =>
+ val tree1 = tree.asInstanceOf[UnApply]
+ val fun = transformTree(tree1.fun, start)
+ val implicits = transformTrees(tree1.implicits, start)
+ val patterns = transformTrees(tree1.patterns, start)
+ trans(cpy.UnApply(tree1)(fun, implicits, patterns))
+ case Tag.ValDef =>
+ val tree1 = tree.asInstanceOf[ValDef]
+ def mapValDef(implicit ctx: Context) = {
+ val tpt = transformTree(tree1.tpt, start)
+ val rhs = transformTree(tree1.rhs, start)
+ cpy.ValDef(tree1)(tree1.name, tpt, rhs)
+ }
+ if (tree1.isEmpty) tree1
+ else trans(mapValDef(if (tree.symbol.exists) localContext else ctx))
+ case Tag.DefDef =>
+ val tree1 = tree.asInstanceOf[DefDef]
+ def mapDefDef(implicit ctx: Context) = {
+ val tparams = transformSpecificTrees(tree1.tparams, start)
+ val vparamss = tree1.vparamss.mapConserve(transformSpecificTrees(_, start))
+ val tpt = transformTree(tree1.tpt, start)
+ val rhs = transformTree(tree1.rhs, start)
+ cpy.DefDef(tree1)(tree1.name, tparams, vparamss, tpt, rhs)
+ }
+ trans(mapDefDef(localContext))
+ case Tag.TypeDef =>
+ val tree1 = tree.asInstanceOf[TypeDef]
+ val rhs = transformTree(tree1.rhs, start)(localContext)
+ trans(cpy.TypeDef(tree1)(tree1.name, rhs))
+ case Tag.Template =>
+ val tree1 = tree.asInstanceOf[Template]
+ val constr = transformSpecificTree(tree1.constr, start)
+ val parents = transformTrees(tree1.parents, start)(ctx.superCallContext)
+ val self = transformSpecificTree(tree1.self, start)
+ val body = transformStats(tree1.body, tree1.symbol, start)
+ trans(cpy.Template(tree1)(constr, parents, self, body))
+ case Tag.PackageDef =>
+ val tree1 = tree.asInstanceOf[PackageDef]
+ def mapPackage(implicit ctx: Context) = {
+ val pid = transformSpecificTree(tree1.pid, start)
+ val stats = transformStats(tree1.stats, tree.symbol, start)
+ cpy.PackageDef(tree1)(pid, stats)
+ }
+ trans(mapPackage(localContext))
+ case Tag.Thicket =>
+ val tree1 = tree.asInstanceOf[Thicket]
+ cpy.Thicket(tree1)(transformTrees(tree1.trees, start))
+ case _ =>
+ trans(tree)
+ }
+ }
+ }
+
+ def transformSpecificTree[T <: Tree](tree: T, start: Int)(implicit ctx: Context): T =
+ transformTree(tree, start).asInstanceOf[T]
+
+ def transformStats(trees: List[Tree], exprOwner: Symbol, start: Int)(implicit ctx: Context): List[Tree] = {
+ def transformStat(stat: Tree)(implicit ctx: Context): Tree = stat match {
+ case _: Import | _: DefTree => transformTree(stat, start)
+ case Thicket(stats) => cpy.Thicket(stat)(stats.mapConserve(transformStat))
+ case _ => transformTree(stat, start)(ctx.exprContext(stat, exprOwner))
+ }
+ val nestedCtx = statsContextTransformer(start)(trees, ctx)
+ val newTrees = flatten(trees.mapConserve(transformStat(_)(nestedCtx)))
+ statsNodeTransformer(start)(newTrees, nestedCtx)
+ }
+
+ def transformUnit(tree: Tree)(implicit ctx: Context) = {
+ val nestedCtx = unitContextTransformer(0)(tree, ctx)
+ val newTree = transformTree(tree, 0)(nestedCtx)
+ unitNodeTransformer(0)(newTree, nestedCtx)
+ }
+
+ def transformTrees(trees: List[Tree], start: Int)(implicit ctx: Context): List[Tree] =
+ flatten(trees.mapConserve(transformTree(_, start)))
+
+ def transformSpecificTrees[T <: Tree](trees: List[T], start: Int)(implicit ctx: Context): List[T] =
+ transformTrees(trees, start).asInstanceOf[List[T]]
+
+ override def run(implicit ctx: Context): Unit =
+ ctx.compilationUnit.tpdTree =
+ transformUnit(ctx.compilationUnit.tpdTree)(ctx.withPhase(miniPhases.last.next))
+
+ // The rest of this class is all made up by initialization code
+
+ for ((phase, idx) <- miniPhases.zipWithIndex) {
+ phase.superPhase = this
+ phase.idxInGroup = idx
+ }
+
+ /** Class#getDeclaredMethods is slow, so we cache its output */
+ private val clsMethodsCache = new java.util.IdentityHashMap[Class[_], Array[java.lang.reflect.Method]]
+
+ /** Does `phase` contain a redefinition of method `name`?
+ * (which is a method of MiniPhase)
+ */
+ private def defines(phase: MiniPhase, name: String) = {
+ def hasRedefinedMethod(cls: Class[_]): Boolean =
+ if (cls.eq(classOf[MiniPhase])) false
+ else {
+ var clsMethods = clsMethodsCache.get(cls)
+ if (clsMethods eq null) {
+ clsMethods = cls.getDeclaredMethods
+ clsMethodsCache.put(cls, clsMethods)
+ }
+ clsMethods.exists(_.getName == name) ||
+ hasRedefinedMethod(cls.getSuperclass)
+ }
+ hasRedefinedMethod(phase.getClass)
+ }
+
+ /** A transformer array is an array of node or context transformers. It has
+ * one more element than there are miniphases. It is constructed as follows:
+ *
+ * - the last element is always `last`, which is the identity transformer
+ * that returns the context or tree unchanged.
+ * - The element corresponding to phase P is `elemFn(P)` if `P` defines a
+ * method with name `methName`, or it the same as the following element
+ * if `P` does not define `methName`.
+ */
+ private def newTransformerArray[T, R](
+ methName: String, elemFn: IndexedTransformer[T, R], last: Transformer[T, R]) = {
+ val trans = new Array[Transformer[T, R]](miniPhases.length + 1)
+ trans(miniPhases.length) = last
+ for (idx <- miniPhases.length - 1 to 0 by -1) {
+ val subPhase = miniPhases(idx)
+ trans(idx) = if (defines(subPhase, methName)) elemFn(subPhase) else trans(idx + 1)
+ }
+ trans
+ }
+
+ private def newContextTransformerArray[T](suffix: String, elemFn: IndexedTransformer[T, Context]) =
+ newTransformerArray[T, Context]("prepareFor" + suffix, elemFn, idContextTransformer.asInstanceOf[Transformer[T, Context]])
+
+ private def newNodeTransformerArray[T, R](suffix: String, elemFn: IndexedTransformer[T, R]) =
+ newTransformerArray[T, R]("transform" + suffix, elemFn, idNodeTransformer.asInstanceOf[Transformer[T, R]])
+
+ private val statsContextTransformer = newContextTransformerArray("Stats", prepForStats)
+ private val statsNodeTransformer = newNodeTransformerArray("Stats", transStats)
+ private val unitContextTransformer = newContextTransformerArray("Unit", prepForUnit)
+ private val unitNodeTransformer = newNodeTransformerArray("Unit", transUnit)
+ private val otherContextTransformer = newContextTransformerArray("Other", prepForOther)
+ private val otherNodeTransformer = newNodeTransformerArray("Other", transOther)
+
+ private val contextTransformer: Array[Array[Transformer[Tree, Context]]] =
+ Array.fill(Tag.NumTags)(otherContextTransformer)
+ private val nodeTransformer: Array[Array[Transformer[Tree, Tree]]] =
+ Array.fill(Tag.NumTags)(otherNodeTransformer)
+
+ // Dotty problem, replace T with _ in the line below, and you get an irreducible application errpr
+ private def init[T](name: String, tag: TreeTag, ctf: IndexedTransformer[T, Context], ntf: IndexedTransformer[T, Tree]): Unit = {
+ if (miniPhases.exists(defines(_, "prepareFor" + name)))
+ contextTransformer(tag) = newContextTransformerArray(name, ctf.asInstanceOf[IndexedTransformer[Tree, Context]])
+ if (miniPhases.exists(defines(_, "transform" + name)))
+ nodeTransformer(tag) = newNodeTransformerArray(name, ntf.asInstanceOf[IndexedTransformer[Tree, Tree]])
+ }
+
+ init("Ident", Tag.Ident, prepForIdent, transIdent)
+ init("Select", Tag.Select, prepForSelect, transSelect)
+ init("This", Tag.This, prepForThis, transThis)
+ init("Super", Tag.Super, prepForSuper, transSuper)
+ init("Apply", Tag.Apply, prepForApply, transApply)
+ init("TypeApply", Tag.TypeApply, prepForTypeApply, transTypeApply)
+ init("Literal", Tag.Literal, prepForLiteral, transLiteral)
+ init("New", Tag.New, prepForNew, transNew)
+ init("Typed", Tag.Typed, prepForTyped, transTyped)
+ init("Assign", Tag.Assign, prepForAssign, transAssign)
+ init("Block", Tag.Block, prepForBlock, transBlock)
+ init("If", Tag.If, prepForIf, transIf)
+ init("Closure", Tag.Closure, prepForClosure, transClosure)
+ init("Match", Tag.Match, prepForMatch, transMatch)
+ init("CaseDef", Tag.CaseDef, prepForCaseDef, transCaseDef)
+ init("Return", Tag.Return, prepForReturn, transReturn)
+ init("Try", Tag.Try, prepForTry, transTry)
+ init("SeqLiteral", Tag.SeqLiteral, prepForSeqLiteral, transSeqLiteral)
+ init("Inlined", Tag.Inlined, prepForInlined, transInlined)
+ init("TypeTree", Tag.TypeTree, prepForTypeTree, transTypeTree)
+ init("Bind", Tag.Bind, prepForBind, transBind)
+ init("Alternative", Tag.Alternative, prepForAlternative, transAlternative)
+ init("UnApply", Tag.UnApply, prepForUnApply, transUnApply)
+ init("ValDef", Tag.ValDef, prepForValDef, transValDef)
+ init("DefDef", Tag.DefDef, prepForDefDef, transDefDef)
+ init("TypeDef", Tag.TypeDef, prepForTypeDef, transTypeDef)
+ init("Template", Tag.Template, prepForTemplate, transTemplate)
+ init("PackageDef", Tag.PackageDef, prepForPackageDef, transPackageDef)
+
+ private def prepForIdent(phase: MiniPhase): Transformer[Ident, Context] =
+ (tree, ctx) => contextTransformer(Tag.Ident)(phase.idxInGroup + 1)(tree, phase.prepareForIdent(tree)(ctx))
+
+ private def prepForSelect(phase: MiniPhase): Transformer[Select, Context] =
+ (tree, ctx) => contextTransformer(Tag.Select)(phase.idxInGroup + 1)(tree, phase.prepareForSelect(tree)(ctx))
+
+ private def prepForThis(phase: MiniPhase): Transformer[This, Context] =
+ (tree, ctx) => contextTransformer(Tag.This)(phase.idxInGroup + 1)(tree, phase.prepareForThis(tree)(ctx))
+
+ private def prepForSuper(phase: MiniPhase): Transformer[Super, Context] =
+ (tree, ctx) => contextTransformer(Tag.Super)(phase.idxInGroup + 1)(tree, phase.prepareForSuper(tree)(ctx))
+
+ private def prepForApply(phase: MiniPhase): Transformer[Apply, Context] =
+ (tree, ctx) => contextTransformer(Tag.Apply)(phase.idxInGroup + 1)(tree, phase.prepareForApply(tree)(ctx))
+
+ private def prepForTypeApply(phase: MiniPhase): Transformer[TypeApply, Context] =
+ (tree, ctx) => contextTransformer(Tag.TypeApply)(phase.idxInGroup + 1)(tree, phase.prepareForTypeApply(tree)(ctx))
+
+ private def prepForLiteral(phase: MiniPhase): Transformer[Literal, Context] =
+ (tree, ctx) => contextTransformer(Tag.Literal)(phase.idxInGroup + 1)(tree, phase.prepareForLiteral(tree)(ctx))
+
+ private def prepForNew(phase: MiniPhase): Transformer[New, Context] =
+ (tree, ctx) => contextTransformer(Tag.New)(phase.idxInGroup + 1)(tree, phase.prepareForNew(tree)(ctx))
+
+ private def prepForTyped(phase: MiniPhase): Transformer[Typed, Context] =
+ (tree, ctx) => contextTransformer(Tag.Typed)(phase.idxInGroup + 1)(tree, phase.prepareForTyped(tree)(ctx))
+
+ private def prepForAssign(phase: MiniPhase): Transformer[Assign, Context] =
+ (tree, ctx) => contextTransformer(Tag.Assign)(phase.idxInGroup + 1)(tree, phase.prepareForAssign(tree)(ctx))
+
+ private def prepForBlock(phase: MiniPhase): Transformer[Block, Context] =
+ (tree, ctx) => contextTransformer(Tag.Block)(phase.idxInGroup + 1)(tree, phase.prepareForBlock(tree)(ctx))
+
+ private def prepForIf(phase: MiniPhase): Transformer[If, Context] =
+ (tree, ctx) => contextTransformer(Tag.If)(phase.idxInGroup + 1)(tree, phase.prepareForIf(tree)(ctx))
+
+ private def prepForClosure(phase: MiniPhase): Transformer[Closure, Context] =
+ (tree, ctx) => contextTransformer(Tag.Closure)(phase.idxInGroup + 1)(tree, phase.prepareForClosure(tree)(ctx))
+
+ private def prepForMatch(phase: MiniPhase): Transformer[Match, Context] =
+ (tree, ctx) => contextTransformer(Tag.Match)(phase.idxInGroup + 1)(tree, phase.prepareForMatch(tree)(ctx))
+
+ private def prepForCaseDef(phase: MiniPhase): Transformer[CaseDef, Context] =
+ (tree, ctx) => contextTransformer(Tag.CaseDef)(phase.idxInGroup + 1)(tree, phase.prepareForCaseDef(tree)(ctx))
+
+ private def prepForReturn(phase: MiniPhase): Transformer[Return, Context] =
+ (tree, ctx) => contextTransformer(Tag.Return)(phase.idxInGroup + 1)(tree, phase.prepareForReturn(tree)(ctx))
+
+ private def prepForTry(phase: MiniPhase): Transformer[Try, Context] =
+ (tree, ctx) => contextTransformer(Tag.Try)(phase.idxInGroup + 1)(tree, phase.prepareForTry(tree)(ctx))
+
+ private def prepForSeqLiteral(phase: MiniPhase): Transformer[SeqLiteral, Context] =
+ (tree, ctx) => contextTransformer(Tag.SeqLiteral)(phase.idxInGroup + 1)(tree, phase.prepareForSeqLiteral(tree)(ctx))
+
+ private def prepForInlined(phase: MiniPhase): Transformer[Inlined, Context] =
+ (tree, ctx) => contextTransformer(Tag.Inlined)(phase.idxInGroup + 1)(tree, phase.prepareForInlined(tree)(ctx))
+
+ private def prepForTypeTree(phase: MiniPhase): Transformer[TypeTree, Context] =
+ (tree, ctx) => contextTransformer(Tag.TypeTree)(phase.idxInGroup + 1)(tree, phase.prepareForTypeTree(tree)(ctx))
+
+ private def prepForBind(phase: MiniPhase): Transformer[Bind, Context] =
+ (tree, ctx) => contextTransformer(Tag.Bind)(phase.idxInGroup + 1)(tree, phase.prepareForBind(tree)(ctx))
+
+ private def prepForAlternative(phase: MiniPhase): Transformer[Alternative, Context] =
+ (tree, ctx) => contextTransformer(Tag.Alternative)(phase.idxInGroup + 1)(tree, phase.prepareForAlternative(tree)(ctx))
+
+ private def prepForUnApply(phase: MiniPhase): Transformer[UnApply, Context] =
+ (tree, ctx) => contextTransformer(Tag.UnApply)(phase.idxInGroup + 1)(tree, phase.prepareForUnApply(tree)(ctx))
+
+ private def prepForValDef(phase: MiniPhase): Transformer[ValDef, Context] =
+ (tree, ctx) => contextTransformer(Tag.ValDef)(phase.idxInGroup + 1)(tree, phase.prepareForValDef(tree)(ctx))
+
+ private def prepForDefDef(phase: MiniPhase): Transformer[DefDef, Context] =
+ (tree, ctx) => contextTransformer(Tag.DefDef)(phase.idxInGroup + 1)(tree, phase.prepareForDefDef(tree)(ctx))
+
+ private def prepForTypeDef(phase: MiniPhase): Transformer[TypeDef, Context] =
+ (tree, ctx) => contextTransformer(Tag.TypeDef)(phase.idxInGroup + 1)(tree, phase.prepareForTypeDef(tree)(ctx))
+
+ private def prepForTemplate(phase: MiniPhase): Transformer[Template, Context] =
+ (tree, ctx) => contextTransformer(Tag.Template)(phase.idxInGroup + 1)(tree, phase.prepareForTemplate(tree)(ctx))
+
+ private def prepForPackageDef(phase: MiniPhase): Transformer[PackageDef, Context] =
+ (tree, ctx) => contextTransformer(Tag.PackageDef)(phase.idxInGroup + 1)(tree, phase.prepareForPackageDef(tree)(ctx))
+
+ private def prepForStats(phase: MiniPhase): Transformer[List[Tree], Context] =
+ (trees, ctx) => statsContextTransformer(phase.idxInGroup + 1)(trees, phase.prepareForStats(trees)(ctx))
+
+ private def prepForUnit(phase: MiniPhase): Transformer[Tree, Context] =
+ (tree, ctx) => unitContextTransformer(phase.idxInGroup + 1)(tree, phase.prepareForUnit(tree)(ctx))
+
+ private def prepForOther(phase: MiniPhase): Transformer[Tree, Context] =
+ (tree, ctx) => otherContextTransformer(phase.idxInGroup + 1)(tree, phase.prepareForOther(tree)(ctx))
+
+ private def transIdent(phase: MiniPhase): Transformer[Ident, Tree] =
+ (tree, ctx) => transformNode(phase.transformIdent(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transSelect(phase: MiniPhase): Transformer[Select, Tree] =
+ (tree, ctx) => transformNode(phase.transformSelect(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transThis(phase: MiniPhase): Transformer[This, Tree] =
+ (tree, ctx) => transformNode(phase.transformThis(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transSuper(phase: MiniPhase): Transformer[Super, Tree] =
+ (tree, ctx) => transformNode(phase.transformSuper(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transApply(phase: MiniPhase): Transformer[Apply, Tree] =
+ (tree, ctx) => transformNode(phase.transformApply(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transTypeApply(phase: MiniPhase): Transformer[TypeApply, Tree] =
+ (tree, ctx) => transformNode(phase.transformTypeApply(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transLiteral(phase: MiniPhase): Transformer[Literal, Tree] =
+ (tree, ctx) => transformNode(phase.transformLiteral(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transNew(phase: MiniPhase): Transformer[New, Tree] =
+ (tree, ctx) => transformNode(phase.transformNew(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transTyped(phase: MiniPhase): Transformer[Typed, Tree] =
+ (tree, ctx) => transformNode(phase.transformTyped(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transAssign(phase: MiniPhase): Transformer[Assign, Tree] =
+ (tree, ctx) => transformNode(phase.transformAssign(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transBlock(phase: MiniPhase): Transformer[Block, Tree] =
+ (tree, ctx) => transformNode(phase.transformBlock(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transIf(phase: MiniPhase): Transformer[If, Tree] =
+ (tree, ctx) => transformNode(phase.transformIf(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transClosure(phase: MiniPhase): Transformer[Closure, Tree] =
+ (tree, ctx) => transformNode(phase.transformClosure(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transMatch(phase: MiniPhase): Transformer[Match, Tree] =
+ (tree, ctx) => transformNode(phase.transformMatch(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transCaseDef(phase: MiniPhase): Transformer[CaseDef, Tree] =
+ (tree, ctx) => transformNode(phase.transformCaseDef(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transReturn(phase: MiniPhase): Transformer[Return, Tree] =
+ (tree, ctx) => transformNode(phase.transformReturn(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transTry(phase: MiniPhase): Transformer[Try, Tree] =
+ (tree, ctx) => transformNode(phase.transformTry(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transSeqLiteral(phase: MiniPhase): Transformer[SeqLiteral, Tree] =
+ (tree, ctx) => transformNode(phase.transformSeqLiteral(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transInlined(phase: MiniPhase): Transformer[Inlined, Tree] =
+ (tree, ctx) => transformNode(phase.transformInlined(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transTypeTree(phase: MiniPhase): Transformer[TypeTree, Tree] =
+ (tree, ctx) => transformNode(phase.transformTypeTree(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transBind(phase: MiniPhase): Transformer[Bind, Tree] =
+ (tree, ctx) => transformNode(phase.transformBind(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transAlternative(phase: MiniPhase): Transformer[Alternative, Tree] =
+ (tree, ctx) => transformNode(phase.transformAlternative(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transUnApply(phase: MiniPhase): Transformer[UnApply, Tree] =
+ (tree, ctx) => transformNode(phase.transformUnApply(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transValDef(phase: MiniPhase): Transformer[ValDef, Tree] =
+ (tree, ctx) => transformNode(phase.transformValDef(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transDefDef(phase: MiniPhase): Transformer[DefDef, Tree] =
+ (tree, ctx) => transformNode(phase.transformDefDef(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transTypeDef(phase: MiniPhase): Transformer[TypeDef, Tree] =
+ (tree, ctx) => transformNode(phase.transformTypeDef(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transTemplate(phase: MiniPhase): Transformer[Template, Tree] =
+ (tree, ctx) => transformNode(phase.transformTemplate(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transPackageDef(phase: MiniPhase): Transformer[PackageDef, Tree] =
+ (tree, ctx) => transformNode(phase.transformPackageDef(tree)(ctx), phase.idxInGroup + 1)(ctx)
+
+ private def transStats(phase: MiniPhase): Transformer[List[Tree], List[Tree]] =
+ (trees, ctx) => statsNodeTransformer(phase.idxInGroup + 1)(phase.transformStats(trees)(ctx), ctx)
+
+ private def transUnit(phase: MiniPhase): Transformer[Tree, Tree] =
+ (tree, ctx) => unitNodeTransformer(phase.idxInGroup + 1)(phase.transformUnit(tree)(ctx), ctx)
+
+ private def transOther(phase: MiniPhase): Transformer[Tree, Tree] =
+ (tree, ctx) => otherNodeTransformer(phase.idxInGroup + 1)(phase.transformOther(tree)(ctx), ctx)
+}
\ No newline at end of file
diff --git a/compiler/src/dotty/tools/dotc/transform/Memoize.scala b/compiler/src/dotty/tools/dotc/transform/Memoize.scala
index 44bb6bd73c88..497a229c2748 100644
--- a/compiler/src/dotty/tools/dotc/transform/Memoize.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Memoize.scala
@@ -12,7 +12,7 @@ import Symbols._
import SymUtils._
import Constants._
import ast.Trees._
-import TreeTransforms._
+import MegaPhase._
import NameOps._
import Flags._
import Decorators._
@@ -32,7 +32,7 @@ import Decorators._
* def x_=(y: T): Unit = ()
* --> def x_=(y: T): Unit = x = y
*/
- class Memoize extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import ast.tpd._
override def phaseName = "memoize"
@@ -66,7 +66,7 @@ import Decorators._
*/
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Mixin])
- override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformDefDef(tree: DefDef)(implicit ctx: Context): Tree = {
val sym = tree.symbol
def newField = {
@@ -82,7 +82,7 @@ import Decorators._
info = fieldType,
coord = tree.pos
).withAnnotationsCarrying(sym, defn.FieldMetaAnnot)
- .enteredAfter(thisTransform)
+ .enteredAfter(thisPhase)
}
def addAnnotations(denot: Denotation): Unit =
@@ -90,7 +90,7 @@ import Decorators._
case fieldDenot: SymDenotation if sym.annotations.nonEmpty =>
val cpy = fieldDenot.copySymDenotation()
cpy.annotations = sym.annotations
- cpy.installAfter(thisTransform)
+ cpy.installAfter(thisPhase)
case _ => ()
}
@@ -98,7 +98,7 @@ import Decorators._
if (sym.annotations.nonEmpty) {
val cpy = sym.copySymDenotation()
cpy.annotations = Nil
- cpy.installAfter(thisTransform)
+ cpy.installAfter(thisPhase)
}
val NoFieldNeeded = Lazy | Deferred | JavaDefined | (if (ctx.settings.YnoInline.value) EmptyFlags else Inline)
@@ -127,13 +127,13 @@ import Decorators._
}
if (sym.isGetter) {
- var rhs = tree.rhs.changeOwnerAfter(sym, field, thisTransform)
+ var rhs = tree.rhs.changeOwnerAfter(sym, field, thisPhase)
if (isWildcardArg(rhs)) rhs = EmptyTree
val fieldDef = transformFollowing(ValDef(field, adaptToField(rhs)))
val rhsClass = tree.tpt.tpe.widenDealias.classSymbol
val getterRhs =
if (isErasableBottomField(rhsClass)) erasedBottomTree(rhsClass)
- else transformFollowingDeep(ref(field))(ctx.withOwner(sym), info)
+ else transformFollowingDeep(ref(field))(ctx.withOwner(sym))
val getterDef = cpy.DefDef(tree)(rhs = getterRhs)
addAnnotations(fieldDef.denot)
removeAnnotations(sym)
@@ -144,7 +144,7 @@ import Decorators._
if (isErasableBottomField(tree.vparamss.head.head.tpt.tpe.classSymbol)) tree
else {
val initializer = Assign(ref(field), adaptToField(ref(tree.vparamss.head.head.symbol)))
- val setterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(initializer)(ctx.withOwner(sym), info))
+ val setterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(initializer)(ctx.withOwner(sym)))
removeAnnotations(sym)
setterDef
}
diff --git a/compiler/src/dotty/tools/dotc/transform/Mixin.scala b/compiler/src/dotty/tools/dotc/transform/Mixin.scala
index fc6cc67eba18..e17976984a07 100644
--- a/compiler/src/dotty/tools/dotc/transform/Mixin.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Mixin.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package transform
import core._
-import TreeTransforms._
+import MegaPhase._
import Contexts.Context
import Flags._
import SymUtils._
@@ -91,11 +91,14 @@ import collection.mutable
* into enclosing classes where they are not visible. This can only be done if all references
* are symbolic.
*/
-class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
+class Mixin extends MiniPhase with SymTransformer { thisPhase =>
import ast.tpd._
override def phaseName: String = "mixin"
+ override def relaxedTypingInGroup = true
+ // Because it changes number of parameters in trait initializers
+
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[Erasure])
override def changesMembers = true // the phase adds implementions of mixin accessors
@@ -125,13 +128,13 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
initName,
Protected | Synthetic | Method,
sym.info,
- coord = sym.symbol.coord).enteredAfter(thisTransform))
+ coord = sym.symbol.coord).enteredAfter(thisPhase))
}
}.asTerm
- override def transformTemplate(impl: Template)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformTemplate(impl: Template)(implicit ctx: Context) = {
val cls = impl.symbol.owner.asClass
- val ops = new MixinOps(cls, thisTransform)
+ val ops = new MixinOps(cls, thisPhase)
import ops._
def traitDefs(stats: List[Tree]): List[Tree] = {
@@ -143,8 +146,8 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
val vsym = stat.symbol
val isym = initializer(vsym)
val rhs = Block(
- initBuf.toList.map(_.changeOwnerAfter(impl.symbol, isym, thisTransform)),
- stat.rhs.changeOwnerAfter(vsym, isym, thisTransform).wildcardToDefault)
+ initBuf.toList.map(_.changeOwnerAfter(impl.symbol, isym, thisPhase)),
+ stat.rhs.changeOwnerAfter(vsym, isym, thisPhase).wildcardToDefault)
initBuf.clear()
cpy.DefDef(stat)(rhs = EmptyTree) :: DefDef(isym, rhs) :: Nil
case stat: DefDef if stat.symbol.isSetter =>
@@ -186,7 +189,7 @@ class Mixin extends MiniPhaseTransform with SymTransformer { thisTransform =>
}
def was(sym: Symbol, flags: FlagSet) =
- ctx.atPhase(thisTransform) { implicit ctx => sym is flags }
+ ctx.atPhase(thisPhase) { implicit ctx => sym is flags }
def traitInits(mixin: ClassSymbol): List[Tree] = {
var argNum = 0
diff --git a/compiler/src/dotty/tools/dotc/transform/MixinOps.scala b/compiler/src/dotty/tools/dotc/transform/MixinOps.scala
index b63833468660..d3e08d7f9b7e 100644
--- a/compiler/src/dotty/tools/dotc/transform/MixinOps.scala
+++ b/compiler/src/dotty/tools/dotc/transform/MixinOps.scala
@@ -8,7 +8,7 @@ import SymUtils._
import StdNames._, NameOps._
import Decorators._
-class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx: Context) {
+class MixinOps(cls: ClassSymbol, thisPhase: DenotTransformer)(implicit ctx: Context) {
import ast.tpd._
val superCls: Symbol = cls.superClass
@@ -23,7 +23,7 @@ class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx:
owner = cls,
name = member.name.stripScala2LocalSuffix,
flags = member.flags &~ Deferred,
- info = cls.thisType.memberInfo(member)).enteredAfter(thisTransform).asTerm
+ info = cls.thisType.memberInfo(member)).enteredAfter(thisPhase).asTerm
res.addAnnotations(member.annotations)
res
}
@@ -40,10 +40,10 @@ class MixinOps(cls: ClassSymbol, thisTransform: DenotTransformer)(implicit ctx:
}
/** Is `sym` a member of implementing class `cls`?
- * The test is performed at phase `thisTransform`.
+ * The test is performed at phase `thisPhase`.
*/
def isCurrent(sym: Symbol) =
- ctx.atPhase(thisTransform) { implicit ctx =>
+ ctx.atPhase(thisPhase) { implicit ctx =>
cls.info.member(sym.name).hasAltWith(_.symbol == sym)
// this is a hot spot, where we spend several seconds while compiling stdlib
// unfortunately it will discard and recompute all the member chaches,
diff --git a/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala b/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala
index 0942c0b4af11..484e538e0bf4 100644
--- a/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala
+++ b/compiler/src/dotty/tools/dotc/transform/MoveStatics.scala
@@ -13,10 +13,10 @@ import dotty.tools.dotc.core.StdNames.nme
import dotty.tools.dotc.core.Phases.Phase
import dotty.tools.dotc.core.Symbols._
import dotty.tools.dotc.core.Types.MethodType
-import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import dotty.tools.dotc.transform.MegaPhase.MiniPhase
/** Move static methods from companion to the class itself */
-class MoveStatics extends MiniPhaseTransform with SymTransformer { thisTransformer =>
+class MoveStatics extends MiniPhase with SymTransformer {
import tpd._
override def phaseName = "moveStatic"
@@ -31,7 +31,7 @@ class MoveStatics extends MiniPhaseTransform with SymTransformer { thisTransform
else sym
}
- override def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] = {
+ override def transformStats(trees: List[Tree])(implicit ctx: Context): List[Tree] = {
if (ctx.owner.is(Flags.Package)) {
val (classes, others) = trees.partition(x => x.isInstanceOf[TypeDef] && x.symbol.isClass)
val pairs = classes.groupBy(_.symbol.name.stripModuleClassSuffix).asInstanceOf[Map[Name, List[TypeDef]]]
diff --git a/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala b/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala
index fdee076b452f..70ae9a77574a 100644
--- a/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala
+++ b/compiler/src/dotty/tools/dotc/transform/NonLocalReturns.scala
@@ -3,7 +3,7 @@ package transform
import core._
import Contexts._, Symbols._, Types._, Flags._, Decorators._, StdNames._, Constants._, Phases._
-import TreeTransforms._
+import MegaPhase._
import ast.Trees._
import NameKinds.NonLocalReturnKeyName
import collection.mutable
@@ -16,7 +16,7 @@ object NonLocalReturns {
/** Implement non-local returns using NonLocalReturnControl exceptions.
*/
-class NonLocalReturns extends MiniPhaseTransform { thisTransformer =>
+class NonLocalReturns extends MiniPhase {
override def phaseName = "nonLocalReturns"
import NonLocalReturns._
@@ -81,13 +81,13 @@ class NonLocalReturns extends MiniPhaseTransform { thisTransformer =>
Block(keyDef :: Nil, tryCatch)
}
- override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformDefDef(tree: DefDef)(implicit ctx: Context): Tree =
nonLocalReturnKeys.remove(tree.symbol) match {
case Some(key) => cpy.DefDef(tree)(rhs = nonLocalReturnTry(tree.rhs, key, tree.symbol))
case _ => tree
}
- override def transformReturn(tree: Return)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformReturn(tree: Return)(implicit ctx: Context): Tree =
if (isNonLocalReturn(tree)) nonLocalReturnThrow(tree.expr, tree.from.symbol).withPos(tree.pos)
else tree
}
diff --git a/compiler/src/dotty/tools/dotc/transform/NormalizeFlags.scala b/compiler/src/dotty/tools/dotc/transform/NormalizeFlags.scala
index 35a183c84a13..ced55ef697d4 100644
--- a/compiler/src/dotty/tools/dotc/transform/NormalizeFlags.scala
+++ b/compiler/src/dotty/tools/dotc/transform/NormalizeFlags.scala
@@ -6,7 +6,7 @@ import DenotTransformers.SymTransformer
import Phases.Phase
import Contexts.Context
import SymDenotations.SymDenotation
-import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import MegaPhase.MiniPhase
import Flags._, Symbols._
/** 1. Widens all private[this] and protected[this] qualifiers to just private/protected
@@ -14,7 +14,7 @@ import Flags._, Symbols._
* do not have initialization code. A pure interface member is either an abstract
* or alias type definition or a deferred val or def.
*/
-class NormalizeFlags extends MiniPhaseTransform with SymTransformer { thisTransformer =>
+class NormalizeFlags extends MiniPhase with SymTransformer {
override def phaseName = "normalizeFlags"
def transformSym(ref: SymDenotation)(implicit ctx: Context) = {
diff --git a/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala b/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala
index 33b7852ac0a7..901b1a316211 100644
--- a/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ParamForwarding.scala
@@ -21,7 +21,7 @@ import config.Printers.typr
* Do the same also if there are intermediate inaccessible parameter accessor forwarders.
* The aim of this transformation is to avoid redundant parameter accessor fields.
*/
-class ParamForwarding(thisTransformer: DenotTransformer) {
+class ParamForwarding(thisPhase: DenotTransformer) {
import ast.tpd._
def forwardParamAccessors(impl: Template)(implicit ctx: Context): Template = {
@@ -66,7 +66,7 @@ class ParamForwarding(thisTransformer: DenotTransformer) {
if (alias.exists) {
def forwarder(implicit ctx: Context) = {
sym.copySymDenotation(initFlags = sym.flags | Method | Stable, info = sym.info.ensureMethodic)
- .installAfter(thisTransformer)
+ .installAfter(thisPhase)
var superAcc =
Super(This(currentClass), tpnme.EMPTY, inConstrCall = false).select(alias)
if (alias.owner != currentClass.superClass)
@@ -77,7 +77,7 @@ class ParamForwarding(thisTransformer: DenotTransformer) {
typr.println(i"adding param forwarder $superAcc")
DefDef(sym, superAcc.ensureConforms(sym.info.widen))
}
- return forwarder(ctx.withPhase(thisTransformer.next))
+ return forwarder(ctx.withPhase(thisPhase.next))
}
}
}
@@ -88,7 +88,7 @@ class ParamForwarding(thisTransformer: DenotTransformer) {
stats map forwardParamAccessor
}
- cpy.Template(impl)(body = fwd(impl.body)(ctx.withPhase(thisTransformer)))
+ cpy.Template(impl)(body = fwd(impl.body)(ctx.withPhase(thisPhase)))
}
def adaptRef[T <: RefTree](tree: T)(implicit ctx: Context): T = tree.tpe match {
diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
index 6e8f3141d39b..512ee80472e0 100644
--- a/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package transform
import core._
-import TreeTransforms._
+import MegaPhase._
import collection.mutable
import SymDenotations._, Symbols._, Contexts._, Types._, Names._, StdNames._, NameOps._
import ast.Trees._
@@ -19,7 +19,7 @@ import config.Printers.patmatch
* After this phase, the only Match nodes remaining in the code are simple switches
* where every pattern is an integer constant
*/
-class PatternMatcher extends MiniPhaseTransform {
+class PatternMatcher extends MiniPhase {
import ast.tpd._
import PatternMatcher._
@@ -27,7 +27,7 @@ class PatternMatcher extends MiniPhaseTransform {
override def runsAfter = Set(classOf[ElimRepeated])
override def runsAfterGroupsOf = Set(classOf[TailRec]) // tailrec is not capable of reversing the patmat tranformation made for tree
- override def transformMatch(tree: Match)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformMatch(tree: Match)(implicit ctx: Context): Tree = {
val translated = new Translator(tree.tpe, this).translateMatch(tree)
// check exhaustivity and unreachability
@@ -69,7 +69,7 @@ object PatternMatcher {
* It's represented by its own data type. Plans are optimized by
* inlining, hoisting, and the elimination of redundant tests and dead code.
*/
- class Translator(resultType: Type, trans: TreeTransform)(implicit ctx: Context, info: TransformerInfo) {
+ class Translator(resultType: Type, thisPhase: MiniPhase)(implicit ctx: Context) {
// ------- Bindings for variables and labels ---------------------
@@ -765,7 +765,7 @@ object PatternMatcher {
}
}
- def outerTest: Tree = trans.transformFollowingDeep {
+ def outerTest: Tree = thisPhase.transformFollowingDeep {
val expectedOuter = singleton(expectedTp.normalizedPrefix)
val expectedClass = expectedTp.dealias.classSymbol.asClass
ExplicitOuter.ensureOuterAccessors(expectedClass)
diff --git a/compiler/src/dotty/tools/dotc/transform/PatternMatcherOld.scala b/compiler/src/dotty/tools/dotc/transform/PatternMatcherOld.scala
index 6375e4b86aad..154a788b4427 100644
--- a/compiler/src/dotty/tools/dotc/transform/PatternMatcherOld.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PatternMatcherOld.scala
@@ -3,7 +3,7 @@ package transform
import scala.language.postfixOps
-import TreeTransforms._
+import MegaPhase._
import core.Denotations._
import core.SymDenotations._
import core.Contexts._
@@ -34,7 +34,7 @@ import dotty.tools.dotc.core.Flags
/** This phase rewrites pattern matches.
* FIXME: A more detailed explanation would be good.
*/
-class PatternMatcherOld extends MiniPhaseTransform with DenotTransformer {
+class PatternMatcherOld extends MiniPhase with DenotTransformer {
import dotty.tools.dotc.ast.tpd._
override def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref
@@ -47,7 +47,7 @@ class PatternMatcherOld extends MiniPhaseTransform with DenotTransformer {
private[this] var _id = 0 // left for debuging
- override def transformMatch(tree: Match)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformMatch(tree: Match)(implicit ctx: Context): Tree = {
val translated = new Translator()(ctx).translator.translateMatch(tree)
// check exhaustivity and unreachability
diff --git a/compiler/src/dotty/tools/dotc/transform/PhantomArgLift.scala b/compiler/src/dotty/tools/dotc/transform/PhantomArgLift.scala
index 6b823a8ce56f..7df418e598d6 100644
--- a/compiler/src/dotty/tools/dotc/transform/PhantomArgLift.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PhantomArgLift.scala
@@ -4,7 +4,7 @@ import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Contexts._
import dotty.tools.dotc.core.NameKinds._
import dotty.tools.dotc.core.Types._
-import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import dotty.tools.dotc.transform.MegaPhase.MiniPhase
import dotty.tools.dotc.typer.EtaExpansion
import scala.collection.mutable.ListBuffer
@@ -24,7 +24,7 @@ import scala.collection.mutable.ListBuffer
* `ev$f(ev$x1,...)(ev$y1,...)...(...)`
*
*/
-class PhantomArgLift extends MiniPhaseTransform {
+class PhantomArgLift extends MiniPhase {
import tpd._
override def phaseName: String = "phantomArgLift"
@@ -40,7 +40,7 @@ class PhantomArgLift extends MiniPhaseTransform {
/* Tree transform */
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = tree.tpe.widen match {
+ override def transformApply(tree: Apply)(implicit ctx: Context): Tree = tree.tpe.widen match {
case _: MethodType => tree // Do the transformation higher in the tree if needed
case _ =>
if (!hasImpurePhantomArgs(tree)) tree
diff --git a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala
index 1d235a81ae04..07c6753892ab 100644
--- a/compiler/src/dotty/tools/dotc/transform/PostTyper.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PostTyper.scala
@@ -1,7 +1,6 @@
package dotty.tools.dotc
package transform
-import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform, TreeTransformer}
import dotty.tools.dotc.ast.{Trees, tpd, untpd}
import scala.collection.{ mutable, immutable }
import ValueClasses._
@@ -54,7 +53,7 @@ import reporting.diagnostic.messages.SuperCallsNotAllowedInline
* mini-phase or subfunction of a macro phase equally well. But taken by themselves
* they do not warrant their own group of miniphases before pickling.
*/
-class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTransformer =>
+class PostTyper extends MacroTransform with IdentityDenotTransformer { thisPhase =>
import tpd._
/** the following two members override abstract members in Transform */
@@ -62,14 +61,14 @@ class PostTyper extends MacroTransform with IdentityDenotTransformer { thisTrans
override def changesMembers = true // the phase adds super accessors and synthetic methods
- override def transformPhase(implicit ctx: Context) = thisTransformer.next
+ override def transformPhase(implicit ctx: Context) = thisPhase.next
protected def newTransformer(implicit ctx: Context): Transformer =
new PostTyperTransformer
- val superAcc = new SuperAccessors(thisTransformer)
- val paramFwd = new ParamForwarding(thisTransformer)
- val synthMth = new SyntheticMethods(thisTransformer)
+ val superAcc = new SuperAccessors(thisPhase)
+ val paramFwd = new ParamForwarding(thisPhase)
+ val synthMth = new SyntheticMethods(thisPhase)
private def newPart(tree: Tree): Option[New] = methPart(tree) match {
case Select(nu: New, _) => Some(nu)
diff --git a/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala b/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala
index fec7bd741dab..17535ac45cfe 100644
--- a/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala
+++ b/compiler/src/dotty/tools/dotc/transform/PrimitiveForwarders.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package transform
import core._
-import TreeTransforms._
+import MegaPhase._
import Contexts.Context
import Flags._
import SymUtils._
@@ -30,7 +30,7 @@ import ResolveSuper._
* IMPORTANT: When\If Valhalla happens, we'll need to move mixin before erasure and than this code will need to be rewritten
* as it will instead change super-class.
*/
-class PrimitiveForwarders extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+class PrimitiveForwarders extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import ast.tpd._
override def phaseName: String = "primitiveForwarders"
@@ -39,9 +39,9 @@ class PrimitiveForwarders extends MiniPhaseTransform with IdentityDenotTransform
override def changesMembers = true // the phase adds primitive forwarders
- override def transformTemplate(impl: Template)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformTemplate(impl: Template)(implicit ctx: Context) = {
val cls = impl.symbol.owner.asClass
- val ops = new MixinOps(cls, thisTransform)
+ val ops = new MixinOps(cls, thisPhase)
import ops._
def methodPrimitiveForwarders: List[Tree] =
diff --git a/compiler/src/dotty/tools/dotc/transform/PrivateToStatic.scala.disabled b/compiler/src/dotty/tools/dotc/transform/PrivateToStatic.scala.disabled
index 218839d010be..51dc44d8b90a 100644
--- a/compiler/src/dotty/tools/dotc/transform/PrivateToStatic.scala.disabled
+++ b/compiler/src/dotty/tools/dotc/transform/PrivateToStatic.scala.disabled
@@ -11,10 +11,10 @@ import StdNames._
import SymDenotations._
import Types._
import collection.mutable
-import TreeTransforms._
+import MegaPhase._
import Decorators._
import ast.Trees._
-import TreeTransforms.TransformerInfo
+import MegaPhase.TransformerInfo
/** Makes private methods static, provided they not deferred, accessors, or static,
* by rewriting a method `m` in class `C` as follows:
@@ -56,7 +56,7 @@ class PrivateToStatic extends MiniPhase with SymTransformer { thisTransform =>
}
else this
- override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformDefDef(tree: DefDef)(implicit ctx: Context) =
if (shouldBeStatic(tree.symbol)) {
val thisParamDef = ValDef(thisParam.asTerm)
val vparams :: Nil = tree.vparamss
@@ -64,7 +64,7 @@ class PrivateToStatic extends MiniPhase with SymTransformer { thisTransform =>
}
else tree
- override def transformThis(tree: This)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformThis(tree: This)(implicit ctx: Context) =
if (shouldBeStatic(ctx.owner.enclosingMethod)) ref(thisParam).withPos(tree.pos)
else tree
@@ -72,7 +72,7 @@ class PrivateToStatic extends MiniPhase with SymTransformer { thisTransform =>
*
* qual.m(args) --> m(qual, args)
*/
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformApply(tree: Apply)(implicit ctx: Context) =
tree.fun match {
case fun @ Select(qual, name) if shouldBeStatic(fun.symbol) =>
ctx.debuglog(i"mapping $tree to ${cpy.Ident(fun)(name)} (${qual :: tree.args}%, %)")
@@ -81,7 +81,7 @@ class PrivateToStatic extends MiniPhase with SymTransformer { thisTransform =>
tree
}
- override def transformClosure(tree: Closure)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformClosure(tree: Closure)(implicit ctx: Context) =
tree.meth match {
case meth @ Select(qual, name) if shouldBeStatic(meth.symbol) =>
cpy.Closure(tree)(
diff --git a/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala
index 8a7b7665a9ec..beef392a3eb2 100644
--- a/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala
+++ b/compiler/src/dotty/tools/dotc/transform/RenameLifted.scala
@@ -9,10 +9,10 @@ import dotty.tools.dotc.core.Names._
import dotty.tools.dotc.core.Phases
import dotty.tools.dotc.core.SymDenotations.SymDenotation
import dotty.tools.dotc.core.Symbols._
-import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import dotty.tools.dotc.transform.MegaPhase.MiniPhase
/** Renames lifted classes to local numbering scheme */
-class RenameLifted extends MiniPhaseTransform with SymTransformer { thisTransformer =>
+class RenameLifted extends MiniPhase with SymTransformer {
override def phaseName = "renameLifted"
diff --git a/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala b/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala
index 03a8f9678085..22a700bdb734 100644
--- a/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ResolveSuper.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package transform
import core._
-import TreeTransforms._
+import MegaPhase._
import Contexts.Context
import Flags._
import SymUtils._
@@ -45,7 +45,7 @@ import ResolveSuper._
* This is the first part of what was the mixin phase. It is complemented by
* Mixin, which runs after erasure.
*/
-class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+class ResolveSuper extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import ast.tpd._
override def phaseName: String = "resolveSuper"
@@ -55,9 +55,9 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
override def changesMembers = true // the phase adds super accessors and method forwarders
- override def transformTemplate(impl: Template)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformTemplate(impl: Template)(implicit ctx: Context) = {
val cls = impl.symbol.owner.asClass
- val ops = new MixinOps(cls, thisTransform)
+ val ops = new MixinOps(cls, thisPhase)
import ops._
def superAccessors(mixin: ClassSymbol): List[Tree] =
@@ -79,12 +79,12 @@ class ResolveSuper extends MiniPhaseTransform with IdentityDenotTransformer { th
cpy.Template(impl)(body = overrides ::: impl.body)
}
- override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformDefDef(ddef: DefDef)(implicit ctx: Context) = {
val meth = ddef.symbol.asTerm
if (meth.isSuperAccessor && !meth.is(Deferred)) {
assert(ddef.rhs.isEmpty)
val cls = meth.owner.asClass
- val ops = new MixinOps(cls, thisTransform)
+ val ops = new MixinOps(cls, thisPhase)
import ops._
polyDefDef(meth, forwarder(rebindSuper(cls, meth)))
}
diff --git a/compiler/src/dotty/tools/dotc/transform/RestoreScopes.scala b/compiler/src/dotty/tools/dotc/transform/RestoreScopes.scala
index 8d2b8e25a61a..b88d46fdda6a 100644
--- a/compiler/src/dotty/tools/dotc/transform/RestoreScopes.scala
+++ b/compiler/src/dotty/tools/dotc/transform/RestoreScopes.scala
@@ -7,18 +7,17 @@ import Contexts.Context
import Symbols._
import Scopes._
import collection.mutable
-import TreeTransforms.MiniPhaseTransform
+import MegaPhase.MiniPhase
import SymDenotations._
import ast.Trees._
import NameOps._
-import TreeTransforms.TransformerInfo
import StdNames._
/** The preceding lambda lift and flatten phases move symbols to different scopes
* and rename them. This miniphase cleans up afterwards and makes sure that all
* class scopes contain the symbols defined in them.
*/
-class RestoreScopes extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+class RestoreScopes extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import ast.tpd._
override def phaseName = "restoreScopes"
@@ -29,12 +28,12 @@ class RestoreScopes extends MiniPhaseTransform with IdentityDenotTransformer { t
* enclosing package definitions. So by the time RestoreScopes gets to
* see a typedef or template, it still might be changed by DropEmptyConstructors.
*/
- override def transformPackageDef(pdef: PackageDef)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformPackageDef(pdef: PackageDef)(implicit ctx: Context) = {
pdef.stats.foreach(restoreScope)
pdef
}
- private def restoreScope(tree: Tree)(implicit ctx: Context, info: TransformerInfo) = tree match {
+ private def restoreScope(tree: Tree)(implicit ctx: Context) = tree match {
case TypeDef(_, impl: Template) =>
val restoredDecls = newScope
for (stat <- impl.constr :: impl.body)
@@ -61,7 +60,7 @@ class RestoreScopes extends MiniPhaseTransform with IdentityDenotTransformer { t
val cinfo = cls.classInfo
tree.symbol.copySymDenotation(
info = cinfo.derivedClassInfo( // Dotty deviation: Cannot expand cinfo inline without a type error
- decls = restoredDecls: Scope)).installAfter(thisTransform)
+ decls = restoredDecls: Scope)).installAfter(thisPhase)
tree
case tree => tree
}
diff --git a/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala b/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala
index b90c6ed37620..761d092da972 100644
--- a/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala
+++ b/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala
@@ -8,19 +8,19 @@ import dotty.tools.dotc.core.DenotTransformers.IdentityDenotTransformer
import dotty.tools.dotc.core.Flags._
import dotty.tools.dotc.core.Symbols._
import dotty.tools.dotc.core._
-import dotty.tools.dotc.transform.TreeTransforms._
+import dotty.tools.dotc.transform.MegaPhase._
/** Removes selects that would be compiled into GetStatic
* otherwise backend needs to be aware that some qualifiers need to be dropped.
* Similar transformation seems to be performed by flatten in nsc
* @author Dmytro Petrashko
*/
-class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+class SelectStatic extends MiniPhase with IdentityDenotTransformer {
import ast.tpd._
override def phaseName: String = "selectStatic"
- override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformSelect(tree: tpd.Select)(implicit ctx: Context): tpd.Tree = {
val sym = tree.symbol
def isStaticMember =
(sym is Flags.Module) && sym.initial.maybeOwner.initial.isStaticOwner ||
@@ -48,15 +48,15 @@ class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { th
case _ => t
}
- override def transformApply(tree: tpd.Apply)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformApply(tree: tpd.Apply)(implicit ctx: Context): tpd.Tree = {
normalize(tree)
}
- override def transformTypeApply(tree: tpd.TypeApply)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformTypeApply(tree: tpd.TypeApply)(implicit ctx: Context): tpd.Tree = {
normalize(tree)
}
- override def transformClosure(tree: tpd.Closure)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformClosure(tree: tpd.Closure)(implicit ctx: Context): tpd.Tree = {
normalize(tree)
}
}
diff --git a/compiler/src/dotty/tools/dotc/transform/SeqLiterals.scala b/compiler/src/dotty/tools/dotc/transform/SeqLiterals.scala
index 49ea695300bb..139424bb111a 100644
--- a/compiler/src/dotty/tools/dotc/transform/SeqLiterals.scala
+++ b/compiler/src/dotty/tools/dotc/transform/SeqLiterals.scala
@@ -3,7 +3,7 @@ package transform
import core._
import Types._
-import dotty.tools.dotc.transform.TreeTransforms._
+import dotty.tools.dotc.transform.MegaPhase._
import Contexts.Context
import Symbols._
import Phases._
@@ -18,7 +18,7 @@ import Decorators._
* is called directly. The reason for this step is that JavaSeqLiterals, being arrays
* keep a precise type after erasure, whereas SeqLiterals only get the erased type `Seq`,
*/
-class SeqLiterals extends MiniPhaseTransform {
+class SeqLiterals extends MiniPhase {
import ast.tpd._
override def phaseName = "seqLiterals"
@@ -29,7 +29,7 @@ class SeqLiterals extends MiniPhaseTransform {
case _ =>
}
- override def transformSeqLiteral(tree: SeqLiteral)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
+ override def transformSeqLiteral(tree: SeqLiteral)(implicit ctx: Context): Tree = tree match {
case tree: JavaSeqLiteral => tree
case _ =>
val arr = JavaSeqLiteral(tree.elems, tree.elemtpt)
diff --git a/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala b/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala
index 91301c0cd86e..453bb7508d7b 100644
--- a/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala
+++ b/compiler/src/dotty/tools/dotc/transform/ShortcutImplicits.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core.DenotTransformers.IdentityDenotTransformer
import core.Symbols._
import core.Contexts._
@@ -14,6 +14,7 @@ import core.NameOps._
import core.NameKinds.DirectMethodName
import ast.Trees._
import ast.tpd
+import util.Store
import collection.mutable
/** This phase optimizes code using implicit function types, by applying two rewrite rules.
@@ -44,14 +45,21 @@ import collection.mutable
* `qual` refers to a method `m` is rewritten to a reference to `m$direct`,
* keeping the same type and value arguments as they are found in `qual`.
*/
-class ShortcutImplicits extends MiniPhase with IdentityDenotTransformer { thisTransform =>
+class ShortcutImplicits extends MiniPhase with IdentityDenotTransformer { thisPhase =>
import tpd._
override def phaseName: String = "shortcutImplicits"
override def changesMembers = true // the phase adds "direct" methods
- val treeTransform = new Transform
+ /** A map to cache mapping local methods to their direct counterparts.
+ * A fresh map is created for each unit.
+ */
+ private var DirectMeth: Store.Location[mutable.HashMap[Symbol, Symbol]] = _
+ private def directMeth(implicit ctx: Context) = ctx.store(DirectMeth)
+
+ override def initContext(ctx: FreshContext) =
+ DirectMeth = ctx.addLocation[mutable.HashMap[Symbol, Symbol]]()
/** If this option is true, we don't specialize symbols that are known to be only
* targets of monomorphic calls.
@@ -61,109 +69,101 @@ class ShortcutImplicits extends MiniPhase with IdentityDenotTransformer { thisTr
*/
final val specializeMonoTargets = true
- class Transform extends TreeTransform {
- def phase = thisTransform
-
- override def prepareForUnit(tree: Tree)(implicit ctx: Context) = new Transform
-
- /** A map to cache mapping local methods to their direct counterparts.
- * A fresh map is created for each unit.
- */
- private val directMeth = new mutable.HashMap[Symbol, Symbol]
-
- /** Should `sym` get a ..$direct companion?
- * This is the case if (1) `sym` is a method with an implicit function type as final result type.
- * However if `specializeMonoTargets` is false, we exclude symbols that are known
- * to be only targets of monomorphic calls because they are effectively
- * final and don't override anything.
- */
- private def shouldBeSpecialized(sym: Symbol)(implicit ctx: Context) =
- sym.is(Method, butNot = Accessor) &&
- defn.isImplicitFunctionType(sym.info.finalResultType) &&
- !sym.isAnonymousFunction &&
- (specializeMonoTargets || !sym.isEffectivelyFinal || sym.allOverriddenSymbols.nonEmpty)
-
- /** @pre The type's final result type is an implicit function type `implicit Ts => R`.
- * @return The type of the `apply` member of `implicit Ts => R`.
- */
- private def directInfo(info: Type)(implicit ctx: Context): Type = info match {
- case info: PolyType => info.derivedLambdaType(resType = directInfo(info.resultType))
- case info: MethodType => info.derivedLambdaType(resType = directInfo(info.resultType))
- case info: ExprType => directInfo(info.resultType)
- case info => info.member(nme.apply).info
- }
+ override def prepareForUnit(tree: Tree)(implicit ctx: Context) =
+ ctx.fresh.updateStore(DirectMeth, new mutable.HashMap[Symbol, Symbol])
+
+ /** Should `sym` get a ..$direct companion?
+ * This is the case if (1) `sym` is a method with an implicit function type as final result type.
+ * However if `specializeMonoTargets` is false, we exclude symbols that are known
+ * to be only targets of monomorphic calls because they are effectively
+ * final and don't override anything.
+ */
+ private def shouldBeSpecialized(sym: Symbol)(implicit ctx: Context) =
+ sym.is(Method, butNot = Accessor) &&
+ defn.isImplicitFunctionType(sym.info.finalResultType) &&
+ !sym.isAnonymousFunction &&
+ (specializeMonoTargets || !sym.isEffectivelyFinal || sym.allOverriddenSymbols.nonEmpty)
+
+ /** @pre The type's final result type is an implicit function type `implicit Ts => R`.
+ * @return The type of the `apply` member of `implicit Ts => R`.
+ */
+ private def directInfo(info: Type)(implicit ctx: Context): Type = info match {
+ case info: PolyType => info.derivedLambdaType(resType = directInfo(info.resultType))
+ case info: MethodType => info.derivedLambdaType(resType = directInfo(info.resultType))
+ case info: ExprType => directInfo(info.resultType)
+ case info => info.member(nme.apply).info
+ }
- /** A new `m$direct` method to accompany the given method `m` */
- private def newDirectMethod(sym: Symbol)(implicit ctx: Context): Symbol = {
- val direct = sym.copy(
- name = DirectMethodName(sym.name.asTermName).asInstanceOf[sym.ThisName],
- flags = sym.flags | Synthetic,
- info = directInfo(sym.info))
- if (direct.allOverriddenSymbols.isEmpty) direct.resetFlag(Override)
- direct
- }
+ /** A new `m$direct` method to accompany the given method `m` */
+ private def newDirectMethod(sym: Symbol)(implicit ctx: Context): Symbol = {
+ val direct = sym.copy(
+ name = DirectMethodName(sym.name.asTermName).asInstanceOf[sym.ThisName],
+ flags = sym.flags | Synthetic,
+ info = directInfo(sym.info))
+ if (direct.allOverriddenSymbols.isEmpty) direct.resetFlag(Override)
+ direct
+ }
- /** The direct method `m$direct` that accompanies the given method `m`.
- * Create one if it does not exist already.
- */
- private def directMethod(sym: Symbol)(implicit ctx: Context): Symbol =
- if (sym.owner.isClass) {
- val direct = sym.owner.info.member(DirectMethodName(sym.name.asTermName))
- .suchThat(_.info matches directInfo(sym.info)).symbol
- if (direct.maybeOwner == sym.owner) direct
- else newDirectMethod(sym).enteredAfter(thisTransform)
+ /** The direct method `m$direct` that accompanies the given method `m`.
+ * Create one if it does not exist already.
+ */
+ private def directMethod(sym: Symbol)(implicit ctx: Context): Symbol =
+ if (sym.owner.isClass) {
+ val direct = sym.owner.info.member(DirectMethodName(sym.name.asTermName))
+ .suchThat(_.info matches directInfo(sym.info)).symbol
+ if (direct.maybeOwner == sym.owner) direct
+ else newDirectMethod(sym).enteredAfter(thisPhase)
+ }
+ else directMeth.getOrElseUpdate(sym, newDirectMethod(sym))
+
+ /** Transform `qual.apply` occurrences according to rewrite rule (2) above */
+ override def transformSelect(tree: Select)(implicit ctx: Context) =
+ if (tree.name == nme.apply &&
+ defn.isImplicitFunctionType(tree.qualifier.tpe.widen) &&
+ shouldBeSpecialized(tree.qualifier.symbol)) {
+ def directQual(tree: Tree): Tree = tree match {
+ case Apply(fn, args) => cpy.Apply(tree)(directQual(fn), args)
+ case TypeApply(fn, args) => cpy.TypeApply(tree)(directQual(fn), args)
+ case Block(stats, expr) => cpy.Block(tree)(stats, directQual(expr))
+ case tree: RefTree =>
+ cpy.Ref(tree)(DirectMethodName(tree.name.asTermName))
+ .withType(directMethod(tree.symbol).termRef)
}
- else directMeth.getOrElseUpdate(sym, newDirectMethod(sym))
-
- /** Transform `qual.apply` occurrences according to rewrite rule (2) above */
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) =
- if (tree.name == nme.apply &&
- defn.isImplicitFunctionType(tree.qualifier.tpe.widen) &&
- shouldBeSpecialized(tree.qualifier.symbol)) {
- def directQual(tree: Tree): Tree = tree match {
- case Apply(fn, args) => cpy.Apply(tree)(directQual(fn), args)
- case TypeApply(fn, args) => cpy.TypeApply(tree)(directQual(fn), args)
- case Block(stats, expr) => cpy.Block(tree)(stats, directQual(expr))
- case tree: RefTree =>
- cpy.Ref(tree)(DirectMethodName(tree.name.asTermName))
- .withType(directMethod(tree.symbol).termRef)
- }
- directQual(tree.qualifier)
- } else tree
-
- /** Transform methods with implicit function type result according to rewrite rule (1) above */
- override def transformDefDef(mdef: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
- val original = mdef.symbol
- if (shouldBeSpecialized(original)) {
- val direct = directMethod(original)
-
- def splitClosure(tree: Tree): (List[Type] => List[List[Tree]] => Tree, Tree) = tree match {
- case Block(Nil, expr) => splitClosure(expr)
- case Block((meth @ DefDef(nme.ANON_FUN, Nil, clparams :: Nil, _, _)) :: Nil, cl: Closure) =>
- val tparamSyms = mdef.tparams.map(_.symbol)
- val vparamSymss = mdef.vparamss.map(_.map(_.symbol))
- val clparamSyms = clparams.map(_.symbol)
- val remappedCore = (ts: List[Type]) => (prefss: List[List[Tree]]) =>
- meth.rhs
- .subst(tparamSyms ::: (vparamSymss.flatten ++ clparamSyms),
- ts.map(_.typeSymbol) ::: prefss.flatten.map(_.symbol))
- .changeOwnerAfter(original, direct, thisTransform)
- .changeOwnerAfter(meth.symbol, direct, thisTransform)
- val forwarder = ref(direct)
- .appliedToTypeTrees(tparamSyms.map(ref(_)))
- .appliedToArgss(vparamSymss.map(_.map(ref(_))) :+ clparamSyms.map(ref(_)))
- val fwdClosure = cpy.Block(tree)(cpy.DefDef(meth)(rhs = forwarder) :: Nil, cl)
- (remappedCore, fwdClosure)
- case EmptyTree =>
- (_ => _ => EmptyTree, EmptyTree)
- }
-
- val (remappedCore, fwdClosure) = splitClosure(mdef.rhs)
- val originalDef = cpy.DefDef(mdef)(rhs = fwdClosure)
- val directDef = transformDefDef(polyDefDef(direct.asTerm, remappedCore))
- flatTree(List(originalDef, directDef))
+ directQual(tree.qualifier)
+ } else tree
+
+ /** Transform methods with implicit function type result according to rewrite rule (1) above */
+ override def transformDefDef(mdef: DefDef)(implicit ctx: Context): Tree = {
+ val original = mdef.symbol
+ if (shouldBeSpecialized(original)) {
+ val direct = directMethod(original)
+
+ def splitClosure(tree: Tree): (List[Type] => List[List[Tree]] => Tree, Tree) = tree match {
+ case Block(Nil, expr) => splitClosure(expr)
+ case Block((meth @ DefDef(nme.ANON_FUN, Nil, clparams :: Nil, _, _)) :: Nil, cl: Closure) =>
+ val tparamSyms = mdef.tparams.map(_.symbol)
+ val vparamSymss = mdef.vparamss.map(_.map(_.symbol))
+ val clparamSyms = clparams.map(_.symbol)
+ val remappedCore = (ts: List[Type]) => (prefss: List[List[Tree]]) =>
+ meth.rhs
+ .subst(tparamSyms ::: (vparamSymss.flatten ++ clparamSyms),
+ ts.map(_.typeSymbol) ::: prefss.flatten.map(_.symbol))
+ .changeOwnerAfter(original, direct, thisPhase)
+ .changeOwnerAfter(meth.symbol, direct, thisPhase)
+ val forwarder = ref(direct)
+ .appliedToTypeTrees(tparamSyms.map(ref(_)))
+ .appliedToArgss(vparamSymss.map(_.map(ref(_))) :+ clparamSyms.map(ref(_)))
+ val fwdClosure = cpy.Block(tree)(cpy.DefDef(meth)(rhs = forwarder) :: Nil, cl)
+ (remappedCore, fwdClosure)
+ case EmptyTree =>
+ (_ => _ => EmptyTree, EmptyTree)
}
- else mdef
+
+ val (remappedCore, fwdClosure) = splitClosure(mdef.rhs)
+ val originalDef = cpy.DefDef(mdef)(rhs = fwdClosure)
+ val directDef = transformDefDef(polyDefDef(direct.asTerm, remappedCore))
+ flatTree(List(originalDef, directDef))
}
+ else mdef
}
}
diff --git a/compiler/src/dotty/tools/dotc/transform/Splitter.scala b/compiler/src/dotty/tools/dotc/transform/Splitter.scala
index 3b6af780c6b9..65a8143cd267 100644
--- a/compiler/src/dotty/tools/dotc/transform/Splitter.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Splitter.scala
@@ -1,14 +1,14 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import ast.Trees._
import core._
import Contexts._, Types._, Decorators._, Denotations._, Symbols._, SymDenotations._, Names._
/** Distribute applications into Block and If nodes
*/
-class Splitter extends MiniPhaseTransform { thisTransform =>
+class Splitter extends MiniPhase {
import ast.tpd._
override def phaseName: String = "splitter"
@@ -23,10 +23,10 @@ class Splitter extends MiniPhaseTransform { thisTransform =>
recur(tree.fun)
}
- override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context) =
distribute(tree, typeApply)
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo) =
+ override def transformApply(tree: Apply)(implicit ctx: Context) =
distribute(tree, apply)
private val typeApply = (fn: Tree, args: List[Tree]) => (ctx: Context) => TypeApply(fn, args)(ctx)
@@ -48,7 +48,7 @@ class Splitter extends MiniPhaseTransform { thisTransform =>
* if (ev$1.isInstanceOf[A]) ev$1.asInstanceOf[A].f(a)
* else ev$1.asInstanceOf[B].f(a)
*/
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformSelect(tree: Select)(implicit ctx: Context) = {
val Select(qual, name) = tree
def memberDenot(tp: Type): SingleDenotation = {
diff --git a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
index e223bff6e992..4f7e588a2548 100644
--- a/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/compiler/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import dotty.tools.dotc.transform.TreeTransforms.{TransformerInfo, TreeTransform, TreeTransformer}
+import dotty.tools.dotc.transform.MegaPhase._
import dotty.tools.dotc.ast.{Trees, tpd}
import scala.collection.{ mutable, immutable }
import ValueClasses._
@@ -35,7 +35,7 @@ import Symbols._, TypeUtils._, SymUtils._
*
* (4) Super calls do not go to synthetic field accessors
*/
-class SuperAccessors(thisTransformer: DenotTransformer) {
+class SuperAccessors(thisPhase: DenotTransformer) {
import tpd._
@@ -83,7 +83,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
val deferredOrPrivate = if (clazz is Trait) Deferred else Private
val acc = ctx.newSymbol(
clazz, superName, Artifact | Method | deferredOrPrivate,
- superInfo, coord = sym.coord).enteredAfter(thisTransformer)
+ superInfo, coord = sym.coord).enteredAfter(thisPhase)
// Diagnostic for SI-7091
if (!accDefs.contains(clazz))
ctx.error(s"Internal error: unable to store accessor definition in ${clazz}. clazz.hasPackageFlag=${clazz is Package}. Accessor required for ${sel} (${sel.show})", sel.pos)
@@ -130,7 +130,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
}
if (name.isTermName && mix.name.isEmpty &&
((clazz is Trait) || clazz != ctx.owner.enclosingClass || !validCurrentClass))
- superAccessorCall(sel)(ctx.withPhase(thisTransformer.next))
+ superAccessorCall(sel)(ctx.withPhase(thisPhase.next))
else sel
}
@@ -183,7 +183,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
}
val protectedAccessor = clazz.info.decl(accName).suchThat(_.signature == accType.signature).symbol orElse {
val newAcc = ctx.newSymbol(
- clazz, accName, Artifact | Method, accType, coord = sel.pos).enteredAfter(thisTransformer)
+ clazz, accName, Artifact | Method, accType, coord = sel.pos).enteredAfter(thisPhase)
val code = polyDefDef(newAcc, trefs => vrefss => {
val (receiver :: _) :: tail = vrefss
val base = receiver.select(sym).appliedToTypes(trefs)
@@ -235,7 +235,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
val accType = accTypeOf(sym.info)
val protectedAccessor = clazz.info.decl(accName).suchThat(_.signature == accType.signature).symbol orElse {
val newAcc = ctx.newSymbol(
- clazz, accName, Artifact, accType, coord = tree.pos).enteredAfter(thisTransformer)
+ clazz, accName, Artifact, accType, coord = tree.pos).enteredAfter(thisPhase)
val code = polyDefDef(newAcc, trefs => vrefss => {
val (receiver :: _) :: tail = vrefss
val base = receiver.select(sym).appliedToTypes(trefs)
@@ -267,7 +267,7 @@ class SuperAccessors(thisTransformer: DenotTransformer) {
val accType = MethodType(clazz.classInfo.selfType :: field.info :: Nil, defn.UnitType)
val protectedAccessor = clazz.info.decl(accName).symbol orElse {
val newAcc = ctx.newSymbol(
- clazz, accName, Artifact, accType, coord = tree.pos).enteredAfter(thisTransformer)
+ clazz, accName, Artifact, accType, coord = tree.pos).enteredAfter(thisPhase)
val code = DefDef(newAcc, vrefss => {
val (receiver :: value :: Nil) :: Nil = vrefss
Assign(receiver.select(field), value).withPos(tree.pos)
diff --git a/compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala b/compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala
index 74e3b6821a9d..ac87ffc91984 100644
--- a/compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala
+++ b/compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala
@@ -5,7 +5,7 @@ import core._
import Symbols._, Types._, Contexts._, Names._, StdNames._, Constants._, SymUtils._
import scala.collection.{ mutable, immutable }
import Flags._
-import TreeTransforms._
+import MegaPhase._
import DenotTransformers._
import ast.Trees._
import ast.untpd
@@ -36,7 +36,7 @@ import scala.language.postfixOps
* def equals(other: Any): Boolean
* def hashCode(): Int
*/
-class SyntheticMethods(thisTransformer: DenotTransformer) {
+class SyntheticMethods(thisPhase: DenotTransformer) {
import ast.tpd._
private[this] var myValueSymbols: List[Symbol] = Nil
@@ -80,7 +80,7 @@ class SyntheticMethods(thisTransformer: DenotTransformer) {
val synthetic = sym.copy(
owner = clazz,
flags = sym.flags &~ Deferred | Synthetic | Override,
- coord = clazz.coord).enteredAfter(thisTransformer).asTerm
+ coord = clazz.coord).enteredAfter(thisPhase).asTerm
def forwardToRuntime(vrefss: List[List[Tree]]): Tree =
ref(defn.runtimeMethodRef("_" + sym.name.toString)).appliedToArgs(This(clazz) :: vrefss.head)
diff --git a/compiler/src/dotty/tools/dotc/transform/TailRec.scala b/compiler/src/dotty/tools/dotc/transform/TailRec.scala
index f6660e813b9d..184a7881b0ed 100644
--- a/compiler/src/dotty/tools/dotc/transform/TailRec.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TailRec.scala
@@ -11,7 +11,7 @@ import Denotations.SingleDenotation
import Symbols._
import Types._
import NameKinds.TailLabelName
-import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import MegaPhase.MiniPhase
import reporting.diagnostic.messages.TailrecNotApplicable
/**
@@ -63,7 +63,7 @@ import reporting.diagnostic.messages.TailrecNotApplicable
* self recursive functions, that's why it's renamed to tailrec
*
*/
-class TailRec extends MiniPhaseTransform with FullParameterization { thisTransform =>
+class TailRec extends MiniPhase with FullParameterization {
import TailRec._
import dotty.tools.dotc.ast.tpd._
@@ -75,12 +75,12 @@ class TailRec extends MiniPhaseTransform with FullParameterization { thisTransfo
/** Symbols of methods that have @tailrec annotatios inside */
private val methodsWithInnerAnnots = new collection.mutable.HashSet[Symbol]()
- override def transformUnit(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformUnit(tree: Tree)(implicit ctx: Context): Tree = {
methodsWithInnerAnnots.clear()
tree
}
- override def transformTyped(tree: Typed)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformTyped(tree: Typed)(implicit ctx: Context): Tree = {
if (tree.tpt.tpe.hasAnnotation(defn.TailrecAnnot))
methodsWithInnerAnnots += ctx.owner.enclosingMethod
tree
@@ -94,7 +94,7 @@ class TailRec extends MiniPhaseTransform with FullParameterization { thisTransfo
else ctx.newSymbol(method, name.toTermName, labelFlags, method.info)
}
- override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context): tpd.Tree = {
val sym = tree.symbol
tree match {
case dd@DefDef(name, tparams, vparamss0, tpt, _)
diff --git a/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala b/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala
index f500583d172a..c0825c7e8bea 100644
--- a/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TransformByNameApply.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core._
import Symbols._
import SymDenotations._
@@ -17,12 +17,12 @@ import reporting.trace
/** Abstract base class of ByNameClosures and ElimByName, factoring out the
* common functionality to transform arguments of by-name parameters.
*/
-abstract class TransformByNameApply extends MiniPhaseTransform { thisTransformer: DenotTransformer =>
+abstract class TransformByNameApply extends MiniPhase { thisPhase: DenotTransformer =>
import ast.tpd._
/** The info of the tree's symbol before it is potentially transformed in this phase */
private def originalDenotation(tree: Tree)(implicit ctx: Context) =
- tree.symbol.denot(ctx.withPhase(thisTransformer))
+ tree.symbol.denot(ctx.withPhase(thisPhase))
/** If denotation had an ExprType before, it now gets a function type */
protected def exprBecomesFunction(symd: SymDenotation)(implicit ctx: Context) =
@@ -35,7 +35,7 @@ abstract class TransformByNameApply extends MiniPhaseTransform { thisTransformer
def mkByNameClosure(arg: Tree, argType: Type)(implicit ctx: Context): Tree = unsupported(i"mkClosure($arg)")
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformApply(tree: Apply)(implicit ctx: Context): Tree =
trace(s"transforming ${tree.show} at phase ${ctx.phase}", show = true) {
def transformArg(arg: Tree, formal: Type): Tree = formal.dealias match {
diff --git a/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala b/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala
index 946722227af9..be813dbeea90 100644
--- a/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TransformWildcards.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core.DenotTransformers._
import core.Contexts._
import ast.tpd
@@ -11,7 +11,7 @@ import ast.tpd
* `val x : T = _` to `val x : T = `
*
*/
-class TransformWildcards extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
+class TransformWildcards extends MiniPhase with IdentityDenotTransformer {
import tpd._
override def phaseName = "transformWildcards"
@@ -23,7 +23,7 @@ class TransformWildcards extends MiniPhaseTransform with IdentityDenotTransforme
}
}
- override def transformValDef(tree: ValDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformValDef(tree: ValDef)(implicit ctx: Context): Tree = {
if (ctx.owner.isClass) tree
else cpy.ValDef(tree)(rhs = tree.rhs.wildcardToDefault)
}
diff --git a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
index e2237c187a27..ddd3ccd827cf 100644
--- a/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -1,7 +1,7 @@
package dotty.tools.dotc
package transform
-import TreeTransforms._
+import MegaPhase._
import core.Names.Name
import core.DenotTransformers._
import core.Denotations._
@@ -106,7 +106,7 @@ class TreeChecker extends Phase with SymTransformer {
}
private def previousPhases(phases: List[Phase])(implicit ctx: Context): List[Phase] = phases match {
- case (phase: TreeTransformer) :: phases1 =>
+ case (phase: MegaPhase) :: phases1 =>
val subPhases = phase.miniPhases
val previousSubPhases = previousPhases(subPhases.toList)
if (previousSubPhases.length == subPhases.length) previousSubPhases ::: previousPhases(phases1)
diff --git a/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala b/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala
index 44d26e7dd3a4..a669dcb79843 100644
--- a/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala
+++ b/compiler/src/dotty/tools/dotc/transform/TryCatchPatterns.scala
@@ -9,7 +9,7 @@ import core.NameKinds.ExceptionBinderName
import dotty.tools.dotc.core.Decorators._
import dotty.tools.dotc.core.Flags
import dotty.tools.dotc.core.Contexts.Context
-import dotty.tools.dotc.transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import dotty.tools.dotc.transform.MegaPhase.MiniPhase
import dotty.tools.dotc.util.Positions.Position
/** Compiles the cases that can not be handled by primitive catch cases as a common pattern match.
@@ -40,7 +40,7 @@ import dotty.tools.dotc.util.Positions.Position
* - `case _: T =>` where `T` is not `Throwable`
*
*/
-class TryCatchPatterns extends MiniPhaseTransform {
+class TryCatchPatterns extends MiniPhase {
import dotty.tools.dotc.ast.tpd._
def phaseName: String = "tryCatchPatterns"
@@ -58,7 +58,7 @@ class TryCatchPatterns extends MiniPhaseTransform {
case _ =>
}
- override def transformTry(tree: Try)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformTry(tree: Try)(implicit ctx: Context): Tree = {
val (tryCases, patternMatchCases) = tree.cases.span(isCatchCase)
val fallbackCase = mkFallbackPatterMatchCase(patternMatchCases, tree.pos)
cpy.Try(tree)(cases = tryCases ++ fallbackCase)
@@ -81,7 +81,7 @@ class TryCatchPatterns extends MiniPhaseTransform {
}
private def mkFallbackPatterMatchCase(patternMatchCases: List[CaseDef], pos: Position)(
- implicit ctx: Context, info: TransformerInfo): Option[CaseDef] = {
+ implicit ctx: Context): Option[CaseDef] = {
if (patternMatchCases.isEmpty) None
else {
val exName = ExceptionBinderName.fresh()
diff --git a/compiler/src/dotty/tools/dotc/transform/VCElideAllocations.scala b/compiler/src/dotty/tools/dotc/transform/VCElideAllocations.scala
index 1582158acaaa..91076cbc3cc3 100644
--- a/compiler/src/dotty/tools/dotc/transform/VCElideAllocations.scala
+++ b/compiler/src/dotty/tools/dotc/transform/VCElideAllocations.scala
@@ -4,7 +4,7 @@ package transform
import ast.{Trees, tpd}
import core._, core.Decorators._
import Contexts._, Trees._, StdNames._, Symbols._
-import DenotTransformers._, TreeTransforms._, Phases.Phase
+import DenotTransformers._, MegaPhase._, Phases.Phase
import ExtensionMethods._, TreeExtractors._, ValueClasses._
/** This phase elides unnecessary value class allocations
@@ -15,14 +15,14 @@ import ExtensionMethods._, TreeExtractors._, ValueClasses._
* new V(u1) == new V(u2) => u1 == u2
* (new V(u)).underlying() => u
*/
-class VCElideAllocations extends MiniPhaseTransform with IdentityDenotTransformer {
+class VCElideAllocations extends MiniPhase with IdentityDenotTransformer {
import tpd._
override def phaseName: String = "vcElideAllocations"
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[ElimErasedValueType])
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformApply(tree: Apply)(implicit ctx: Context): Tree =
tree match {
// new V(u1) == new V(u2) => u1 == u2
// (We don't handle != because it has been eliminated by InterceptedMethods)
diff --git a/compiler/src/dotty/tools/dotc/transform/VCInlineMethods.scala b/compiler/src/dotty/tools/dotc/transform/VCInlineMethods.scala
index 146d30697bae..7daa374855a6 100644
--- a/compiler/src/dotty/tools/dotc/transform/VCInlineMethods.scala
+++ b/compiler/src/dotty/tools/dotc/transform/VCInlineMethods.scala
@@ -4,7 +4,7 @@ package transform
import ast.{Trees, tpd}
import core._, core.Decorators._
import Contexts._, Trees._, Types._
-import DenotTransformers._, TreeTransforms._, Phases.Phase
+import DenotTransformers._, MegaPhase._, Phases.Phase
import ExtensionMethods._, ValueClasses._
import collection.mutable.ListBuffer
@@ -39,7 +39,7 @@ import collection.mutable.ListBuffer
* methods (like [[TypeSpecializer]]), this way [[VCInlineMethods]] does not
* need to have any knowledge of the name mangling done by other phases.
*/
-class VCInlineMethods extends MiniPhaseTransform with IdentityDenotTransformer {
+class VCInlineMethods extends MiniPhase with IdentityDenotTransformer {
import tpd._
override def phaseName: String = "vcInlineMethods"
@@ -98,10 +98,10 @@ class VCInlineMethods extends MiniPhaseTransform with IdentityDenotTransformer {
tree
}
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformSelect(tree: Select)(implicit ctx: Context): Tree =
rewireIfNeeded(tree)
- override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context): Tree =
rewireIfNeeded(tree)
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
+ override def transformApply(tree: Apply)(implicit ctx: Context): Tree =
rewireIfNeeded(tree)
}
diff --git a/compiler/src/dotty/tools/dotc/transform/localopt/Simplify.scala b/compiler/src/dotty/tools/dotc/transform/localopt/Simplify.scala
index c78536c3b4fc..d336c944e9e6 100644
--- a/compiler/src/dotty/tools/dotc/transform/localopt/Simplify.scala
+++ b/compiler/src/dotty/tools/dotc/transform/localopt/Simplify.scala
@@ -8,7 +8,7 @@ import core.Types._
import core.Flags._
import core.Decorators._
import core.NameOps._
-import transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
+import transform.MegaPhase.MiniPhase
import config.Printers.simplify
import ast.tpd
import dotty.tools.dotc.core.PhantomErasure
@@ -27,7 +27,7 @@ import scala.annotation.tailrec
* - running this phase late allows to eliminate inefficiencies created by previous phase
* - different patters are easier to optimize at different moments of pipeline
*/
-class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
+class Simplify extends MiniPhase with IdentityDenotTransformer {
import tpd._
override def phaseName: String = "simplify"
override val cpy = tpd.cpy
@@ -93,11 +93,11 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
if (p.isEmpty) o else o.filter(x => p.contains(x.name))
}
- this
+ ctx
}
// The entry point of local optimisation: DefDefs
- override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformDefDef(tree: DefDef)(implicit ctx: Context): Tree = {
val ctx0 = ctx
if (ctx.settings.optimise.value && !tree.symbol.is(Label)) {
implicit val ctx: Context = ctx0.withOwner(tree.symbol(ctx0))
diff --git a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
index 204e9cf81e55..efecb89d5d68 100644
--- a/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
+++ b/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
@@ -9,10 +9,11 @@ import StdNames._, Denotations._, Scopes._, Constants.Constant, SymUtils._
import NameKinds.DefaultGetterName
import Annotations._
import util.Positions._
+import util.Store
import scala.collection.{ mutable, immutable }
import ast._
import Trees._
-import TreeTransforms._
+import MegaPhase._
import config.Printers.{checks, noPrinter}
import util.DotClass
import scala.util.{Try, Success, Failure}
@@ -793,7 +794,7 @@ import RefChecks._
* todo: But RefChecks is not done yet. It's still a somewhat dirty port from the Scala 2 version.
* todo: move untrivial logic to their own mini-phases
*/
-class RefChecks extends MiniPhase { thisTransformer =>
+class RefChecks extends MiniPhase { thisPhase =>
import tpd._
import reporting.diagnostic.messages.ForwardReferenceExtendsOverDefinition
@@ -804,84 +805,81 @@ class RefChecks extends MiniPhase { thisTransformer =>
// Needs to run after ElimRepeated for override checks involving varargs methods
override def runsAfter = Set(classOf[ElimRepeated])
- val treeTransform = new Transform(NoLevelInfo)
+ private var LevelInfo: Store.Location[OptLevelInfo] = _
+ private def currentLevel(implicit ctx: Context): OptLevelInfo = ctx.store(LevelInfo)
- class Transform(currentLevel: RefChecks.OptLevelInfo = RefChecks.NoLevelInfo) extends TreeTransform {
- def phase = thisTransformer
+ override def initContext(ctx: FreshContext) =
+ LevelInfo = ctx.addLocation(NoLevelInfo)
- 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 transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] = trees
+ override def prepareForStats(trees: List[Tree])(implicit ctx: Context) =
+ if (ctx.owner.isTerm)
+ ctx.fresh.updateStore(LevelInfo, new LevelInfo(currentLevel.levelAndIndex, trees))
+ else ctx
- override def transformValDef(tree: ValDef)(implicit ctx: Context, info: TransformerInfo) = {
- checkDeprecatedOvers(tree)
- val sym = tree.symbol
- if (sym.exists && sym.owner.isTerm) {
- tree.rhs match {
- case Ident(nme.WILDCARD) => ctx.error(UnboundPlaceholderParameter(), sym.pos)
+ override def transformValDef(tree: ValDef)(implicit ctx: Context) = {
+ checkDeprecatedOvers(tree)
+ val sym = tree.symbol
+ if (sym.exists && sym.owner.isTerm) {
+ tree.rhs match {
+ case Ident(nme.WILDCARD) => ctx.error(UnboundPlaceholderParameter(), sym.pos)
+ case _ =>
+ }
+ if (!sym.is(Lazy)) {
+ currentLevel.levelAndIndex.get(sym) match {
+ case Some((level, symIdx)) if symIdx <= level.maxIndex =>
+ ctx.error(ForwardReferenceExtendsOverDefinition(sym, level.refSym), level.refPos)
case _ =>
}
- if (!sym.is(Lazy)) {
- currentLevel.levelAndIndex.get(sym) match {
- case Some((level, symIdx)) if symIdx <= level.maxIndex =>
- ctx.error(ForwardReferenceExtendsOverDefinition(sym, level.refSym), level.refPos)
- case _ =>
- }
- }
}
- tree
}
+ tree
+ }
- override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo) = {
- checkDeprecatedOvers(tree)
- if (tree.symbol is Macro) EmptyTree else tree
- }
+ override def transformDefDef(tree: DefDef)(implicit ctx: Context) = {
+ checkDeprecatedOvers(tree)
+ if (tree.symbol is Macro) EmptyTree else tree
+ }
- override def transformTemplate(tree: Template)(implicit ctx: Context, info: TransformerInfo) = try {
- val cls = ctx.owner
- checkOverloadedRestrictions(cls)
- checkParents(cls)
- checkCompanionNameClashes(cls)
- checkAllOverrides(cls)
+ override def transformTemplate(tree: Template)(implicit ctx: Context) = try {
+ val cls = ctx.owner
+ checkOverloadedRestrictions(cls)
+ checkParents(cls)
+ checkCompanionNameClashes(cls)
+ checkAllOverrides(cls)
+ tree
+ } catch {
+ case ex: MergeError =>
+ ctx.error(ex.getMessage, tree.pos)
tree
- } catch {
- case ex: MergeError =>
- ctx.error(ex.getMessage, tree.pos)
- tree
- }
+ }
- override def transformIdent(tree: Ident)(implicit ctx: Context, info: TransformerInfo) = {
- checkUndesiredProperties(tree.symbol, tree.pos)
- currentLevel.enterReference(tree.symbol, tree.pos)
- tree
- }
+ override def transformIdent(tree: Ident)(implicit ctx: Context) = {
+ checkUndesiredProperties(tree.symbol, tree.pos)
+ currentLevel.enterReference(tree.symbol, tree.pos)
+ tree
+ }
- override def transformSelect(tree: Select)(implicit ctx: Context, info: TransformerInfo) = {
- checkUndesiredProperties(tree.symbol, tree.pos)
- tree
- }
+ override def transformSelect(tree: Select)(implicit ctx: Context) = {
+ checkUndesiredProperties(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 transformApply(tree: Apply)(implicit ctx: Context) = {
+ 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
}
+ tree
+ }
- override def transformNew(tree: New)(implicit ctx: Context, info: TransformerInfo) = {
- currentLevel.enterReference(tree.tpe.typeSymbol, tree.pos)
- tree
- }
+ override def transformNew(tree: New)(implicit ctx: Context) = {
+ currentLevel.enterReference(tree.tpe.typeSymbol, tree.pos)
+ tree
}
}
@@ -1379,7 +1377,7 @@ class RefChecks extends MiniPhase { thisTransformer =>
checkAllOverrides(ctx.owner)
checkAnyValSubclass(ctx.owner)
if (ctx.owner.isDerivedValueClass)
- ctx.owner.primaryConstructor.makeNotPrivateAfter(NoSymbol, thisTransformer) // SI-6601, must be done *after* pickler!
+ ctx.owner.primaryConstructor.makeNotPrivateAfter(NoSymbol, thisPhase) // SI-6601, must be done *after* pickler!
tree
@@ -1408,7 +1406,7 @@ class RefChecks extends MiniPhase { thisTransformer =>
checkAllOverrides(ctx.owner)
checkAnyValSubclass(ctx.owner)
if (ctx.owner.isDerivedValueClass)
- ctx.owner.primaryConstructor.makeNotPrivateAfter(NoSymbol, thisTransformer) // SI-6601, must be done *after* pickler!
+ ctx.owner.primaryConstructor.makeNotPrivateAfter(NoSymbol, thisPhase) // SI-6601, must be done *after* pickler!
tree
case tpt: TypeTree =>
diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
index 09d380eb06f9..45c8a422b855 100644
--- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -349,8 +349,11 @@ trait TypeAssigner {
def assignType(tree: untpd.Apply, fn: Tree, args: List[Tree])(implicit ctx: Context) = {
val ownType = fn.tpe.widen match {
case fntpe: MethodType =>
- if (fntpe.isDependent) safeSubstParams(fntpe.resultType, fntpe.paramRefs, args.tpes)
- else fntpe.resultType
+ if (sameLength(fntpe.paramInfos, args) || ctx.phase.prev.relaxedTyping || true)
+ if (fntpe.isDependent) safeSubstParams(fntpe.resultType, fntpe.paramRefs, args.tpes)
+ else fntpe.resultType
+ else
+ errorType(i"wrong number of arguments at ${ctx.phase.prev} for $fntpe: ${fn.tpe}, expected: ${fntpe.paramInfos.length}, found: ${args.length}", tree.pos)
case t =>
errorType(err.takesNoParamsStr(fn, ""), tree.pos)
}
diff --git a/compiler/src/dotty/tools/dotc/util/Store.scala b/compiler/src/dotty/tools/dotc/util/Store.scala
new file mode 100644
index 000000000000..72e6da0faa49
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/util/Store.scala
@@ -0,0 +1,33 @@
+package dotty.tools.dotc.util
+
+object Store {
+
+ class Location[T](private[Store] val idx: Int) extends AnyVal
+
+ val empty: Store = new Store(Array())
+}
+
+class Store(private val elems: Array[AnyRef]) extends AnyVal {
+ import Store._
+
+ def newLocation[T](): (Location[T], Store) = {
+ val elems1 = new Array[AnyRef](elems.length + 1)
+ System.arraycopy(elems, 0, elems1, 0, elems.length)
+ (new Location(elems.length), new Store(elems1))
+ }
+
+ def newLocation[T](initial: T): (Location[T], Store) = {
+ val (loc, store) = newLocation[T]()
+ store.elems(loc.idx) = initial.asInstanceOf[AnyRef]
+ (loc, store)
+ }
+
+ def updated[T](loc: Location[T], value: T): Store = {
+ val elems1 = elems.clone
+ elems1(loc.idx) = value.asInstanceOf[AnyRef]
+ new Store(elems1)
+ }
+
+ def apply[T](loc: Location[T]): T =
+ elems(loc.idx).asInstanceOf[T]
+}
diff --git a/compiler/test/dotc/tests.scala b/compiler/test/dotc/tests.scala
index 39ab4da8b9bd..a81a8c12fce0 100644
--- a/compiler/test/dotc/tests.scala
+++ b/compiler/test/dotc/tests.scala
@@ -348,7 +348,7 @@ class tests extends CompilerTest {
"NormalizeFlags.scala", "OverridingPairs.scala", "ParamForwarding.scala", "Pickler.scala", "PostTyper.scala",
"ResolveSuper.scala", "RestoreScopes.scala", "SeqLiterals.scala", "Splitter.scala", "SuperAccessors.scala",
"SymUtils.scala", "SyntheticMethods.scala", "TailRec.scala", "TreeChecker.scala", "TreeExtractors.scala",
- "TreeGen.scala", "TreeTransform.scala", "TypeTestsCasts.scala", "TypeUtils.scala", "ValueClasses.scala",
+ "TreeGen.scala", "MegaPhase.scala", "TypeTestsCasts.scala", "TypeUtils.scala", "ValueClasses.scala",
"VCElideAllocations.scala", "VCInlineMethods.scala"
) map (s"${dotcDir}transform/" + _), testPickling)
diff --git a/compiler/test/dotty/tools/dotc/transform/CreateCompanionObjectsTest.scala b/compiler/test/dotty/tools/dotc/transform/CreateCompanionObjectsTest.scala
index 18acb21057df..f0dfdbb14a69 100644
--- a/compiler/test/dotty/tools/dotc/transform/CreateCompanionObjectsTest.scala
+++ b/compiler/test/dotty/tools/dotc/transform/CreateCompanionObjectsTest.scala
@@ -13,7 +13,6 @@ import Symbols._
import Types._
import Decorators._
import Trees._
-import TreeTransforms.{TreeTransform, TreeTransformer}
class CreateCompanionObjectsTest extends DottyTest {
diff --git a/compiler/test/dotty/tools/dotc/transform/PostTyperTransformerTest.scala b/compiler/test/dotty/tools/dotc/transform/PostTyperTransformerTest.scala
index 03d6d9b36e92..605f222c3cf5 100644
--- a/compiler/test/dotty/tools/dotc/transform/PostTyperTransformerTest.scala
+++ b/compiler/test/dotty/tools/dotc/transform/PostTyperTransformerTest.scala
@@ -13,7 +13,6 @@ import Symbols._
import Types._
import Decorators._
import Trees._
-import TreeTransforms.{TreeTransform, TreeTransformer}
class PostTyperTransformerTest extends DottyTest {
/* FIXME: re-enable after adapting to new scheme
diff --git a/compiler/test/dotty/tools/dotc/transform/TreeTransformerTest.scala b/compiler/test/dotty/tools/dotc/transform/TreeTransformerTest.scala
index 238ce3d51cbb..aace7b734d17 100644
--- a/compiler/test/dotty/tools/dotc/transform/TreeTransformerTest.scala
+++ b/compiler/test/dotty/tools/dotc/transform/TreeTransformerTest.scala
@@ -3,7 +3,7 @@ package dotc
package transform
import org.junit.{Assert, Test}
-import TreeTransforms.{TransformerInfo, TreeTransformer, MiniPhaseTransform}
+import MegaPhase._
import ast.tpd
import core.Constants.Constant
import core.Contexts.Context
@@ -14,16 +14,12 @@ class TreeTransformerTest extends DottyTest {
def shouldReturnSameTreeIfUnchanged: Unit = checkCompile("frontend", "class A{ val d = 1}") {
(tree, context) =>
implicit val ctx = context
- class EmptyTransform extends MiniPhaseTransform {
+ class EmptyTransform extends MiniPhase {
override def phaseName: String = "empty"
init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId)
}
- val transformer = new TreeTransformer {
- override def miniPhases = Array(new EmptyTransform)
-
- override def phaseName: String = "test"
- }
- val transformed = transformer.macroTransform(tree)
+ val transformer = new MegaPhase(Array(new EmptyTransform))
+ val transformed = transformer.transformUnit(tree)
Assert.assertTrue("returns same tree if unmodified",
tree eq transformed
@@ -34,18 +30,14 @@ class TreeTransformerTest extends DottyTest {
def canReplaceConstant: Unit = checkCompile("frontend", "class A{ val d = 1}") {
(tree, context) =>
implicit val ctx = context
- class ConstantTransform extends MiniPhaseTransform {
+ class ConstantTransform extends MiniPhase {
- override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = tpd.Literal(Constant(2))
+ override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context): tpd.Tree = tpd.Literal(Constant(2))
override def phaseName: String = "canReplaceConstant"
init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId)
}
- val transformer = new TreeTransformer {
- override def miniPhases = Array(new ConstantTransform)
-
- override def phaseName: String = "test"
- }
- val transformed = transformer.macroTransform(tree)
+ val transformer = new MegaPhase(Array(new ConstantTransform))
+ val transformed = transformer.transformUnit(tree)
Assert.assertTrue("returns same tree if unmodified",
transformed.toString.contains("List(ValDef(Modifiers(,,List()),d,TypeTree[TypeRef(ThisType(module class scala),Int)],Literal(Constant(2)))")
@@ -56,12 +48,12 @@ class TreeTransformerTest extends DottyTest {
def canOverwrite: Unit = checkCompile("frontend", "class A{ val d = 1}") {
(tree, context) =>
implicit val ctx = context
- class Transformation extends MiniPhaseTransform {
+ class Transformation extends MiniPhase {
- override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = tpd.Literal(Constant(-1))
+ override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context): tpd.Tree = tpd.Literal(Constant(-1))
override def phaseName: String = "canOverwrite"
- override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.ValDef = {
+ override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context): tpd.ValDef = {
Assert.assertTrue("transformation of children succeeded",
tree.rhs.toString == "Literal(Constant(-1))"
)
@@ -70,13 +62,8 @@ class TreeTransformerTest extends DottyTest {
init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId)
}
- val transformer = new TreeTransformer {
- override def miniPhases = Array(new Transformation)
-
- override def phaseName: String = "test"
-
- }
- val tr = transformer.macroTransform(tree).toString
+ val transformer = new MegaPhase(Array(new Transformation))
+ val tr = transformer.transformUnit(tree).toString
Assert.assertTrue("node can rewrite children",
tr.contains("Literal(Constant(2))") && !tr.contains("Literal(Constant(-1))")
@@ -87,17 +74,17 @@ class TreeTransformerTest extends DottyTest {
def transformationOrder: Unit = checkCompile("frontend", "class A{ val d = 1}") {
(tree, context) =>
implicit val ctx = context
- class Transformation1 extends MiniPhaseTransform {
+ class Transformation1 extends MiniPhase {
override def phaseName: String = "transformationOrder1"
- override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context): tpd.Tree = {
Assert.assertTrue("correct constant",
tree.const.toString == "Constant(1)"
)
tpd.cpy.Literal(tree)(Constant(-1))
}
- override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.ValDef = {
+ override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context): tpd.ValDef = {
Assert.assertTrue("transformation of children succeeded",
tree.rhs.toString == "Literal(Constant(-1))"
)
@@ -106,9 +93,9 @@ class TreeTransformerTest extends DottyTest {
init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId)
}
- class Transformation2 extends MiniPhaseTransform {
+ class Transformation2 extends MiniPhase {
override def phaseName: String = "transformationOrder2"
- override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.ValDef = {
+ override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context): tpd.ValDef = {
Assert.assertTrue("transformation of children succeeded",
tree.rhs.toString == "Literal(Constant(2))"
)
@@ -117,12 +104,8 @@ class TreeTransformerTest extends DottyTest {
init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId)
}
- val transformer = new TreeTransformer {
- override def miniPhases = Array(new Transformation1, new Transformation2)
-
- override def phaseName: String = "test"
- }
- val tr = transformer.macroTransform(tree).toString
+ val transformer = new MegaPhase(Array(new Transformation1, new Transformation2))
+ val tr = transformer.transformUnit(tree).toString
Assert.assertTrue("node can rewrite children",
tr.contains("Literal(Constant(3))")
@@ -134,9 +117,9 @@ class TreeTransformerTest extends DottyTest {
(tree, context) =>
implicit val ctx = context
var transformed1 = 0
- class Transformation1 extends MiniPhaseTransform {
+ class Transformation1 extends MiniPhase {
override def phaseName: String = "invocationCount1"
- override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context): tpd.Tree = {
transformed1 += 1
Assert.assertTrue("correct constant",
tree.const.toString == "Constant(1)"
@@ -144,7 +127,7 @@ class TreeTransformerTest extends DottyTest {
tpd.cpy.Literal(tree)(Constant(-1))
}
- override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context) = {
transformed1 += 1
Assert.assertTrue("transformation of children succeeded",
tree.rhs.toString == "Literal(Constant(-3))"
@@ -155,10 +138,10 @@ class TreeTransformerTest extends DottyTest {
init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId)
}
var transformed2 = 0
- class Transformation2 extends MiniPhaseTransform {
+ class Transformation2 extends MiniPhase {
var constantsSeen = 0
override def phaseName: String = "invocationCount2"
- override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
+ override def transformLiteral(tree: tpd.Literal)(implicit ctx: Context): tpd.Tree = {
transformed2 += 1
constantsSeen match {
case 0 =>
@@ -175,7 +158,7 @@ class TreeTransformerTest extends DottyTest {
tpd.cpy.Literal(tree)(Constant(-3))
}
- override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo) = {
+ override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context) = {
transformed2 += 1
Assert.assertTrue("transformation of children succeeded",
tree.rhs.toString == "Literal(Constant(-3))"
@@ -185,12 +168,8 @@ class TreeTransformerTest extends DottyTest {
init(ctx, ctx.period.firstPhaseId, ctx.period.lastPhaseId)
}
- val transformer = new TreeTransformer {
- override def miniPhases = Array(new Transformation1, new Transformation2)
-
- override def phaseName: String = "test"
- }
- val tr = transformer.macroTransform(tree).toString
+ val transformer = new MegaPhase(Array(new Transformation1, new Transformation2))
+ val tr = transformer.transformUnit(tree).toString
Assert.assertTrue("transformations aren't invoked multiple times",
transformed1 == 2 && transformed2 == 3
)
diff --git a/doc-tool/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala b/doc-tool/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala
index 6577f0cb784f..00dcd83b37dc 100644
--- a/doc-tool/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala
+++ b/doc-tool/src/dotty/tools/dottydoc/core/DocImplicitsPhase.scala
@@ -2,17 +2,17 @@ package dotty.tools
package dottydoc
package core
-import dotty.tools.dotc.transform.TreeTransforms.{ MiniPhaseTransform, TransformerInfo }
+import dotty.tools.dotc.transform.MegaPhase.MiniPhase
import dotty.tools.dotc.core.Flags
import dotc.core.Contexts.Context
import util.syntax._
-class DocImplicitsPhase extends MiniPhaseTransform { thisTransformer =>
+class DocImplicitsPhase extends MiniPhase {
import dotty.tools.dotc.ast.tpd._
def phaseName = "addImplicitsPhase"
- override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformDefDef(tree: DefDef)(implicit ctx: Context): Tree = {
if (
tree.symbol.is(Flags.Implicit) && // has to have an implicit flag
tree.symbol.owner.isStaticOwner && // owner has to be static (e.g. top-level `object`)
diff --git a/doc-tool/src/dotty/tools/dottydoc/core/transform.scala b/doc-tool/src/dotty/tools/dottydoc/core/transform.scala
index cdf57bd02c5d..5eba48b289f6 100644
--- a/doc-tool/src/dotty/tools/dottydoc/core/transform.scala
+++ b/doc-tool/src/dotty/tools/dottydoc/core/transform.scala
@@ -14,7 +14,7 @@ import util.traversing._
object transform {
/**
* The idea behind DocMiniTransformations is to fuse transformations to the
- * doc AST, much like `MiniPhaseTransform` in dotty core - but in a much more
+ * doc AST, much like `MiniPhase` in dotty core - but in a much more
* simple implementation
*
* Usage