aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-07-27 19:48:30 +0200
committerMartin Odersky <odersky@gmail.com>2013-07-27 19:48:30 +0200
commit60b3469ac70052b762cc7bf0d36bf2ec37e8e6dc (patch)
tree2aaf9fff135e0ac94a3a44457d3523eee02c01f7
parentcf65e84a6da2a151286a36297c057b72545960c8 (diff)
downloaddotty-60b3469ac70052b762cc7bf0d36bf2ec37e8e6dc.tar.gz
dotty-60b3469ac70052b762cc7bf0d36bf2ec37e8e6dc.tar.bz2
dotty-60b3469ac70052b762cc7bf0d36bf2ec37e8e6dc.zip
Redesign of trees.
1) Trees are now contravariant. 2) All creation ops, transformers, copiers are pushed into Instance. 3) Still to do: integrate TreeMappers and tpd.TreeTransformers.
-rw-r--r--src/dotty/tools/dotc/ast/CheckTrees.scala14
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala53
-rw-r--r--src/dotty/tools/dotc/ast/TreeInfo.scala356
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala1232
-rw-r--r--src/dotty/tools/dotc/ast/TypedTrees.scala225
-rw-r--r--src/dotty/tools/dotc/ast/UntypedTrees.scala152
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala12
-rw-r--r--src/dotty/tools/dotc/parsing/MarkupParsers.scala1
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala44
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala65
-rw-r--r--src/dotty/tools/dotc/typer/EtaExpansion.scala8
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala6
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala39
-rw-r--r--test/test/ContravariantTrees.scala65
-rw-r--r--test/test/DeSugarTest.scala36
-rw-r--r--test/test/DottyTest.scala1
-rw-r--r--test/test/parsePackage.scala5
18 files changed, 1244 insertions, 1072 deletions
diff --git a/src/dotty/tools/dotc/ast/CheckTrees.scala b/src/dotty/tools/dotc/ast/CheckTrees.scala
index 502b2eea3..a004789e6 100644
--- a/src/dotty/tools/dotc/ast/CheckTrees.scala
+++ b/src/dotty/tools/dotc/ast/CheckTrees.scala
@@ -8,16 +8,16 @@ import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
object CheckTrees {
- import tpd.{TreeMapper, localSyms, TreeOps}
+ import tpd._
def check(p: Boolean, msg: => String = "")(implicit ctx: Context): Unit = assert(p, msg)
- def checkTypeArg(arg: tpd.Tree, bounds: TypeBounds)(implicit ctx: Context): Unit = {
+ def checkTypeArg(arg: Tree, bounds: TypeBounds)(implicit ctx: Context): Unit = {
check(arg.isValueType)
check(bounds contains arg.tpe)
}
- def checkType(tree: tpd.Tree)(implicit ctx: Context): Unit = tree match {
+ def checkType(tree: Tree)(implicit ctx: Context): Unit = tree match {
case Ident(name) =>
case Select(qualifier, name) =>
check(qualifier.isValue)
@@ -31,7 +31,7 @@ object CheckTrees {
val cls = qual.tpe.typeSymbol
check(cls.isClass)
case Apply(fn, args) =>
- def checkArg(arg: tpd.Tree, name: Name, formal: Type): Unit = {
+ def checkArg(arg: Tree, name: Name, formal: Type): Unit = {
arg match {
case NamedArg(argName, _) =>
check(argName == name)
@@ -147,7 +147,7 @@ object CheckTrees {
check(left.isValueType); check(right.isValueType)
case RefinedTypeTree(tpt, refinements) =>
check(tpt.isValueType)
- def checkRefinements(forbidden: Set[Symbol], rs: List[tpd.Tree]): Unit = rs match {
+ def checkRefinements(forbidden: Set[Symbol], rs: List[Tree]): Unit = rs match {
case r :: rs1 =>
val rsym = r.symbol
check(rsym.isTerm || rsym.isAbstractOrAliasType)
@@ -185,7 +185,7 @@ object CheckTrees {
case nme.unapplySeq =>
// args need to be wrapped in (...: _*)
check(args.length == 1)
- check(args.head.isInstanceOf[tpd.SeqLiteral])
+ check(args.head.isInstanceOf[SeqLiteral])
case nme.unapply =>
val rtp = funtpe.resultType
val rsym = rtp.dealias.typeSymbol
@@ -221,7 +221,7 @@ object CheckTrees {
check(rhs.tpe <:< tpt.tpe)
}
case TypeDef(mods, name, tpt) =>
- check(tpt.isInstanceOf[Template[_]] || tpt.tpe.isInstanceOf[TypeBounds])
+ check(tpt.isInstanceOf[Template] || tpt.tpe.isInstanceOf[TypeBounds])
case Template(constr, parents, selfType, body) =>
case Import(expr, selectors) =>
check(expr.isValue)
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index 0a0638fa1..9f91d3143 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -5,7 +5,6 @@ package ast
import core._
import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
-import TreeInfo._
import Decorators._
import language.higherKinds
import collection.mutable.ListBuffer
@@ -22,19 +21,19 @@ object desugar {
if (!ctx.owner.isClass || (mods is Private)) vdef
else {
val lname = name.toLocalName
- val field = vdef.derivedValDef(mods, lname, tpt, rhs)
- val getter = vdef.derivedDefDef(mods, name, Nil, Nil, tpt, Ident(lname))
+ val field = cpy.ValDef(vdef, mods, lname, tpt, rhs)
+ val getter = cpy.DefDef(vdef, mods, name, Nil, Nil, tpt, Ident(lname))
if (!(mods is Mutable)) Thicket(field, getter)
else {
val setterParam = makeSyntheticParameter(tpt = TypeTree(field))
- val setter = vdef.derivedDefDef(
+ val setter = cpy.DefDef(vdef,
mods, name.getterToSetter, Nil, (setterParam :: Nil) :: Nil, EmptyTree, refOfDef(setterParam))
Thicket(field, getter, setter)
}
}
}
- def defDef(meth: DefDef, isPrimaryConstructor: Boolean = false): Tree = {
+ def defDef(meth: DefDef, isPrimaryConstructor: Boolean = false)(implicit ctx: Context): Tree = {
val DefDef(mods, name, tparams, vparamss, tpt, rhs) = meth
val epbuf = new ListBuffer[ValDef]
val tparams1 = tparams mapConserve {
@@ -45,7 +44,7 @@ object desugar {
epbuf +=
ValDef(Modifiers(paramFlags | Implicit), epname, cxbound, EmptyTree)
}
- tparam.derivedTypeDef(mods, name, tbounds, tparam.tparams)
+ cpy.TypeDef(tparam, mods, name, tbounds, tparam.tparams)
case tparam =>
tparam
}
@@ -60,7 +59,7 @@ object desugar {
case _ =>
vparamss :+ evidenceParams
}
- meth.derivedDefDef(mods, name, tparams1, vparamss1, tpt, rhs)
+ cpy.DefDef(meth, mods, name, tparams1, vparamss1, tpt, rhs)
}
def take(vparamss: List[List[ValDef]], n: Int): List[List[ValDef]] = vparamss match {
@@ -94,8 +93,8 @@ object desugar {
else {
val mods1 = meth1.mods | DefaultParameterized
val vparamss1 = vparamss map (_ map (vparam =>
- vparam.derivedValDef(vparam.mods, vparam.name, vparam.tpt, EmptyTree)))
- val meth2 = meth1.derivedDefDef(mods1, meth1.name, meth1.tparams, vparamss1, meth1.tpt, meth1.rhs)
+ cpy.ValDef(vparam, vparam.mods, vparam.name, vparam.tpt, EmptyTree)))
+ val meth2 = cpy.DefDef(meth1, mods1, meth1.name, meth1.tparams, vparamss1, meth1.tpt, meth1.rhs)
Thicket(meth2 :: defGetters)
}
}
@@ -103,9 +102,9 @@ object desugar {
def typeDef(tdef: TypeDef)(implicit ctx: Context): Tree = {
val TypeDef(mods, name, rhs) = tdef
if (mods is PrivateLocalParamAccessor) {
- val tparam = tdef.derivedTypeDef(
+ val tparam = cpy.TypeDef(tdef,
tdef.mods &~ PrivateLocal | ExpandedName, tdef.name.expandedName(ctx.owner), tdef.rhs, tdef.tparams)
- val alias = tdef.derivedTypeDef(
+ val alias = cpy.TypeDef(tdef,
Modifiers(PrivateLocal | Synthetic), tdef.name, refOfDef(tparam))
Thicket(tparam, alias)
}
@@ -123,7 +122,7 @@ object desugar {
case Thicket((meth: DefDef) :: defaults) => (meth, defaults)
}
- val tparams = constr1.tparams.map(tparam => tparam.derivedTypeDef(
+ val tparams = constr1.tparams.map(tparam => cpy.TypeDef(tparam,
Modifiers(Param), tparam.name, tparam.rhs, tparam.tparams))
// ensure parameter list is non-empty
@@ -133,10 +132,10 @@ object desugar {
ctx.error("case class needs to have at least one parameter list", cdef.pos)
ListOfNil
} else
- constr1.vparamss.nestedMap(vparam => vparam.derivedValDef(
+ constr1.vparamss.nestedMap(vparam => cpy.ValDef(vparam,
Modifiers(Param), vparam.name, vparam.tpt, vparam.rhs))
- val constr = constr1.derivedDefDef(
+ val constr = cpy.DefDef(constr1,
constr1.mods, constr1.name, tparams, vparamss, constr1.tpt, constr1.rhs)
val classTypeRef = {
@@ -160,9 +159,9 @@ object desugar {
if (mods is Abstract) Nil
else {
val copyFirstParams = vparamss.head.map(vparam =>
- vparam.derivedValDef(vparam.mods, vparam.name, vparam.tpt, refOfDef(vparam)))
+ cpy.ValDef(vparam, vparam.mods, vparam.name, vparam.tpt, refOfDef(vparam)))
val copyRestParamss = vparamss.tail.nestedMap(vparam =>
- vparam.derivedValDef(vparam.mods, vparam.name, vparam.tpt, EmptyTree))
+ cpy.ValDef(vparam, vparam.mods, vparam.name, vparam.tpt, EmptyTree))
DefDef(synthetic, nme.copy, tparams, copyFirstParams :: copyRestParamss, EmptyTree, creatorExpr) :: Nil
}
copyMeths ::: isDefinedMeth :: productArityMeth :: productElemMeths.toList
@@ -176,7 +175,7 @@ object desugar {
moduleDef(
ModuleDef(
Modifiers(Synthetic), name.toTermName,
- Template(emptyConstructor, parentConstr :: Nil, EmptyValDef(), defs))).toList
+ Template(emptyConstructor, parentConstr :: Nil, EmptyValDef, defs))).toList
}
val companions =
@@ -209,10 +208,10 @@ object desugar {
}
else Nil
- val cdef1 = cdef.derivedTypeDef(mods, name,
- impl.derivedTemplate(constr, parents, self,
+ val cdef1 = cpy.TypeDef(cdef, mods, name,
+ cpy.Template(impl, constr, parents, self,
constr1.tparams ::: constr1.vparamss.flatten ::: body ::: caseClassMeths))
- Thicket.make(cdef1 :: companions ::: implicitWrappers)
+ flatTree(cdef1 :: companions ::: implicitWrappers)
}
/** Expand to:
@@ -224,8 +223,8 @@ object desugar {
val clsName = name.moduleClassName
val clsRef = Ident(clsName)
val modul = ValDef(mods | ModuleCreationFlags, name, clsRef, New(clsRef, Nil))
- val clsSelf = self.derivedValDef(self.mods, self.name, SingletonTypeTree(Ident(name)), self.rhs)
- val clsTmpl = tmpl.derivedTemplate(constr, parents, clsSelf, body)
+ val clsSelf = cpy.ValDef(self, self.mods, self.name, SingletonTypeTree(Ident(name)), self.rhs)
+ val clsTmpl = cpy.Template(tmpl, constr, parents, clsSelf, body)
val cls = TypeDef(mods.toTypeFlags & AccessFlags | ModuleClassCreationFlags, clsName, clsTmpl)
Thicket(cls, valDef(modul))
}
@@ -251,7 +250,7 @@ object desugar {
*/
def makeBinop(left: Tree, op: Name, right: Tree): Tree = {
def assignToNamedArg(arg: Tree) = arg match {
- case Assign(Ident(name), rhs) => arg.derivedNamedArg(name, rhs)
+ case Assign(Ident(name), rhs) => cpy.NamedArg(arg, name, rhs)
case _ => arg
}
if (isLeftAssoc(op)) {
@@ -456,7 +455,7 @@ object desugar {
val restDefs =
for (((named, tpt), n) <- vars.zipWithIndex)
yield derivedValDef(mods, named, tpt, selector(n))
- Thicket.make(firstDef :: restDefs)
+ flatTree(firstDef :: restDefs)
}
}
@@ -536,7 +535,7 @@ object desugar {
makeFor(nme.map, nme.flatMap, enums, body) orElse tree
case PatDef(mods, pats, tpt, rhs) =>
val pats1 = if (tpt.isEmpty) pats else pats map (Typed(_, tpt))
- Thicket.make(pats1 map (makePatDef(mods, _, rhs)))
+ flatTree(pats1 map (makePatDef(mods, _, rhs)))
case _ =>
tree
}
@@ -549,7 +548,7 @@ object desugar {
/** If tree is a variable pattern, return its name and type, otherwise return None.
*/
private object VarPattern {
- def unapply(tree: Tree): Option[VarInfo] = tree match {
+ def unapply(tree: Tree)(implicit ctx: Context): Option[VarInfo] = tree match {
case id: Ident => Some(id, TypeTree())
case Typed(id: Ident, tpt) => Some((id, tpt))
case _ => None
@@ -560,7 +559,7 @@ object desugar {
* Works for expanded as well as unexpanded patterns
*
*/
- private object getVars extends TreeAccumulator[ListBuffer[VarInfo]] {
+ private object getVars extends UntypedTreeAccumulator[ListBuffer[VarInfo]] {
override def apply(buf: ListBuffer[VarInfo], tree: Tree): ListBuffer[VarInfo] = {
def seenName(name: Name) = buf exists (_._1.name == name)
def add(named: NameTree, t: Tree): ListBuffer[VarInfo] =
diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala
index cde8c10b0..de00cee7e 100644
--- a/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -7,14 +7,9 @@ import Flags._, Trees._, Types._, Contexts._
import Names._, StdNames._, NameOps._, Decorators._, Symbols._
import util.HashSet
-/** This class ...
- *
- * @author Martin Odersky
- * @version 1.0
- */
-abstract class TreeInfo {
-
- def isDeclarationOrTypeDef(tree: Tree[_ >: Untyped]): Boolean = tree match {
+trait TreeInfo[T >: Untyped] { self: Trees.Instance[T] =>
+
+ def isDeclarationOrTypeDef(tree: Tree): Boolean = tree match {
case DefDef(_, _, _, _, _, EmptyTree)
| ValDef(_, _, _, EmptyTree)
| TypeDef(_, _, _) => true
@@ -23,7 +18,7 @@ abstract class TreeInfo {
/** Is tree legal as a member definition of an interface?
*/
- def isInterfaceMember(tree: Tree[_ >: Untyped]): Boolean = tree match {
+ def isInterfaceMember(tree: Tree): Boolean = tree match {
case EmptyTree => true
case Import(_, _) => true
case TypeDef(_, _, _) => true
@@ -32,71 +27,14 @@ abstract class TreeInfo {
case _ => false
}
- /** Is tree a definition that has no side effects when
- * evaluated as part of a block after the first time?
- */
- def isIdempotentDef(tree: Tree[Type])(implicit ctx: Context): Boolean = tree match {
- case EmptyTree
- | TypeDef(_, _, _)
- | Import(_, _)
- | DefDef(_, _, _, _, _, _) =>
- true
- case ValDef(mods, _, _, rhs) =>
- !(mods is Mutable) && isIdempotentExpr(rhs)
- case _ =>
- false
- }
-
- def isOpAssign(tree: untpd.Tree) = tree match {
+ def isOpAssign(tree: Tree) = tree match {
case Apply(Select(_, name), _ :: Nil) if name.isOpAssignmentName => true
case _ => false
}
- /** Is tree an expression which can be inlined without affecting program semantics?
- *
- * Note that this is not called "isExprPure" since purity (lack of side-effects)
- * is not the litmus test. References to modules and lazy vals are side-effecting,
- * both because side-effecting code may be executed and because the first reference
- * takes a different code path than all to follow; but they are safe to inline
- * because the expression result from evaluating them is always the same.
- */
- def isIdempotentExpr(tree: Tree[Type])(implicit ctx: Context): Boolean = tree match {
- case EmptyTree
- | This(_)
- | Super(_, _)
- | Literal(_) =>
- true
- case Ident(_) =>
- tree.symbol is Stable
- case Select(qual, _) =>
- tree.symbol.isStable && isIdempotentExpr(qual)
- case TypeApply(fn, _) =>
- isIdempotentExpr(fn)
-/*
- * Not sure we'll need that. Comment out until we find out
- case Apply(Select(free @ Ident(_), nme.apply), _) if free.symbol.name endsWith nme.REIFY_FREE_VALUE_SUFFIX =>
- // see a detailed explanation of this trick in `GenSymbols.reifyFreeTerm`
- free.symbol.hasStableFlag && isIdempotentExpr(free)
-*/
- case Apply(fn, Nil) =>
- // Note: After uncurry, field accesses are represented as Apply(getter, Nil),
- // so an Apply can also be pure.
- // However, before typing, applications of nullary functional values are also
- // Apply(function, Nil) trees. To prevent them from being treated as pure,
- // we check that the callee is a method.
- // The callee might also be a Block, which has a null symbol, so we guard against that (SI-7185)
- fn.symbol != null && (fn.symbol is (Method, butNot = Lazy)) && isIdempotentExpr(fn)
- case Typed(expr, _) =>
- isIdempotentExpr(expr)
- case Block(stats, expr) =>
- (stats forall isIdempotentDef) && isIdempotentExpr(expr)
- case _ =>
- false
- }
-
- class MatchingArgs[T >: Untyped](params: List[Symbol], args: List[Tree[T]])(implicit ctx: Context) {
- def foreach(f: (Symbol, Tree[T]) => Unit): Boolean = {
- def recur(params: List[Symbol], args: List[Tree[T]]): Boolean = params match {
+ class MatchingArgs(params: List[Symbol], args: List[Tree])(implicit ctx: Context) {
+ def foreach(f: (Symbol, Tree) => Unit): Boolean = {
+ def recur(params: List[Symbol], args: List[Tree]): Boolean = params match {
case Nil => args.isEmpty
case param :: params1 =>
if (param.info.isRepeatedParam) {
@@ -111,8 +49,8 @@ abstract class TreeInfo {
}
recur(params, args)
}
- def zipped: List[(Symbol, Tree[T])] = map((_, _))
- def map[R](f: (Symbol, Tree[T]) => R): List[R] = {
+ def zipped: List[(Symbol, Tree)] = map((_, _))
+ def map[R](f: (Symbol, Tree) => R): List[R] = {
val b = List.newBuilder[R]
foreach(b += f(_, _))
b.result
@@ -129,7 +67,7 @@ abstract class TreeInfo {
* <init>(x$2, x$1)
* }
*/
- def methPart[T >: Untyped](tree: Tree[T]): Tree[T] = tree match {
+ def methPart(tree: Tree): Tree = tree match {
case Apply(fn, _) => methPart(fn)
case TypeApply(fn, _) => methPart(fn)
case AppliedTypeTree(fn, _) => methPart(fn)
@@ -138,7 +76,7 @@ abstract class TreeInfo {
}
/** The number of arguments in an application */
- def numArgs[T >: Untyped](tree: Tree[T]): Int = tree match {
+ def numArgs(tree: Tree): Int = tree match {
case Apply(fn, args) => numArgs(fn) + args.length
case TypeApply(fn, args) => numArgs(fn) + args.length
case AppliedTypeTree(fn, args) => numArgs(fn) + args.length
@@ -146,120 +84,75 @@ abstract class TreeInfo {
case _ => 0
}
- /** Is symbol potentially a getter of a mutable variable?
- */
- def mayBeVarGetter(sym: Symbol)(implicit ctx: Context): Boolean = {
- def maybeGetterType(tpe: Type): Boolean = tpe match {
- case _: ExprType | _: ImplicitMethodType => true
- case tpe: PolyType => maybeGetterType(tpe.resultType)
- case _ => false
- }
- sym.owner.isClass && !sym.isStable && maybeGetterType(sym.info)
- }
-
- /** Is tree a reference to a mutable variable, or to a potential getter
- * that has a setter in the same class?
- */
- def isVariableOrGetter(tree: Tree[Type])(implicit ctx: Context) = {
- def sym = tree.symbol
- def isVar = sym is Mutable
- def isGetter =
- mayBeVarGetter(sym) && sym.owner.info.member(sym.name.asTermName.getterToSetter).exists
-
- tree match {
- case Ident(_) => isVar
- case Select(_, _) => isVar || isGetter
- case Apply(_, _) =>
- methPart(tree) match {
- case Select(qual, nme.apply) => qual.tpe.member(nme.update).exists
- case _ => false
- }
- case _ => false
- }
- }
-
/** Is tree a self constructor call this(...)? I.e. a call to a constructor of the
* same object?
*/
- def isSelfConstrCall(tree: Tree[_ >: Untyped]): Boolean = methPart(tree) match {
+ def isSelfConstrCall(tree: Tree): Boolean = methPart(tree) match {
case Ident(nme.CONSTRUCTOR) | Select(This(_), nme.CONSTRUCTOR) => true
case _ => false
}
/** Is tree a super constructor call?
*/
- def isSuperConstrCall(tree: Tree[_ >: Untyped]): Boolean = methPart(tree) match {
+ def isSuperConstrCall(tree: Tree): Boolean = methPart(tree) match {
case Select(Super(_, _), nme.CONSTRUCTOR) => true
case _ => false
}
- def isSelfOrSuperConstrCall(tree: Tree[_ >: Untyped]): Boolean = methPart(tree) match {
+ def isSelfOrSuperConstrCall(tree: Tree): Boolean = methPart(tree) match {
case Ident(nme.CONSTRUCTOR)
| Select(This(_), nme.CONSTRUCTOR)
| Select(Super(_, _), nme.CONSTRUCTOR) => true
case _ => false
}
- /** Strips layers of `.asInstanceOf[T]` / `_.$asInstanceOf[T]()` from an expression */
- def stripCast(tree: Tree[Type])(implicit ctx: Context): Tree[Type] = {
- def isCast(sel: Tree[Type]) = defn.asInstanceOfMethods contains sel.symbol
- tree match {
- case TypeApply(sel @ Select(inner, _), _) if isCast(sel) =>
- stripCast(inner)
- case Apply(TypeApply(sel @ Select(inner, _), _), Nil) if isCast(sel) =>
- stripCast(inner)
- case t =>
- t
- }
- }
-
/** Is tree a variable pattern? */
- def isVarPattern[T >: Untyped](pat: Tree[T]): Boolean = pat match {
- case x: BackquotedIdent[_] => false
- case x: Ident[_] => x.name.isVariableName
+ def isVarPattern(pat: Tree): Boolean = pat match {
+ case x: BackquotedIdent => false
+ case x: Ident => x.name.isVariableName
case _ => false
}
/** The first constructor definition in `stats` */
- def firstConstructor[T >: Untyped](stats: List[Tree[T]]): Tree[T] = stats match {
- case (meth: DefDef[_]) :: _ if meth.name.isConstructorName => meth
+ def firstConstructor(stats: List[Tree]): Tree = stats match {
+ case (meth: DefDef) :: _ if meth.name.isConstructorName => meth
case stat :: stats => firstConstructor(stats)
- case nil => emptyTree()
+ case nil => EmptyTree
}
/** The arguments to the first constructor in `stats`. */
- def firstConstructorArgs[T >: Untyped](stats: List[Tree[T]]): List[Tree[T]] = firstConstructor(stats) match {
+ def firstConstructorArgs(stats: List[Tree]): List[Tree] = firstConstructor(stats) match {
case DefDef(_, _, _, args :: _, _, _) => args
case _ => Nil
}
/** The value definitions marked PRESUPER in this statement sequence */
- def preSuperFields[T >: Untyped](stats: List[Tree[T]]): List[ValDef[T]] =
- (stats filter isEarlyValDef).asInstanceOf[List[ValDef[T]]]
+ def preSuperFields(stats: List[Tree]): List[ValDef] =
+ (stats filter isEarlyValDef).asInstanceOf[List[ValDef]]
- def isEarlyDef(tree: Tree[_ >: Untyped]) = isEarlyValDef(tree) || isEarlyTypeDef(tree)
+ def isEarlyDef(tree: Tree) = isEarlyValDef(tree) || isEarlyTypeDef(tree)
- def isEarlyValDef(tree: Tree[_ >: Untyped]) = tree match {
+ def isEarlyValDef(tree: Tree) = tree match {
case ValDef(mods, _, _, _) => mods is Scala2PreSuper
case _ => false
}
- def isEarlyTypeDef(tree: Tree[_ >: Untyped]) = tree match {
+ def isEarlyTypeDef(tree: Tree) = tree match {
case TypeDef(mods, _, _) => mods is Scala2PreSuper
case _ => false
}
/** Is tpt a vararg type of the form T* ? */
- def isRepeatedParamType(tpt: Tree[_ >: Untyped])(implicit ctx: Context) = tpt match {
- case tpt: TypeTree[_] => tpt.typeOpt.isRepeatedParam
+ def isRepeatedParamType(tpt: Tree)(implicit ctx: Context) = tpt match {
+ case tpt: TypeTree => tpt.typeOpt.isRepeatedParam
case AppliedTypeTree(Select(_, tpnme.REPEATED_PARAM_CLASS), _) => true
case AppliedTypeTree(Select(_, tpnme.JAVA_REPEATED_PARAM_CLASS), _) => true
case _ => false
}
/** Is tpt a by-name parameter type of the form => T? */
- def isByNameParamType(tpt: Tree[_ >: Untyped])(implicit ctx: Context) = tpt match {
- case tpt: TypeTree[_] => tpt.typeOpt.typeSymbol == defn.ByNameParamClass
+ def isByNameParamType(tpt: Tree)(implicit ctx: Context) = tpt match {
+ case tpt: TypeTree => tpt.typeOpt.typeSymbol == defn.ByNameParamClass
case AppliedTypeTree(Select(_, tpnme.BYNAME_PARAM_CLASS), _) => true
case _ => false
}
@@ -267,22 +160,12 @@ abstract class TreeInfo {
/** Is name a left-associative operator? */
def isLeftAssoc(operator: Name) = operator.nonEmpty && (operator.last != ':')
- /** Is tree a `this` node which belongs to `enclClass`? */
- def isSelf(tree: Tree[_ >: Untyped], enclClass: Symbol)(implicit ctx: Context): Boolean = tree match {
- case This(_) => tree.symbol == enclClass
- case _ => false
- }
-
- /** a Match(Typed(_, tpt), _) must be translated into a switch if isSwitchAnnotation(tpt.tpe)
- def isSwitchAnnotation(tpe: Type) = tpe hasAnnotation defn.SwitchClass
- */
-
/** can this type be a type pattern? */
- def mayBeTypePat(tree: Tree[Untyped]): Boolean = tree match {
+ def mayBeTypePat(tree: untpd.Tree): Boolean = tree match {
case AndTypeTree(tpt1, tpt2) => mayBeTypePat(tpt1) || mayBeTypePat(tpt2)
case OrTypeTree(tpt1, tpt2) => mayBeTypePat(tpt1) || mayBeTypePat(tpt2)
- case RefinedTypeTree(tpt, refinements) => mayBeTypePat(tpt) || refinements.exists(_.isInstanceOf[Bind[_]])
- case AppliedTypeTree(tpt, args) => mayBeTypePat(tpt) || args.exists(_.isInstanceOf[Bind[_]])
+ case RefinedTypeTree(tpt, refinements) => mayBeTypePat(tpt) || refinements.exists(_.isInstanceOf[Bind])
+ case AppliedTypeTree(tpt, args) => mayBeTypePat(tpt) || args.exists(_.isInstanceOf[Bind])
case SelectFromTypeTree(tpt, _) => mayBeTypePat(tpt)
case Annotated(_, tpt) => mayBeTypePat(tpt)
case _ => false
@@ -290,13 +173,13 @@ abstract class TreeInfo {
/** Is this argument node of the form <expr> : _* ?
*/
- def isWildcardStarArg(tree: Tree[_ >: Untyped]): Boolean = tree match {
+ def isWildcardStarArg(tree: untpd.Tree): Boolean = tree match {
case Typed(_, Ident(tpnme.WILDCARD_STAR)) => true
case _ => false
}
/** If this tree has type parameters, those. Otherwise Nil.
- def typeParameters(tree: Tree[_]): List[TypeDef] = tree match {
+ def typeParameters(tree: Tree): List[TypeDef] = tree match {
case DefDef(_, _, tparams, _, _, _) => tparams
case ClassDef(_, _, tparams, _) => tparams
case TypeDef(_, _, tparams, _) => tparams
@@ -304,42 +187,42 @@ abstract class TreeInfo {
}*/
/** Does this argument list end with an argument of the form <expr> : _* ? */
- def isWildcardStarArgList(trees: List[Tree[_ >: Untyped]]) =
+ def isWildcardStarArgList(trees: List[Tree]) =
trees.nonEmpty && isWildcardStarArg(trees.last)
/** Is the argument a wildcard argument of the form `_` or `x @ _`?
*/
- def isWildcardArg(tree: Tree[_ >: Untyped]): Boolean = unbind(tree) match {
+ def isWildcardArg(tree: Tree): Boolean = unbind(tree) match {
case Ident(nme.WILDCARD) => true
case _ => false
}
/** Is the argument a wildcard star type of the form `_*`?
*/
- def isWildcardStarType(tree: Tree[_ >: Untyped]): Boolean = tree match {
+ def isWildcardStarType(tree: Tree): Boolean = tree match {
case Ident(tpnme.WILDCARD_STAR) => true
case _ => false
}
/** Is this pattern node a catch-all (wildcard or variable) pattern? */
- def isDefaultCase(cdef: CaseDef[_ >: Untyped]) = cdef match {
+ def isDefaultCase(cdef: CaseDef) = cdef match {
case CaseDef(pat, EmptyTree, _) => isWildcardArg(pat)
case _ => false
}
/** Is this pattern node a synthetic catch-all case, added during PartialFuction synthesis before we know
* whether the user provided cases are exhaustive. */
- def isSyntheticDefaultCase(cdef: CaseDef[_ >: Untyped]) = cdef match {
+ def isSyntheticDefaultCase(cdef: CaseDef) = cdef match {
case CaseDef(Bind(nme.DEFAULT_CASE, _), EmptyTree, _) => true
case _ => false
}
/** Does this CaseDef catch Throwable? */
- def catchesThrowable(cdef: CaseDef[_ >: Untyped])(implicit ctx: Context) =
+ def catchesThrowable(cdef: CaseDef)(implicit ctx: Context) =
catchesAllOf(cdef, defn.ThrowableClass.typeConstructor)
/** Does this CaseDef catch everything of a certain Type? */
- def catchesAllOf(cdef: CaseDef[_ >: Untyped], threshold: Type)(implicit ctx: Context) =
+ def catchesAllOf(cdef: CaseDef, threshold: Type)(implicit ctx: Context) =
isDefaultCase(cdef) ||
cdef.guard.isEmpty && {
unbind(cdef.pat) match {
@@ -348,8 +231,135 @@ abstract class TreeInfo {
}
}
+ /** Is this case guarded? */
+ def isGuardedCase(cdef: CaseDef) = cdef.guard ne EmptyTree
+
+ /** Is this pattern node a sequence-valued pattern? */
+ def isSequenceValued(tree: Tree): Boolean = unbind(tree) match {
+ case Alternative(ts) => ts exists isSequenceValued
+ case SeqLiteral(_) => true
+ case _ => false
+ }
+
+ /** The underlying pattern ignoring any bindings */
+ def unbind(x: Tree): Tree = x match {
+ case Bind(_, y) => unbind(y)
+ case y => y
+ }
+}
+
+trait TypedTreeInfo extends TreeInfo[Type] {self: Trees.Instance[Type] =>
+
+ /** Is tree a definition that has no side effects when
+ * evaluated as part of a block after the first time?
+ */
+ def isIdempotentDef(tree: tpd.Tree)(implicit ctx: Context): Boolean = tree match {
+ case EmptyTree
+ | TypeDef(_, _, _)
+ | Import(_, _)
+ | DefDef(_, _, _, _, _, _) =>
+ true
+ case ValDef(mods, _, _, rhs) =>
+ !(mods is Mutable) && isIdempotentExpr(rhs)
+ case _ =>
+ false
+ }
+
+ /** Is tree an expression which can be inlined without affecting program semantics?
+ *
+ * Note that this is not called "isExprPure" since purity (lack of side-effects)
+ * is not the litmus test. References to modules and lazy vals are side-effecting,
+ * both because side-effecting code may be executed and because the first reference
+ * takes a different code path than all to follow; but they are safe to inline
+ * because the expression result from evaluating them is always the same.
+ */
+ def isIdempotentExpr(tree: tpd.Tree)(implicit ctx: Context): Boolean = tree match {
+ case EmptyTree
+ | This(_)
+ | Super(_, _)
+ | Literal(_) =>
+ true
+ case Ident(_) =>
+ tree.symbol is Stable
+ case Select(qual, _) =>
+ tree.symbol.isStable && isIdempotentExpr(qual)
+ case TypeApply(fn, _) =>
+ isIdempotentExpr(fn)
+/*
+ * Not sure we'll need that. Comment out until we find out
+ case Apply(Select(free @ Ident(_), nme.apply), _) if free.symbol.name endsWith nme.REIFY_FREE_VALUE_SUFFIX =>
+ // see a detailed explanation of this trick in `GenSymbols.reifyFreeTerm`
+ free.symbol.hasStableFlag && isIdempotentExpr(free)
+*/
+ case Apply(fn, Nil) =>
+ // Note: After uncurry, field accesses are represented as Apply(getter, Nil),
+ // so an Apply can also be pure.
+ // However, before typing, applications of nullary functional values are also
+ // Apply(function, Nil) trees. To prevent them from being treated as pure,
+ // we check that the callee is a method.
+ // The callee might also be a Block, which has a null symbol, so we guard against that (SI-7185)
+ fn.symbol != null && (fn.symbol is (Method, butNot = Lazy)) && isIdempotentExpr(fn)
+ case Typed(expr, _) =>
+ isIdempotentExpr(expr)
+ case Block(stats, expr) =>
+ (stats forall isIdempotentDef) && isIdempotentExpr(expr)
+ case _ =>
+ false
+ }
+
+ /** Is symbol potentially a getter of a mutable variable?
+ */
+ def mayBeVarGetter(sym: Symbol)(implicit ctx: Context): Boolean = {
+ def maybeGetterType(tpe: Type): Boolean = tpe match {
+ case _: ExprType | _: ImplicitMethodType => true
+ case tpe: PolyType => maybeGetterType(tpe.resultType)
+ case _ => false
+ }
+ sym.owner.isClass && !sym.isStable && maybeGetterType(sym.info)
+ }
+
+ /** Is tree a reference to a mutable variable, or to a potential getter
+ * that has a setter in the same class?
+ */
+ def isVariableOrGetter(tree: tpd.Tree)(implicit ctx: Context) = {
+ def sym = tree.symbol
+ def isVar = sym is Mutable
+ def isGetter =
+ mayBeVarGetter(sym) && sym.owner.info.member(sym.name.asTermName.getterToSetter).exists
+
+ tree match {
+ case Ident(_) => isVar
+ case Select(_, _) => isVar || isGetter
+ case Apply(_, _) =>
+ methPart(tree) match {
+ case Select(qual, nme.apply) => qual.tpe.member(nme.update).exists
+ case _ => false
+ }
+ case _ => false
+ }
+ }
+
+ /** Is tree a `this` node which belongs to `enclClass`? */
+ def isSelf(tree: Tree, enclClass: Symbol)(implicit ctx: Context): Boolean = tree match {
+ case This(_) => tree.symbol == enclClass
+ case _ => false
+ }
+
+ /** Strips layers of `.asInstanceOf[T]` / `_.$asInstanceOf[T]()` from an expression */
+ def stripCast(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = {
+ def isCast(sel: tpd.Tree) = defn.asInstanceOfMethods contains sel.symbol
+ tree match {
+ case TypeApply(sel @ Select(inner, _), _) if isCast(sel) =>
+ stripCast(inner)
+ case Apply(TypeApply(sel @ Select(inner, _), _), Nil) if isCast(sel) =>
+ stripCast(inner)
+ case t =>
+ t
+ }
+ }
+
/** Is this pattern node a catch-all or type-test pattern? */
- def isCatchCase(cdef: CaseDef[Type])(implicit ctx: Context) = cdef match {
+ def isCatchCase(cdef: CaseDef)(implicit ctx: Context) = cdef match {
case CaseDef(Typed(Ident(nme.WILDCARD), tpt), EmptyTree, _) =>
isSimpleThrowable(tpt.tpe)
case CaseDef(Bind(_, Typed(Ident(nme.WILDCARD), tpt)), EmptyTree, _) =>
@@ -366,21 +376,10 @@ abstract class TreeInfo {
false
}
- /** Is this case guarded? */
- def isGuardedCase(cdef: CaseDef[_ >: Untyped]) = cdef.guard ne EmptyTree
-
- /** Is this pattern node a sequence-valued pattern? */
- def isSequenceValued(tree: Tree[_ >: Untyped]): Boolean = unbind(tree) match {
- case Alternative(ts) => ts exists isSequenceValued
- case SeqLiteral(_) => true
- case _ => false
- }
-
- /** The underlying pattern ignoring any bindings */
- def unbind[T >: Untyped](x: Tree[T]): Tree[T] = x match {
- case Bind(_, y) => unbind(y)
- case y => y
- }
+ /** a Match(Typed(_, tpt), _) must be translated into a switch if isSwitchAnnotation(tpt.tpe)
+ def isSwitchAnnotation(tpe: Type) = tpe hasAnnotation defn.SwitchClass
+ */
+}
/** Does list of trees start with a definition of
@@ -489,5 +488,6 @@ abstract class TreeInfo {
case tree: RefTree => true
case _ => false
})*/
-}
-object TreeInfo extends TreeInfo \ No newline at end of file
+
+
+
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index 2ae474d15..5836b0863 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -12,6 +12,7 @@ import collection.mutable.ListBuffer
import parsing.Tokens.Token
import printing.Printer
import util.Stats
+import annotation.unchecked.uncheckedVariance
object Trees {
@@ -96,7 +97,7 @@ object Trees {
* It should have as end the end of the opening keywords(s).
* If there is no opening keyword, point should equal end.
*/
- case class Modifiers[T >: Untyped] (
+ case class Modifiers[-T >: Untyped] (
flags: FlagSet = EmptyFlags,
privateWithin: TypeName = tpnme.EMPTY,
annotations: List[Tree[T]] = Nil) extends Positioned with Cloneable {
@@ -115,7 +116,7 @@ object Trees {
if (this.flags == flags) this
else copy(flags = flags)
- def withAnnotations(annots: List[Tree[T]]) =
+ def withAnnotations[U >: Untyped <: T](annots: List[Tree[U]]): Modifiers[U] =
if (annots.isEmpty) this
else copy(annotations = annotations ++ annots)
@@ -146,19 +147,21 @@ object Trees {
* - Type checking an untyped tree should remove all embedded `TypedSplice`
* nodes.
*/
- abstract class Tree[T >: Untyped] extends Positioned with Product with printing.Showable with Cloneable {
+ abstract class Tree[-T >: Untyped] extends Positioned with Product with printing.Showable with Cloneable {
if (Stats.enabled) ntrees += 1
/** The type constructor at the root of the tree */
type ThisTree[T >: Untyped] <: Tree[T]
- private var myTpe: T = _
+ private[this] var myTpe: T = _
+
+ private def setMyTpe(tpe: T) = myTpe = tpe
/** The type of the tree. In case of an untyped tree,
* an UnAssignedTypeException is thrown. (Overridden by empty trees)
*/
- def tpe: T = {
+ def tpe: T @uncheckedVariance = {
if (myTpe == null) throw new UnAssignedTypeException(this)
myTpe
}
@@ -182,7 +185,7 @@ object Trees {
(if (myTpe == null ||
(myTpe.asInstanceOf[AnyRef] eq tpe.asInstanceOf[AnyRef])) this
else clone).asInstanceOf[Tree[Type]]
- tree.myTpe = tpe
+ tree setMyTpe tpe
tree.asInstanceOf[ThisTree[Type]]
}
@@ -228,8 +231,8 @@ object Trees {
def toList: List[Tree[T]] = this :: Nil
/** if this tree is the empty tree, the alternative, else this tree */
- def orElse(that: => Tree[T]): Tree[T] =
- if (this eq EmptyTree) that else this
+ def orElse[U >: Untyped <: T](that: => Tree[U]): Tree[U] =
+ if (this eq genericEmptyTree) that else this
override def toText(printer: Printer) = printer.toText(this)
@@ -246,30 +249,30 @@ object Trees {
/** Instances of this class are trees for which isType is definitely true.
* Note that some trees have isType = true without being TypTrees (e.g. Ident, AnnotatedTree)
*/
- trait TypTree[T >: Untyped] extends Tree[T] {
- type ThisTree[T >: Untyped] <: TypTree[T]
+ trait TypTree[-T >: Untyped] extends Tree[T] {
+ type ThisTree[-T >: Untyped] <: TypTree[T]
override def isType = true
}
/** Instances of this class are trees for which isTerm is definitely true.
* Note that some trees have isTerm = true without being TermTrees (e.g. Ident, AnnotatedTree)
*/
- trait TermTree[T >: Untyped] extends Tree[T] {
- type ThisTree[T >: Untyped] <: TermTree[T]
+ trait TermTree[-T >: Untyped] extends Tree[T] {
+ type ThisTree[-T >: Untyped] <: TermTree[T]
override def isTerm = true
}
/** Instances of this class are trees which are not terms but are legal
* parts of patterns.
*/
- trait PatternTree[T >: Untyped] extends Tree[T] {
- type ThisTree[T >: Untyped] <: PatternTree[T]
+ trait PatternTree[-T >: Untyped] extends Tree[T] {
+ type ThisTree[-T >: Untyped] <: PatternTree[T]
override def isPattern = true
}
/** Tree's denotation can be derived from its type */
- abstract class DenotingTree[T >: Untyped] extends Tree[T] {
- type ThisTree[T >: Untyped] <: DenotingTree[T]
+ abstract class DenotingTree[-T >: Untyped] extends Tree[T] {
+ type ThisTree[-T >: Untyped] <: DenotingTree[T]
override def denot(implicit ctx: Context) = tpe match {
case tpe: NamedType => tpe.denot
case _ => NoDenotation
@@ -279,8 +282,8 @@ object Trees {
/** Tree's denot/isType/isTerm properties come from a subtree
* identified by `forwardTo`.
*/
- abstract class ProxyTree[T >: Untyped] extends Tree[T] {
- type ThisTree[T >: Untyped] <: ProxyTree[T]
+ abstract class ProxyTree[-T >: Untyped] extends Tree[T] {
+ type ThisTree[-T >: Untyped] <: ProxyTree[T]
def forwardTo: Tree[T]
override def denot(implicit ctx: Context): Denotation = forwardTo.denot
override def isTerm = forwardTo.isTerm
@@ -288,23 +291,23 @@ object Trees {
}
/** Tree has a name */
- abstract class NameTree[T >: Untyped] extends DenotingTree[T] {
- type ThisTree[T >: Untyped] <: NameTree[T]
+ abstract class NameTree[-T >: Untyped] extends DenotingTree[T] {
+ type ThisTree[-T >: Untyped] <: NameTree[T]
def name: Name
- def withName(name1: Name): NameTree[T]
+ def withName(name1: Name)(implicit ctx: Context): untpd.NameTree
}
/** Tree refers by name to a denotation */
- abstract class RefTree[T >: Untyped] extends NameTree[T] {
- type ThisTree[T >: Untyped] <: RefTree[T]
+ abstract class RefTree[-T >: Untyped] extends NameTree[T] {
+ type ThisTree[-T >: Untyped] <: RefTree[T]
def qualifier: Tree[T]
override def isType = name.isTypeName
override def isTerm = name.isTermName
}
/** Tree defines a new symbol */
- trait DefTree[T >: Untyped] extends DenotingTree[T] {
- type ThisTree[T >: Untyped] <: DefTree[T]
+ trait DefTree[-T >: Untyped] extends DenotingTree[T] {
+ type ThisTree[-T >: Untyped] <: DefTree[T]
override def isDef = true
}
@@ -313,14 +316,14 @@ object Trees {
* The envelope of a MemberDef contains the whole definition and his its point
* on the opening keyword (or the next token after that if keyword is missing).
*/
- trait MemberDef[T >: Untyped] extends NameTree[T] with DefTree[T] {
- type ThisTree[T >: Untyped] <: MemberDef[T]
+ trait MemberDef[-T >: Untyped] extends NameTree[T] with DefTree[T] {
+ type ThisTree[-T >: Untyped] <: MemberDef[T]
def mods: Modifiers[T]
override def envelope: Position = mods.pos union pos union initialPos
}
/** A ValDef or DefDef tree */
- trait ValOrDefDef[T >: Untyped] extends MemberDef[T] {
+ trait ValOrDefDef[-T >: Untyped] extends MemberDef[T] {
def tpt: Tree[T]
def rhs: Tree[T]
}
@@ -328,128 +331,126 @@ object Trees {
// ----------- Tree case classes ------------------------------------
/** name */
- case class Ident[T >: Untyped](name: Name)
+ case class Ident[-T >: Untyped] private[ast] (name: Name)
extends RefTree[T] {
- type ThisTree[T >: Untyped] = Ident[T]
- def withName(name: Name) = this.derivedIdent(name)
- def qualifier: Tree[T] = emptyTree[T]
+ type ThisTree[-T >: Untyped] = Ident[T]
+ def withName(name: Name)(implicit ctx: Context): untpd.Ident = untpd.cpy.Ident(this, name)
+ def qualifier: Tree[T] = genericEmptyTree
}
- class BackquotedIdent[T >: Untyped](name: Name)
+ class BackquotedIdent[-T >: Untyped] private[ast] (name: Name)
extends Ident[T](name)
/** qualifier.name */
- case class Select[T >: Untyped](qualifier: Tree[T], name: Name)
+ case class Select[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name)
extends RefTree[T] {
- type ThisTree[T >: Untyped] = Select[T]
- def withName(name: Name) = this.derivedSelect(qualifier, name)
+ type ThisTree[-T >: Untyped] = Select[T]
+ def withName(name: Name)(implicit ctx: Context): untpd.Select = untpd.cpy.Select(this, qualifier, name)
}
+ class SelectWithSig[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name, val sig: Signature)
+ extends Select[T](qualifier, name)
+
/** qual.this */
- case class This[T >: Untyped](qual: TypeName)
+ case class This[-T >: Untyped] private[ast] (qual: TypeName)
extends DenotingTree[T] with TermTree[T] {
- type ThisTree[T >: Untyped] = This[T]
+ type ThisTree[-T >: Untyped] = This[T]
}
/** C.super[mix], where qual = C.this */
- case class Super[T >: Untyped](qual: Tree[T], mix: TypeName)
+ case class Super[-T >: Untyped] private[ast] (qual: Tree[T], mix: TypeName)
extends ProxyTree[T] with TermTree[T] {
- type ThisTree[T >: Untyped] = Super[T]
+ type ThisTree[-T >: Untyped] = Super[T]
def forwardTo = qual
}
- abstract class GenericApply[T >: Untyped] extends ProxyTree[T] with TermTree[T] {
- type ThisTree[T >: Untyped] <: GenericApply[T]
+ abstract class GenericApply[-T >: Untyped] extends ProxyTree[T] with TermTree[T] {
+ type ThisTree[-T >: Untyped] <: GenericApply[T]
val fun: Tree[T]
val args: List[Tree[T]]
def forwardTo = fun
}
/** fun(args) */
- case class Apply[T >: Untyped](fun: Tree[T], args: List[Tree[T]])
+ case class Apply[-T >: Untyped] private[ast] (fun: Tree[T], args: List[Tree[T]])
extends GenericApply[T] {
- type ThisTree[T >: Untyped] = Apply[T]
+ type ThisTree[-T >: Untyped] = Apply[T]
}
/** fun[args] */
- case class TypeApply[T >: Untyped](fun: Tree[T], args: List[Tree[T]])
+ case class TypeApply[-T >: Untyped] private[ast] (fun: Tree[T], args: List[Tree[T]])
extends GenericApply[T] {
- type ThisTree[T >: Untyped] = TypeApply[T]
+ type ThisTree[-T >: Untyped] = TypeApply[T]
}
/** const */
- case class Literal[T >: Untyped](const: Constant)
+ case class Literal[-T >: Untyped] private[ast] (const: Constant)
extends TermTree[T] {
- type ThisTree[T >: Untyped] = Literal[T]
+ type ThisTree[-T >: Untyped] = Literal[T]
}
/** new tpt, but no constructor call */
- case class New[T >: Untyped](tpt: Tree[T])
+ case class New[-T >: Untyped] private[ast] (tpt: Tree[T])
extends TermTree[T] {
- type ThisTree[T >: Untyped] = New[T]
+ type ThisTree[-T >: Untyped] = New[T]
}
- /** new tpt(args1)...(args_n)
- */
- def New[T >: Untyped](tpt: Tree[T], argss: List[List[Tree[T]]]): Tree[T] =
- ((Select(New(tpt), nme.CONSTRUCTOR): Tree[T]) /: argss)(Apply(_, _))
-
/** (left, right) */
- case class Pair[T >: Untyped](left: Tree[T], right: Tree[T])
+ case class Pair[-T >: Untyped] private[ast] (left: Tree[T], right: Tree[T])
extends TermTree[T] {
- type ThisTree[T >: Untyped] = Pair[T]
+ type ThisTree[-T >: Untyped] = Pair[T]
override def isTerm = left.isTerm && right.isTerm
override def isType = left.isType && right.isType
override def isPattern = !isTerm && (left.isPattern || left.isTerm) && (right.isPattern || right.isTerm)
}
/** expr : tpt */
- case class Typed[T >: Untyped](expr: Tree[T], tpt: Tree[T])
+ 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]
+ type ThisTree[-T >: Untyped] = Typed[T]
def forwardTo = expr
}
/** name = arg, in a parameter list */
- case class NamedArg[T >: Untyped](name: Name, arg: Tree[T])
+ case class NamedArg[-T >: Untyped] private[ast] (name: Name, arg: Tree[T])
extends Tree[T] {
- type ThisTree[T >: Untyped] = NamedArg[T]
+ type ThisTree[-T >: Untyped] = NamedArg[T]
}
/** name = arg, outside a parameter list */
- case class Assign[T >: Untyped](lhs: Tree[T], rhs: Tree[T])
+ case class Assign[-T >: Untyped] private[ast] (lhs: Tree[T], rhs: Tree[T])
extends TermTree[T] {
- type ThisTree[T >: Untyped] = Assign[T]
+ type ThisTree[-T >: Untyped] = Assign[T]
}
/** { stats; expr } */
- case class Block[T >: Untyped](stats: List[Tree[T]], expr: Tree[T])
+ case class Block[-T >: Untyped] private[ast] (stats: List[Tree[T]], expr: Tree[T])
extends TermTree[T] {
- type ThisTree[T >: Untyped] = Block[T]
+ type ThisTree[-T >: Untyped] = Block[T]
}
/** if cond then thenp else elsep */
- case class If[T >: Untyped](cond: Tree[T], thenp: Tree[T], elsep: Tree[T])
+ 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]
+ type ThisTree[-T >: Untyped] = If[T]
}
/** A closure with an environment and a reference to a method */
- case class Closure[T >: Untyped](env: List[Tree[T]], meth: RefTree[T])
+ case class Closure[-T >: Untyped] private[ast] (env: List[Tree[T]], meth: RefTree[T])
extends TermTree[T] {
- type ThisTree[T >: Untyped] = Closure[T]
+ type ThisTree[-T >: Untyped] = Closure[T]
}
/** selector match { cases } */
- case class Match[T >: Untyped](selector: Tree[T], cases: List[CaseDef[T]])
+ case class Match[-T >: Untyped] private[ast] (selector: Tree[T], cases: List[CaseDef[T]])
extends TermTree[T] {
- type ThisTree[T >: Untyped] = Match[T]
+ type ThisTree[-T >: Untyped] = Match[T]
}
/** case pat if guard => body */
- case class CaseDef[T >: Untyped](pat: Tree[T], guard: Tree[T], body: Tree[T])
+ 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]
+ type ThisTree[-T >: Untyped] = CaseDef[T]
}
/** return expr
@@ -457,121 +458,114 @@ object Trees {
* After program transformations this is not necessarily the enclosing method, because
* closures can intervene.
*/
- case class Return[T >: Untyped](expr: Tree[T], from: Tree[T] = emptyTree[T]())
+ case class Return[-T >: Untyped] private[ast] (expr: Tree[T], from: Tree[T] = genericEmptyTree)
extends TermTree[T] {
- type ThisTree[T >: Untyped] = Return[T]
+ type ThisTree[-T >: Untyped] = Return[T]
}
/** try block catch handler finally finalizer */
- case class Try[T >: Untyped](expr: Tree[T], handler: Tree[T], finalizer: Tree[T])
+ case class Try[-T >: Untyped] private[ast] (expr: Tree[T], handler: Tree[T], finalizer: Tree[T])
extends TermTree[T] {
- type ThisTree[T >: Untyped] = Try[T]
+ type ThisTree[-T >: Untyped] = Try[T]
}
/** throw expr */
- case class Throw[T >: Untyped](expr: Tree[T])
+ case class Throw[-T >: Untyped] private[ast] (expr: Tree[T])
extends TermTree[T] {
- type ThisTree[T >: Untyped] = Throw[T]
+ type ThisTree[-T >: Untyped] = Throw[T]
}
/** Array[elemtpt](elems) */
- case class SeqLiteral[T >: Untyped](elems: List[Tree[T]])
+ case class SeqLiteral[-T >: Untyped] private[ast] (elems: List[Tree[T]])
extends Tree[T] {
- type ThisTree[T >: Untyped] = SeqLiteral[T]
+ type ThisTree[-T >: Untyped] = SeqLiteral[T]
}
/** A type tree that represents an existing or inferred type */
- case class TypeTree[T >: Untyped](original: Tree[T] = emptyTree[T])
+ case class TypeTree[-T >: Untyped] private[ast] (original: Tree[T])
extends DenotingTree[T] with TypTree[T] {
- type ThisTree[T >: Untyped] = TypeTree[T]
+ type ThisTree[-T >: Untyped] = TypeTree[T]
override def initialPos = NoPosition
override def isEmpty = !hasType && original.isEmpty
}
- object TypeTree {
- def apply(tpe: Type): TypeTree[Type] = TypeTree().withType(tpe)
- }
-
/** ref.type */
- case class SingletonTypeTree[T >: Untyped](ref: Tree[T])
+ case class SingletonTypeTree[-T >: Untyped] private[ast] (ref: Tree[T])
extends DenotingTree[T] with TypTree[T] {
- type ThisTree[T >: Untyped] = SingletonTypeTree[T]
+ type ThisTree[-T >: Untyped] = SingletonTypeTree[T]
}
/** qualifier # name */
- case class SelectFromTypeTree[T >: Untyped](qualifier: Tree[T], name: Name)
+ case class SelectFromTypeTree[-T >: Untyped] private[ast] (qualifier: Tree[T], name: Name)
extends RefTree[T] {
- type ThisTree[T >: Untyped] = SelectFromTypeTree[T]
- def withName(name: Name) = this.derivedSelectFromTypeTree(qualifier, name)
+ type ThisTree[-T >: Untyped] = SelectFromTypeTree[T]
+ def withName(name: Name)(implicit ctx: Context): untpd.SelectFromTypeTree = untpd.cpy.SelectFromTypeTree(this, qualifier, name)
}
/** left & right */
- case class AndTypeTree[T >: Untyped](left: Tree[T], right: Tree[T])
+ case class AndTypeTree[-T >: Untyped] private[ast] (left: Tree[T], right: Tree[T])
extends TypTree[T] {
- type ThisTree[T >: Untyped] = AndTypeTree[T]
+ type ThisTree[-T >: Untyped] = AndTypeTree[T]
}
/** left | right */
- case class OrTypeTree[T >: Untyped](left: Tree[T], right: Tree[T])
+ case class OrTypeTree[-T >: Untyped] private[ast] (left: Tree[T], right: Tree[T])
extends TypTree[T] {
- type ThisTree[T >: Untyped] = OrTypeTree[T]
+ type ThisTree[-T >: Untyped] = OrTypeTree[T]
}
/** tpt { refinements } */
- case class RefinedTypeTree[T >: Untyped](tpt: Tree[T], refinements: List[Tree[T]])
+ 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]
+ type ThisTree[-T >: Untyped] = RefinedTypeTree[T]
def forwardTo = tpt
}
/** tpt[args] */
- case class AppliedTypeTree[T >: Untyped](tpt: Tree[T], args: List[Tree[T]])
+ 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]
+ type ThisTree[-T >: Untyped] = AppliedTypeTree[T]
def forwardTo = tpt
}
- def AppliedTypeTree[T >: Untyped](tpt: Tree[T], arg: Tree[T]): AppliedTypeTree[T] =
- AppliedTypeTree(tpt, arg :: Nil)
-
/** >: lo <: hi */
- case class TypeBoundsTree[T >: Untyped](lo: Tree[T], hi: Tree[T])
+ case class TypeBoundsTree[-T >: Untyped] private[ast] (lo: Tree[T], hi: Tree[T])
extends Tree[T] {
- type ThisTree[T >: Untyped] = TypeBoundsTree[T]
+ type ThisTree[-T >: Untyped] = TypeBoundsTree[T]
}
/** name @ body */
- case class Bind[T >: Untyped](name: Name, body: Tree[T])
+ 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]
+ type ThisTree[-T >: Untyped] = Bind[T]
override def envelope: Position = pos union initialPos
- def withName(name: Name) = this.derivedBind(name, body)
+ def withName(name: Name)(implicit ctx: Context): untpd.Bind = untpd.cpy.Bind(this, name, body)
}
/** tree_1 | ... | tree_n */
- case class Alternative[T >: Untyped](trees: List[Tree[T]])
+ case class Alternative[-T >: Untyped] private[ast] (trees: List[Tree[T]])
extends PatternTree[T] {
- type ThisTree[T >: Untyped] = Alternative[T]
+ type ThisTree[-T >: Untyped] = Alternative[T]
}
/** fun(args) in a pattern, if fun is an extractor */
- case class UnApply[T >: Untyped](fun: Tree[T], args: List[Tree[T]])
+ case class UnApply[-T >: Untyped] private[ast] (fun: Tree[T], args: List[Tree[T]])
extends PatternTree[T] {
- type ThisTree[T >: Untyped] = UnApply[T]
+ type ThisTree[-T >: Untyped] = UnApply[T]
}
/** mods val name: tpt = rhs */
- case class ValDef[T >: Untyped](mods: Modifiers[T], name: TermName, tpt: Tree[T], rhs: Tree[T])
+ case class ValDef[-T >: Untyped] private[ast] (mods: Modifiers[T], name: TermName, tpt: Tree[T], rhs: Tree[T])
extends ValOrDefDef[T] {
- type ThisTree[T >: Untyped] = ValDef[T]
- def withName(name: Name) = this.derivedValDef(mods, name.toTermName, tpt, rhs)
+ type ThisTree[-T >: Untyped] = ValDef[T]
+ def withName(name: Name)(implicit ctx: Context): untpd.ValDef = untpd.cpy.ValDef(this, mods, name.toTermName, tpt, rhs)
}
/** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
- case class DefDef[T >: Untyped](mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])
+ case class DefDef[-T >: Untyped] private[ast] (mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])
extends ValOrDefDef[T] {
- type ThisTree[T >: Untyped] = DefDef[T]
- def withName(name: Name) = this.derivedDefDef(mods, name.toTermName, tparams, vparamss, tpt, rhs)
+ type ThisTree[-T >: Untyped] = DefDef[T]
+ def withName(name: Name)(implicit ctx: Context): untpd.DefDef = untpd.cpy.DefDef(this, mods, name.toTermName, tparams, vparamss, tpt, rhs)
}
/** mods class name template or
@@ -579,10 +573,10 @@ object Trees {
* mods type name = rhs or
* mods type name >: lo <: hi, if rhs = TypeBoundsTree(lo, hi) & (lo ne hi)
*/
- case class TypeDef[T >: Untyped](mods: Modifiers[T], name: TypeName, rhs: Tree[T])
+ case class TypeDef[-T >: Untyped] private[ast] (mods: Modifiers[T], name: TypeName, rhs: Tree[T])
extends MemberDef[T] {
- type ThisTree[T >: Untyped] = TypeDef[T]
- def withName(name: Name) = this.derivedTypeDef(mods, name.toTypeName, rhs, tparams)
+ type ThisTree[-T >: Untyped] = TypeDef[T]
+ def withName(name: Name)(implicit ctx: Context): untpd.TypeDef = untpd.cpy.TypeDef(this, mods, name.toTypeName, rhs, tparams)
/** Is this a definition of a class? */
def isClassDef = rhs.isInstanceOf[Template[_]]
@@ -595,97 +589,76 @@ object Trees {
}
/** extends parents { self => body } */
- case class Template[T >: Untyped](constr: DefDef[T], parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]])
+ case class Template[-T >: Untyped] private[ast] (constr: DefDef[T], parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]])
extends DefTree[T] {
- type ThisTree[T >: Untyped] = Template[T]
+ type ThisTree[-T >: Untyped] = Template[T]
}
/** import expr.selectors
* where a selector is either an untyped `Ident`, `name` or
* an untyped `Pair` `name => rename`
*/
- case class Import[T >: Untyped](expr: Tree[T], selectors: List[Tree[Untyped]])
+ case class Import[-T >: Untyped] private[ast] (expr: Tree[T], selectors: List[Tree[Untyped]])
extends DenotingTree[T] {
- type ThisTree[T >: Untyped] = Import[T]
+ type ThisTree[-T >: Untyped] = Import[T]
}
/** package pid { stats } */
- case class PackageDef[T >: Untyped](pid: RefTree[T], stats: List[Tree[T]])
+ case class PackageDef[-T >: Untyped] private[ast] (pid: RefTree[T], stats: List[Tree[T]])
extends ProxyTree[T] {
- type ThisTree[T >: Untyped] = PackageDef[T]
+ type ThisTree[-T >: Untyped] = PackageDef[T]
def forwardTo = pid
}
/** arg @annot */
- case class Annotated[T >: Untyped](annot: Tree[T], arg: Tree[T])
+ case class Annotated[-T >: Untyped] private[ast] (annot: Tree[T], arg: Tree[T])
extends ProxyTree[T] {
- type ThisTree[T >: Untyped] = Annotated[T]
+ type ThisTree[-T >: Untyped] = Annotated[T]
def forwardTo = arg
}
- trait WithoutType[T >: Untyped] extends Tree[T] {
- override def tpe = NoType.asInstanceOf[T]
+ trait WithoutType[-T >: Untyped] extends Tree[T] {
+ override def tpe: T @uncheckedVariance = NoType.asInstanceOf[T]
override def withType(tpe: Type) = this.asInstanceOf[ThisTree[Type]]
}
- val EmptyTree: Thicket[_] = Thicket(Nil)
-
- def emptyTree[T >: Untyped](): Thicket[T] = EmptyTree.asInstanceOf[Thicket[T]]
-
- class EmptyValDef[T >: Untyped] extends ValDef[T](
- Modifiers[T](Private), nme.WILDCARD, emptyTree[T], emptyTree[T]) with WithoutType[T] {
- override def isEmpty: Boolean = true
- }
-
- private object theEmptyValDef extends EmptyValDef[Untyped]
-
- object EmptyValDef {
- def apply[T >: Untyped](): EmptyValDef[T] = theEmptyValDef.asInstanceOf[EmptyValDef[T]]
- }
-
- /** A tree that can be shared without its position
- * polluting containing trees. Accumulators and tranformers
- * memoize results of shared subtrees
- */
- case class SharedTree[T >: Untyped](shared: Tree[T]) extends ProxyTree[T] {
- type ThisTree[T >: Untyped] = SharedTree[T]
- def forwardTo: Tree[T] = shared
- }
-
/** Temporary class that results from translation of ModuleDefs
* (and possibly other statements).
* The contained trees will be integrated when transformed with
* a `transform(List[Tree])` call.
*/
- case class Thicket[T >: Untyped](trees: List[Tree[T]])
+ case class Thicket[-T >: Untyped](trees: List[Tree[T]])
extends Tree[T] with WithoutType[T] {
- type ThisTree[T >: Untyped] = Thicket[T]
+ type ThisTree[-T >: Untyped] = Thicket[T]
override def isEmpty: Boolean = trees.isEmpty
override def toList: List[Tree[T]] = trees
override def toString = if (isEmpty) "EmptyTree" else "Thicket(" + trees.mkString(", ") + ")"
}
- object Thicket {
- def apply[T >: Untyped](): Thicket[T] = emptyTree()
- def apply[T >: Untyped](x1: Tree[T], x2: Tree[T]): Thicket[T] = Thicket(x1 :: x2 :: Nil)
- def apply[T >: Untyped](x1: Tree[T], x2: Tree[T], x3: Tree[T]): Thicket[T] = Thicket(x1 :: x2 :: x3 :: Nil)
- def make[T >: Untyped](xs: List[Tree[T]]): Tree[T] = flatten(xs) match {
- case x :: Nil => x
- case _ => apply(xs)
- }
+ class EmptyValDef[T >: Untyped] extends ValDef[T](
+ Modifiers[T](Private), nme.WILDCARD, genericEmptyTree[T], genericEmptyTree[T]) with WithoutType[T] {
+ override def isEmpty: Boolean = true
}
- // ----- Auxiliary creation methods ------------------
+ val theEmptyTree: Thicket[Type] = Thicket(Nil)
+ val theEmptyValDef = new EmptyValDef[Type]
+
+ def genericEmptyValDef[T >: Untyped]: ValDef[T] = theEmptyValDef.asInstanceOf[ValDef[T]]
+ def genericEmptyTree[T >: Untyped]: Thicket[T] = theEmptyTree.asInstanceOf[Thicket[T]]
- def Block[T >: Untyped](stat: Tree[T], expr: Tree[T]): Block[T] =
- Block(stat :: Nil, expr)
+ /** A tree that can be shared without its position
+ * polluting containing trees. Accumulators and tranformers
+ * memoize results of shared subtrees
+ */
+ case class SharedTree[-T >: Untyped](shared: Tree[T]) extends ProxyTree[T] {
+ type ThisTree[-T >: Untyped] = SharedTree[T]
+ def forwardTo: Tree[T] = shared
+ }
- def Apply[T >: Untyped](fn: Tree[T], arg: Tree[T]): Apply[T] =
- Apply(fn, arg :: Nil)
// ----- Generic Tree Instances, inherited from `tpt` and `untpd`.
- abstract class Instance[T >: Untyped] {
+ abstract class Instance[T >: Untyped] extends DotClass { inst =>
type Modifiers = Trees.Modifiers[T]
type Tree = Trees.Tree[T]
@@ -703,6 +676,7 @@ object Trees {
type Ident = Trees.Ident[T]
type BackquotedIdent = Trees.BackquotedIdent[T]
type Select = Trees.Select[T]
+ type SelectWithSig = Trees.SelectWithSig[T]
type This = Trees.This[T]
type Super = Trees.Super[T]
type Apply = Trees.Apply[T]
@@ -743,182 +717,521 @@ object Trees {
type SharedTree = Trees.SharedTree[T]
type Thicket = Trees.Thicket[T]
- protected implicit def pos(implicit ctx: Context): Position = ctx.position
+ def Ident(name: Name)(implicit ctx: Context): Ident = new Ident(name)
+ def BackquotedIdent(name: Name)(implicit ctx: Context): BackquotedIdent = new BackquotedIdent(name)
+ def Select(qualifier: Tree, name: Name)(implicit ctx: Context): Select = new Select(qualifier, name)
+ def SelectWithSig(qualifier: Tree, name: Name, sig: Signature)(implicit ctx: Context): Select = new SelectWithSig(qualifier, name, sig)
+ def This(qual: TypeName)(implicit ctx: Context): This = new This(qual)
+ def Super(qual: Tree, mix: TypeName)(implicit ctx: Context): Super = new Super(qual, mix)
+ def Apply(fun: Tree, args: List[Tree])(implicit ctx: Context): Apply = new Apply(fun, args)
+ def TypeApply(fun: Tree, args: List[Tree])(implicit ctx: Context): TypeApply = new TypeApply(fun, args)
+ def Literal(const: Constant)(implicit ctx: Context): Literal = new Literal(const)
+ def New(tpt: Tree)(implicit ctx: Context): New = new New(tpt)
+ def Pair(left: Tree, right: Tree)(implicit ctx: Context): Pair = new Pair(left, right)
+ def Typed(expr: Tree, tpt: Tree)(implicit ctx: Context): Typed = new Typed(expr, tpt)
+ def NamedArg(name: Name, arg: Tree)(implicit ctx: Context): NamedArg = new NamedArg(name, arg)
+ def Assign(lhs: Tree, rhs: Tree)(implicit ctx: Context): Assign = new Assign(lhs, rhs)
+ def Block(stats: List[Tree], expr: Tree)(implicit ctx: Context): Block = new Block(stats, expr)
+ def If(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If = new If(cond, thenp, elsep)
+ def Closure(env: List[Tree], meth: RefTree)(implicit ctx: Context): Closure = new Closure(env, meth)
+ def Match(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match = new Match(selector, cases)
+ def CaseDef(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef = new CaseDef(pat, guard, body)
+ def Return(expr: Tree, from: Tree)(implicit ctx: Context): Return = new Return(expr, from)
+ def Try(expr: Tree, handler: Tree, finalizer: Tree)(implicit ctx: Context): Try = new Try(expr, handler, finalizer)
+ def Throw(expr: Tree)(implicit ctx: Context): Throw = new Throw(expr)
+ def SeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral = new SeqLiteral(elems)
+ def TypeTree(original: Tree)(implicit ctx: Context): TypeTree = new TypeTree(original)
+ def TypeTree() = new TypeTree(EmptyTree)
+ def SingletonTypeTree(ref: Tree)(implicit ctx: Context): SingletonTypeTree = new SingletonTypeTree(ref)
+ def SelectFromTypeTree(qualifier: Tree, name: Name)(implicit ctx: Context): SelectFromTypeTree = new SelectFromTypeTree(qualifier, name)
+ def AndTypeTree(left: Tree, right: Tree)(implicit ctx: Context): AndTypeTree = new AndTypeTree(left, right)
+ def OrTypeTree(left: Tree, right: Tree)(implicit ctx: Context): OrTypeTree = new OrTypeTree(left, right)
+ def RefinedTypeTree(tpt: Tree, refinements: List[Tree])(implicit ctx: Context): RefinedTypeTree = new RefinedTypeTree(tpt, refinements)
+ def AppliedTypeTree(tpt: Tree, args: List[Tree])(implicit ctx: Context): AppliedTypeTree = new AppliedTypeTree(tpt, args)
+ def TypeBoundsTree(lo: Tree, hi: Tree)(implicit ctx: Context): TypeBoundsTree = new TypeBoundsTree(lo, hi)
+ def Bind(name: Name, body: Tree)(implicit ctx: Context): Bind = new Bind(name, body)
+ def Alternative(trees: List[Tree])(implicit ctx: Context): Alternative = new Alternative(trees)
+ def UnApply(fun: Tree, args: List[Tree])(implicit ctx: Context): UnApply = new UnApply(fun, args)
+ def ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree)(implicit ctx: Context): ValDef = new ValDef(mods, name, tpt, rhs)
+ def DefDef(mods: Modifiers, name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree)(implicit ctx: Context): DefDef = new DefDef(mods, name, tparams, vparamss, tpt, rhs)
+ def TypeDef(mods: Modifiers, name: TypeName, rhs: Tree)(implicit ctx: Context): TypeDef = new TypeDef(mods, name, rhs)
+ def Template(constr: DefDef, parents: List[Tree], self: ValDef, body: List[Tree])(implicit ctx: Context): Template = new Template(constr, parents, self, body)
+ def Import(expr: Tree, selectors: List[untpd.Tree])(implicit ctx: Context): Import = new Import(expr, selectors)
+ def PackageDef(pid: RefTree, stats: List[Tree])(implicit ctx: Context): PackageDef = new PackageDef(pid, stats)
+ def Annotated(annot: Tree, arg: Tree)(implicit ctx: Context): Annotated = new Annotated(annot, arg)
+ def SharedTree(shared: Tree)(implicit ctx: Context): SharedTree = new SharedTree(shared)
+ def Thicket(trees: List[Tree])(implicit ctx: Context): Thicket = new Thicket(trees)
+
+ val EmptyTree: Thicket = genericEmptyTree
+ val EmptyValDef: ValDef = genericEmptyValDef
+
+ def Modifiers(flags: FlagSet = EmptyFlags,
+ privateWithin: TypeName = tpnme.EMPTY,
+ annotations: List[Tree] = Nil) = new Modifiers(flags, privateWithin, annotations)
+
+ // ----- Auxiliary creation methods ------------------
+
+ // def TypeTree(tpe: Type): TypeTree = TypeTree().withType(tpe) todo: move to untpd/tpd
+
+ /** new tpt(args1)...(args_n)
+ */
+ def New(tpt: Tree, argss: List[List[Tree]])(implicit ctx: Context): Tree =
+ ((Select(New(tpt), nme.CONSTRUCTOR): Tree) /: argss)(Apply(_, _))
- def defPos(sym: Symbol)(implicit ctx: Context) = ctx.position union sym.coord.toPosition
- }
+ def Block(stat: Tree, expr: Tree)(implicit ctx: Context): Block =
+ Block(stat :: Nil, expr)
- // ----- Helper functions and classes ---------------------------------------
+ def Apply(fn: Tree, arg: Tree)(implicit ctx: Context): Apply =
+ Apply(fn, arg :: Nil)
- implicit class TreeCopier[T >: Untyped](val tree: Tree[T]) extends AnyVal {
- def derivedIdent(name: Name): Ident[T] = tree match {
- case tree: BackquotedIdent[_] =>
- if (name == tree.name) tree
- else new BackquotedIdent[T](name).withPos(tree.pos)
- case tree: Ident[_] if (name == tree.name) => tree
- case _ => Ident[T](name).withPos(tree.pos)
- }
- def derivedSelect(qualifier: Tree[T], name: Name): Select[T] = tree match {
- case tree: Select[_] if (qualifier eq tree.qualifier) && (name == tree.name) => tree
- case _ => Select(qualifier, name).withPos(tree.pos)
- }
- def derivedThis(qual: TypeName): This[T] = tree match {
- case tree: This[_] if (qual == tree.qual) => tree
- case _ => This[T](qual).withPos(tree.pos)
- }
- def derivedSuper(qual: Tree[T], mix: TypeName): Super[T] = tree match {
- case tree: Super[_] if (qual eq tree.qual) && (mix == tree.mix) => tree
- case _ => Super(qual, mix).withPos(tree.pos)
- }
- def derivedApply(fun: Tree[T], args: List[Tree[T]]): Apply[T] = tree match {
- case tree: Apply[_] if (fun eq tree.fun) && (args eq tree.args) => tree
- case _ => Apply(fun, args).withPos(tree.pos)
- }
- def derivedTypeApply(fun: Tree[T], args: List[Tree[T]]): TypeApply[T] = tree match {
- case tree: TypeApply[_] if (fun eq tree.fun) && (args eq tree.args) => tree
- case _ => TypeApply(fun, args).withPos(tree)
- }
- def derivedLiteral(const: Constant): Literal[T] = tree match {
- case tree: Literal[_] if (const == tree.const) => tree
- case _ => Literal[T](const).withPos(tree.pos)
- }
- def derivedNew(tpt: Tree[T]): New[T] = tree match {
- case tree: New[_] if (tpt eq tree.tpt) => tree
- case _ => New(tpt).withPos(tree.pos)
- }
- def derivedPair(left: Tree[T], right: Tree[T]): Pair[T] = tree match {
- case tree: Pair[_] if (left eq tree.left) && (right eq tree.right) => tree
- case _ => Pair(left, right).withPos(tree.pos)
- }
- def derivedTyped(expr: Tree[T], tpt: Tree[T]): Typed[T] = tree match {
- case tree: Typed[_] if (expr eq tree.expr) && (tpt eq tree.tpt) => tree
- case _ => Typed(expr, tpt).withPos(tree.pos)
- }
- def derivedNamedArg(name: Name, arg: Tree[T]): NamedArg[T] = tree match {
- case tree: NamedArg[_] if (name == tree.name) && (arg eq tree.arg) => tree
- case _ => NamedArg(name, arg).withPos(tree.pos)
- }
- def derivedAssign(lhs: Tree[T], rhs: Tree[T]): Assign[T] = tree match {
- case tree: Assign[_] if (lhs eq tree.lhs) && (rhs eq tree.rhs) => tree
- case _ => Assign(lhs, rhs).withPos(tree.pos)
- }
- def derivedBlock(stats: List[Tree[T]], expr: Tree[T]): Block[T] = tree match {
- case tree: Block[_] if (stats eq tree.stats) && (expr eq tree.expr) => tree
- case _ => Block(stats, expr).withPos(tree.pos)
- }
- def derivedIf(cond: Tree[T], thenp: Tree[T], elsep: Tree[T]): If[T] = tree match {
- case tree: If[_] if (cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep) => tree
- case _ => If(cond, thenp, elsep).withPos(tree.pos)
- }
- def derivedClosure(env: List[Tree[T]], meth: RefTree[T]): Closure[T] = tree match {
- case tree: Closure[_] if (env eq tree.env) && (meth eq tree.meth) => tree
- case _ => Closure(env, meth).withPos(tree.pos)
- }
- def derivedMatch(selector: Tree[T], cases: List[CaseDef[T]]): Match[T] = tree match {
- case tree: Match[_] if (selector eq tree.selector) && (cases eq tree.cases) => tree
- case _ => Match(selector, cases).withPos(tree.pos)
- }
- def derivedCaseDef(pat: Tree[T], guard: Tree[T], body: Tree[T]): CaseDef[T] = tree match {
- case tree: CaseDef[_] if (pat eq tree.pat) && (guard eq tree.guard) && (body eq tree.body) => tree
- case _ => CaseDef(pat, guard, body).withPos(tree.pos)
- }
- def derivedReturn(expr: Tree[T], from: Tree[T]): Return[T] = tree match {
- case tree: Return[_] if (expr eq tree.expr) && (from eq tree.from) => tree
- case _ => Return(expr, from).withPos(tree.pos)
- }
- def derivedTry(expr: Tree[T], handler: Tree[T], finalizer: Tree[T]): Try[T] = tree match {
- case tree: Try[_] if (expr eq tree.expr) && (handler eq tree.handler) && (finalizer eq tree.finalizer) => tree
- case _ => Try(expr, handler, finalizer).withPos(tree.pos)
- }
- def derivedThrow(expr: Tree[T]): Throw[T] = tree match {
- case tree: Throw[_] if (expr eq tree.expr) => tree
- case _ => Throw(expr).withPos(tree.pos)
- }
- def derivedSeqLiteral(elems: List[Tree[T]]): SeqLiteral[T] = tree match {
- case tree: SeqLiteral[_] if (elems eq tree.elems) => tree
- case _ => SeqLiteral(elems).withPos(tree.pos)
- }
- def derivedSingletonTypeTree(ref: Tree[T]): SingletonTypeTree[T] = tree match {
- case tree: SingletonTypeTree[_] if (ref eq tree.ref) => tree
- case _ => SingletonTypeTree(ref).withPos(tree.pos)
- }
- def derivedSelectFromTypeTree(qualifier: Tree[T], name: Name): SelectFromTypeTree[T] = tree match {
- case tree: SelectFromTypeTree[_] if (qualifier eq tree.qualifier) && (name == tree.name) => tree
- case _ => SelectFromTypeTree(qualifier, name).withPos(tree.pos)
- }
- def derivedAndTypeTree(left: Tree[T], right: Tree[T]): AndTypeTree[T] = tree match {
- case tree: AndTypeTree[_] if (left eq tree.left) && (right eq tree.right) => tree
- case _ => AndTypeTree(left, right).withPos(tree.pos)
- }
- def derivedOrTypeTree(left: Tree[T], right: Tree[T]): OrTypeTree[T] = tree match {
- case tree: OrTypeTree[_] if (left eq tree.left) && (right eq tree.right) => tree
- case _ => OrTypeTree(left, right).withPos(tree.pos)
- }
- def derivedRefinedTypeTree(tpt: Tree[T], refinements: List[Tree[T]]): RefinedTypeTree[T] = tree match {
- case tree: RefinedTypeTree[_] if (tpt eq tree.tpt) && (refinements eq tree.refinements) => tree
- case _ => RefinedTypeTree(tpt, refinements).withPos(tree.pos)
- }
- def derivedAppliedTypeTree(tpt: Tree[T], args: List[Tree[T]]): AppliedTypeTree[T] = tree match {
- case tree: AppliedTypeTree[_] if (tpt eq tree.tpt) && (args eq tree.args) => tree
- case _ => AppliedTypeTree(tpt, args).withPos(tree.pos)
- }
- def derivedTypeBoundsTree(lo: Tree[T], hi: Tree[T]): TypeBoundsTree[T] = tree match {
- case tree: TypeBoundsTree[_] if (lo eq tree.lo) && (hi eq tree.hi) => tree
- case _ => TypeBoundsTree(lo, hi).withPos(tree.pos)
- }
- def derivedBind(name: Name, body: Tree[T]): Bind[T] = tree match {
- case tree: Bind[_] if (name eq tree.name) && (body eq tree.body) => tree
- case _ => Bind(name, body).withPos(tree.pos)
- }
- def derivedAlternative(trees: List[Tree[T]]): Alternative[T] = tree match {
- case tree: Alternative[_] if (trees eq tree.trees) => tree
- case _ => Alternative(trees).withPos(tree.pos)
- }
- def derivedUnApply(fun: Tree[T], args: List[Tree[T]]): UnApply[T] = tree match {
- case tree: UnApply[_] if (fun eq tree.fun) && (args eq tree.args) => tree
- case _ => UnApply(fun, args).withPos(tree.pos)
- }
- def derivedValDef(mods: Modifiers[T], name: TermName, tpt: Tree[T], rhs: Tree[T]): ValDef[T] = tree match {
- case tree: ValDef[_] if (mods == tree.mods) && (name == tree.name) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
- case _ => ValDef(mods, name, tpt, rhs).withPos(tree.pos)
- }
- def derivedDefDef(mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T]): DefDef[T] = tree match {
- case tree: DefDef[_] if (mods == tree.mods) && (name == tree.name) && (tparams eq tree.tparams) && (vparamss eq tree.vparamss) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
- case _ => DefDef(mods, name, tparams, vparamss, tpt, rhs).withPos(tree.pos)
- }
- def derivedTypeDef(mods: Modifiers[T], name: TypeName, rhs: Tree[T], tparams: List[untpd.TypeDef] = Nil): TypeDef[T] = tree match {
- case tree: TypeDef[_] if (mods == tree.mods) && (name == tree.name) && (rhs eq tree.rhs) && (tparams eq tree.tparams) => tree
- case _ =>
- if (tparams.nonEmpty)
- (untpd.typeDef _).asInstanceOf[(Modifiers[T], TypeName, List[untpd.TypeDef], Tree[T]) => TypeDef[T]](
- mods, name, tparams, rhs).withPos(tree.pos)
- else TypeDef(mods, name, rhs).withPos(tree.pos)
+ def AppliedTypeTree(tpt: Tree, arg: Tree)(implicit ctx: Context): AppliedTypeTree =
+ AppliedTypeTree(tpt, arg :: Nil)
+
+ def Thicket()(implicit ctx: Context): Thicket = EmptyTree
+ def Thicket(x1: Tree, x2: Tree)(implicit ctx: Context): Thicket = Thicket(x1 :: x2 :: Nil)
+ def Thicket(x1: Tree, x2: Tree, x3: Tree)(implicit ctx: Context): Thicket = Thicket(x1 :: x2 :: x3 :: Nil)
+ def flatTree(xs: List[Tree])(implicit ctx: Context): Tree = flatten(xs) match {
+ case x :: Nil => x
+ case _ => Thicket(xs)
}
- def derivedTemplate(constr: DefDef[T], parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]]): Template[T] = tree match {
- case tree: Template[_] if (constr eq tree.constr) && (parents eq tree.parents) && (self eq tree.self) && (body eq tree.body) => tree
- case _ => Template(constr, parents, self, body).withPos(tree.pos)
+
+ def flatten(trees: List[Tree]): List[Tree] = {
+ var buf: ListBuffer[Tree] = null
+ def add(tree: Tree) = {
+ assert(!tree.isInstanceOf[Thicket])
+ buf += tree
+ }
+ var xs = trees
+ while (xs.nonEmpty) {
+ xs.head match {
+ case Thicket(elems) =>
+ if (buf == null) {
+ buf = new ListBuffer
+ var ys = trees
+ while (ys ne xs) {
+ buf += ys.head
+ ys = ys.tail
+ }
+ }
+ for (elem <- elems) {
+ assert(!elem.isInstanceOf[Thicket])
+ buf += elem
+ }
+ case tree =>
+ if (buf != null) buf += tree
+ }
+ xs = xs.tail
+ }
+ if (buf != null) buf.toList else trees
}
- def derivedImport(expr: Tree[T], selectors: List[Tree[Untyped]]): Import[T] = tree match {
- case tree: Import[_] if (expr eq tree.expr) && (selectors eq tree.selectors) => tree
- case _ => Import(expr, selectors).withPos(tree.pos)
+
+ // ----- Position handling -----------------------------------------
+
+ protected implicit def pos(implicit ctx: Context): Position = ctx.position
+
+ def defPos(sym: Symbol)(implicit ctx: Context) = ctx.position union sym.coord.toPosition
+
+ // ----- Helper classes for copying, transforming, accumulating -----------------
+
+ val cpy: TreeCopier
+
+ abstract class TreeCopier {
+
+ def postProcess(tree: Tree, copied: untpd.Tree): copied.ThisTree[T]
+
+ def finalize(tree: Tree, copied: untpd.Tree): copied.ThisTree[T] =
+ postProcess(tree, copied withPos tree.pos)
+
+ private def copyAttrs(t: untpd.Tree, tree: Tree): t.ThisTree[T] =
+ t.withType(tree.typeOpt).withPos(tree.pos).asInstanceOf[t.ThisTree[T]]
+
+ def Ident(tree: Tree, name: Name)(implicit ctx: Context): Ident = tree match {
+ case tree: BackquotedIdent =>
+ if (name == tree.name) tree
+ else finalize(tree, new BackquotedIdent(name))
+ case tree: Ident if (name == tree.name) => tree
+ case _ => finalize(tree, untpd.Ident(name))
+ }
+ def Select(tree: Tree, qualifier: Tree, name: Name)(implicit ctx: Context): Select = tree match {
+ case tree: SelectWithSig =>
+ if ((qualifier eq tree.qualifier) && (name == tree.name) ) tree
+ else finalize(tree, new SelectWithSig(qualifier, name, tree.sig))
+ case tree: Select if (qualifier eq tree.qualifier) && (name == tree.name) => tree
+ case _ => finalize(tree, untpd.Select(qualifier, name))
+ }
+ def This(tree: Tree, qual: TypeName)(implicit ctx: Context): This = tree match {
+ case tree: This if (qual == tree.qual) => tree
+ case _ => finalize(tree, untpd.This(qual))
+ }
+ def Super(tree: Tree, qual: Tree, mix: TypeName)(implicit ctx: Context): Super = tree match {
+ case tree: Super if (qual eq tree.qual) && (mix == tree.mix) => tree
+ case _ => finalize(tree, untpd.Super(qual, mix))
+ }
+ def Apply(tree: Tree, fun: Tree, args: List[Tree])(implicit ctx: Context): Apply = tree match {
+ case tree: Apply if (fun eq tree.fun) && (args eq tree.args) => tree
+ case _ => finalize(tree, untpd.Apply(fun, args))
+ }
+ def TypeApply(tree: Tree, fun: Tree, args: List[Tree])(implicit ctx: Context): TypeApply = tree match {
+ case tree: TypeApply if (fun eq tree.fun) && (args eq tree.args) => tree
+ case _ => inst.TypeApply(fun, args).withPos(tree)
+ }
+ def Literal(tree: Tree, const: Constant)(implicit ctx: Context): Literal = tree match {
+ case tree: Literal if (const == tree.const) => tree
+ case _ => finalize(tree, untpd.Literal(const))
+ }
+ def New(tree: Tree, tpt: Tree)(implicit ctx: Context): New = tree match {
+ case tree: New if (tpt eq tree.tpt) => tree
+ case _ => finalize(tree, untpd.New(tpt))
+ }
+ def Pair(tree: Tree, left: Tree, right: Tree)(implicit ctx: Context): Pair = tree match {
+ case tree: Pair if (left eq tree.left) && (right eq tree.right) => tree
+ case _ => finalize(tree, untpd.Pair(left, right))
+ }
+ def Typed(tree: Tree, expr: Tree, tpt: Tree)(implicit ctx: Context): Typed = tree match {
+ case tree: Typed if (expr eq tree.expr) && (tpt eq tree.tpt) => tree
+ case _ => finalize(tree, untpd.Typed(expr, tpt))
+ }
+ def NamedArg(tree: Tree, name: Name, arg: Tree)(implicit ctx: Context): NamedArg = tree match {
+ case tree: NamedArg if (name == tree.name) && (arg eq tree.arg) => tree
+ case _ => finalize(tree, untpd.NamedArg(name, arg))
+ }
+ def Assign(tree: Tree, lhs: Tree, rhs: Tree)(implicit ctx: Context): Assign = tree match {
+ case tree: Assign if (lhs eq tree.lhs) && (rhs eq tree.rhs) => tree
+ case _ => finalize(tree, untpd.Assign(lhs, rhs))
+ }
+ def Block(tree: Tree, stats: List[Tree], expr: Tree)(implicit ctx: Context): Block = tree match {
+ case tree: Block if (stats eq tree.stats) && (expr eq tree.expr) => tree
+ case _ => finalize(tree, untpd.Block(stats, expr))
+ }
+ def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If = tree match {
+ case tree: If if (cond eq tree.cond) && (thenp eq tree.thenp) && (elsep eq tree.elsep) => tree
+ case _ => finalize(tree, untpd.If(cond, thenp, elsep))
+ }
+ def Closure(tree: Tree, env: List[Tree], meth: RefTree)(implicit ctx: Context): Closure = tree match {
+ case tree: Closure if (env eq tree.env) && (meth eq tree.meth) => tree
+ case _ => finalize(tree, untpd.Closure(env, meth))
+ }
+ def Match(tree: Tree, selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match = tree match {
+ case tree: Match if (selector eq tree.selector) && (cases eq tree.cases) => tree
+ case _ => finalize(tree, untpd.Match(selector, cases))
+ }
+ def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef = tree match {
+ case tree: CaseDef if (pat eq tree.pat) && (guard eq tree.guard) && (body eq tree.body) => tree
+ case _ => finalize(tree, untpd.CaseDef(pat, guard, body))
+ }
+ def Return(tree: Tree, expr: Tree, from: Tree)(implicit ctx: Context): Return = tree match {
+ case tree: Return if (expr eq tree.expr) && (from eq tree.from) => tree
+ case _ => finalize(tree, untpd.Return(expr, from))
+ }
+ def Try(tree: Tree, expr: Tree, handler: Tree, finalizer: Tree)(implicit ctx: Context): Try = tree match {
+ case tree: Try if (expr eq tree.expr) && (handler eq tree.handler) && (finalizer eq tree.finalizer) => tree
+ case _ => finalize(tree, untpd.Try(expr, handler, finalizer))
+ }
+ def Throw(tree: Tree, expr: Tree)(implicit ctx: Context): Throw = tree match {
+ case tree: Throw if (expr eq tree.expr) => tree
+ case _ => finalize(tree, untpd.Throw(expr))
+ }
+ def SeqLiteral(tree: Tree, elems: List[Tree])(implicit ctx: Context): SeqLiteral = tree match {
+ case tree: SeqLiteral if (elems eq tree.elems) => tree
+ case _ => finalize(tree, untpd.SeqLiteral(elems))
+ }
+ def SingletonTypeTree(tree: Tree, ref: Tree)(implicit ctx: Context): SingletonTypeTree = tree match {
+ case tree: SingletonTypeTree if (ref eq tree.ref) => tree
+ case _ => finalize(tree, untpd.SingletonTypeTree(ref))
+ }
+ def SelectFromTypeTree(tree: Tree, qualifier: Tree, name: Name)(implicit ctx: Context): SelectFromTypeTree = tree match {
+ case tree: SelectFromTypeTree if (qualifier eq tree.qualifier) && (name == tree.name) => tree
+ case _ => finalize(tree, untpd.SelectFromTypeTree(qualifier, name))
+ }
+ def AndTypeTree(tree: Tree, left: Tree, right: Tree)(implicit ctx: Context): AndTypeTree = tree match {
+ case tree: AndTypeTree if (left eq tree.left) && (right eq tree.right) => tree
+ case _ => finalize(tree, untpd.AndTypeTree(left, right))
+ }
+ def OrTypeTree(tree: Tree, left: Tree, right: Tree)(implicit ctx: Context): OrTypeTree = tree match {
+ case tree: OrTypeTree if (left eq tree.left) && (right eq tree.right) => tree
+ case _ => finalize(tree, untpd.OrTypeTree(left, right))
+ }
+ def RefinedTypeTree(tree: Tree, tpt: Tree, refinements: List[Tree])(implicit ctx: Context): RefinedTypeTree = tree match {
+ case tree: RefinedTypeTree if (tpt eq tree.tpt) && (refinements eq tree.refinements) => tree
+ case _ => finalize(tree, untpd.RefinedTypeTree(tpt, refinements))
+ }
+ def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree])(implicit ctx: Context): AppliedTypeTree = tree match {
+ case tree: AppliedTypeTree if (tpt eq tree.tpt) && (args eq tree.args) => tree
+ case _ => finalize(tree, untpd.AppliedTypeTree(tpt, args))
+ }
+ def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree)(implicit ctx: Context): TypeBoundsTree = tree match {
+ case tree: TypeBoundsTree if (lo eq tree.lo) && (hi eq tree.hi) => tree
+ case _ => finalize(tree, untpd.TypeBoundsTree(lo, hi))
+ }
+ def Bind(tree: Tree, name: Name, body: Tree)(implicit ctx: Context): Bind = tree match {
+ case tree: Bind if (name eq tree.name) && (body eq tree.body) => tree
+ case _ => finalize(tree, untpd.Bind(name, body))
+ }
+ def Alternative(tree: Tree, trees: List[Tree])(implicit ctx: Context): Alternative = tree match {
+ case tree: Alternative if (trees eq tree.trees) => tree
+ case _ => finalize(tree, untpd.Alternative(trees))
+ }
+ def UnApply(tree: Tree, fun: Tree, args: List[Tree])(implicit ctx: Context): UnApply = tree match {
+ case tree: UnApply if (fun eq tree.fun) && (args eq tree.args) => tree
+ case _ => finalize(tree, untpd.UnApply(fun, args))
+ }
+ def ValDef(tree: Tree, mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree)(implicit ctx: Context): ValDef = tree match {
+ case tree: ValDef if (mods == tree.mods) && (name == tree.name) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
+ case _ => finalize(tree, untpd.ValDef(mods, name, tpt, rhs))
+ }
+ def DefDef(tree: Tree, mods: Modifiers, name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree)(implicit ctx: Context): DefDef = tree match {
+ case tree: DefDef if (mods == tree.mods) && (name == tree.name) && (tparams eq tree.tparams) && (vparamss eq tree.vparamss) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
+ case _ => finalize(tree, untpd.DefDef(mods, name, tparams, vparamss, tpt, rhs))
+ }
+ def TypeDef(tree: Tree, mods: Modifiers, name: TypeName, rhs: Tree, tparams: List[untpd.TypeDef] = Nil)(implicit ctx: Context): TypeDef = tree match {
+ case tree: TypeDef if (mods == tree.mods) && (name == tree.name) && (rhs eq tree.rhs) && (tparams eq tree.tparams) => tree
+ case _ => finalize(tree, untpd.TypeDef(mods, name, tparams, rhs))
+ }
+ def Template(tree: Tree, constr: DefDef, parents: List[Tree], self: ValDef, body: List[Tree])(implicit ctx: Context): Template = tree match {
+ case tree: Template if (constr eq tree.constr) && (parents eq tree.parents) && (self eq tree.self) && (body eq tree.body) => tree
+ case _ => finalize(tree, untpd.Template(constr, parents, self, body))
+ }
+ def Import(tree: Tree, expr: Tree, selectors: List[untpd.Tree])(implicit ctx: Context): Import = tree match {
+ case tree: Import if (expr eq tree.expr) && (selectors eq tree.selectors) => tree
+ case _ => finalize(tree, untpd.Import(expr, selectors))
+ }
+ def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree])(implicit ctx: Context): PackageDef = tree match {
+ case tree: PackageDef if (pid eq tree.pid) && (stats eq tree.stats) => tree
+ case _ => finalize(tree, untpd.PackageDef(pid, stats))
+ }
+ def Annotated(tree: Tree, annot: Tree, arg: Tree)(implicit ctx: Context): Annotated = tree match {
+ case tree: Annotated if (annot eq tree.annot) && (arg eq tree.arg) => tree
+ case _ => finalize(tree, untpd.Annotated(annot, arg))
+ }
+ def SharedTree(tree: Tree, shared: Tree)(implicit ctx: Context): SharedTree = tree match {
+ case tree: SharedTree if (shared eq tree.shared) => tree
+ case _ => finalize(tree, untpd.SharedTree(shared))
+ }
+ def Thicket(tree: Tree, trees: List[Tree])(implicit ctx: Context): Thicket = tree match {
+ case tree: Thicket if (trees eq tree.trees) => tree
+ case _ => finalize(tree, untpd.Thicket(trees))
+ }
}
- def derivedPackageDef(pid: RefTree[T], stats: List[Tree[T]]): PackageDef[T] = tree match {
- case tree: PackageDef[_] if (pid eq tree.pid) && (stats eq tree.stats) => tree
- case _ => PackageDef(pid, stats).withPos(tree.pos)
+
+ abstract class TreeTransformer(val cpy: TreeCopier = inst.cpy) {
+ var sharedMemo: Map[SharedTree, SharedTree] = Map()
+
+ def transform(tree: Tree)(implicit ctx: Context): Tree = tree match {
+ case Ident(name) =>
+ tree
+ case Select(qualifier, name) =>
+ cpy.Select(tree, transform(qualifier), name)
+ case This(qual) =>
+ tree
+ case Super(qual, mix) =>
+ cpy.Super(tree, transform(qual), mix)
+ case Apply(fun, args) =>
+ cpy.Apply(tree, transform(fun), transform(args))
+ case TypeApply(fun, args) =>
+ cpy.TypeApply(tree, transform(fun), transform(args))
+ case Literal(const) =>
+ tree
+ case New(tpt) =>
+ cpy.New(tree, transform(tpt))
+ case Pair(left, right) =>
+ cpy.Pair(tree, transform(left), transform(right))
+ case Typed(expr, tpt) =>
+ cpy.Typed(tree, transform(expr), transform(tpt))
+ case NamedArg(name, arg) =>
+ cpy.NamedArg(tree, name, transform(arg))
+ case Assign(lhs, rhs) =>
+ cpy.Assign(tree, transform(lhs), transform(rhs))
+ case Block(stats, expr) =>
+ cpy.Block(tree, transformStats(stats), transform(expr))
+ case If(cond, thenp, elsep) =>
+ cpy.If(tree, transform(cond), transform(thenp), transform(elsep))
+ case Closure(env, meth) =>
+ cpy.Closure(tree, transform(env), transformSub(meth))
+ case Match(selector, cases) =>
+ cpy.Match(tree, transform(selector), transformSub(cases))
+ case CaseDef(pat, guard, body) =>
+ cpy.CaseDef(tree, transform(pat), transform(guard), transform(body))
+ case Return(expr, from) =>
+ cpy.Return(tree, transform(expr), transformSub(from))
+ case Try(block, handler, finalizer) =>
+ cpy.Try(tree, transform(block), transform(handler), transform(finalizer))
+ case Throw(expr) =>
+ cpy.Throw(tree, transform(expr))
+ case SeqLiteral(elems) =>
+ cpy.SeqLiteral(tree, transform(elems))
+ case TypeTree(original) =>
+ tree
+ case SingletonTypeTree(ref) =>
+ cpy.SingletonTypeTree(tree, transform(ref))
+ case SelectFromTypeTree(qualifier, name) =>
+ cpy.SelectFromTypeTree(tree, transform(qualifier), name)
+ case AndTypeTree(left, right) =>
+ cpy.AndTypeTree(tree, transform(left), transform(right))
+ case OrTypeTree(left, right) =>
+ cpy.OrTypeTree(tree, transform(left), transform(right))
+ case RefinedTypeTree(tpt, refinements) =>
+ cpy.RefinedTypeTree(tree, transform(tpt), transformSub(refinements))
+ case AppliedTypeTree(tpt, args) =>
+ cpy.AppliedTypeTree(tree, transform(tpt), transform(args))
+ case TypeBoundsTree(lo, hi) =>
+ cpy.TypeBoundsTree(tree, transform(lo), transform(hi))
+ case Bind(name, body) =>
+ cpy.Bind(tree, name, transform(body))
+ case Alternative(trees) =>
+ cpy.Alternative(tree, transform(trees))
+ case UnApply(fun, args) =>
+ cpy.UnApply(tree, transform(fun), transform(args))
+ case ValDef(mods, name, tpt, rhs) =>
+ cpy.ValDef(tree, mods, name, transform(tpt), transform(rhs))
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ cpy.DefDef(tree, mods, name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt), transform(rhs))
+ case tree @ TypeDef(mods, name, rhs) =>
+ cpy.TypeDef(tree, mods, name, transform(rhs), tree.tparams)
+ case Template(constr, parents, self, body) =>
+ cpy.Template(tree, transformSub(constr), transform(parents), transformSub(self), transformStats(body))
+ case Import(expr, selectors) =>
+ cpy.Import(tree, transform(expr), selectors)
+ case PackageDef(pid, stats) =>
+ cpy.PackageDef(tree, transformSub(pid), transformStats(stats))
+ case Annotated(annot, arg) =>
+ cpy.Annotated(tree, transform(annot), transform(arg))
+ case Thicket(trees) =>
+ val trees1 = transform(trees)
+ if (trees1 eq trees) tree else Thicket(trees1)
+ case tree @ SharedTree(shared) =>
+ sharedMemo get tree match {
+ case Some(tree1) => tree1
+ case None =>
+ val tree1 = cpy.SharedTree(tree, transform(shared))
+ sharedMemo = sharedMemo.updated(tree, tree1)
+ tree1
+ }
+ }
+ def transformStats(trees: List[Tree])(implicit ctx: Context): List[Tree] =
+ transform(trees)
+ def transform(trees: List[Tree])(implicit ctx: Context): List[Tree] =
+ flatten(trees mapConserve (transform(_)))
+ def transformSub[Tr <: Tree](tree: Tr)(implicit ctx: Context): Tr =
+ transform(tree).asInstanceOf[Tr]
+ def transformSub[Tr <: Tree](trees: List[Tr])(implicit ctx: Context): List[Tr] =
+ transform(trees).asInstanceOf[List[Tr]]
}
- def derivedAnnotated(annot: Tree[T], arg: Tree[T]): Annotated[T] = tree match {
- case tree: Annotated[_] if (annot eq tree.annot) && (arg eq tree.arg) => tree
- case _ => Annotated(annot, arg).withPos(tree.pos)
+
+ abstract class TreeAccumulator[X] extends ((X, Tree) => X) {
+ var sharedMemo: Map[SharedTree, X] = Map()
+ def apply(x: X, tree: Tree): X
+ def apply(x: X, trees: Traversable[Tree]): X = (x /: trees)(apply)
+ def foldOver(x: X, tree: Tree): X = tree match {
+ case Ident(name) =>
+ x
+ case Select(qualifier, name) =>
+ this(x, qualifier)
+ case This(qual) =>
+ x
+ case Super(qual, mix) =>
+ this(x, qual)
+ case Apply(fun, args) =>
+ this(this(x, fun), args)
+ case TypeApply(fun, args) =>
+ this(this(x, fun), args)
+ case Literal(const) =>
+ x
+ case New(tpt) =>
+ this(x, tpt)
+ case Pair(left, right) =>
+ this(this(x, left), right)
+ case Typed(expr, tpt) =>
+ this(this(x, expr), tpt)
+ case NamedArg(name, arg) =>
+ this(x, arg)
+ case Assign(lhs, rhs) =>
+ this(this(x, lhs), rhs)
+ case Block(stats, expr) =>
+ this(this(x, stats), expr)
+ case If(cond, thenp, elsep) =>
+ this(this(this(x, cond), thenp), elsep)
+ case Closure(env, meth) =>
+ this(this(x, env), meth)
+ case Match(selector, cases) =>
+ this(this(x, selector), cases)
+ case CaseDef(pat, guard, body) =>
+ this(this(this(x, pat), guard), body)
+ case Return(expr, from) =>
+ this(this(x, expr), from)
+ case Try(block, handler, finalizer) =>
+ this(this(this(x, block), handler), finalizer)
+ case Throw(expr) =>
+ this(x, expr)
+ case SeqLiteral(elems) =>
+ this(x, elems)
+ case TypeTree(original) =>
+ x
+ case SingletonTypeTree(ref) =>
+ this(x, ref)
+ case SelectFromTypeTree(qualifier, name) =>
+ this(x, qualifier)
+ case AndTypeTree(left, right) =>
+ this(this(x, left), right)
+ case OrTypeTree(left, right) =>
+ this(this(x, left), right)
+ case RefinedTypeTree(tpt, refinements) =>
+ this(this(x, tpt), refinements)
+ case AppliedTypeTree(tpt, args) =>
+ this(this(x, tpt), args)
+ case TypeBoundsTree(lo, hi) =>
+ this(this(x, lo), hi)
+ case Bind(name, body) =>
+ this(x, body)
+ case Alternative(trees) =>
+ this(x, trees)
+ case UnApply(fun, args) =>
+ this(this(x, fun), args)
+ case ValDef(mods, name, tpt, rhs) =>
+ this(this(x, tpt), rhs)
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ this(this((this(x, tparams) /: vparamss)(apply), tpt), rhs)
+ case TypeDef(mods, name, rhs) =>
+ this(x, rhs)
+ case Template(constr, parents, self, body) =>
+ this(this(this(this(x, constr), parents), self), body)
+ case Import(expr, selectors) =>
+ this(x, expr)
+ case PackageDef(pid, stats) =>
+ this(this(x, pid), stats)
+ case Annotated(annot, arg) =>
+ this(this(x, annot), arg)
+ case Thicket(ts) =>
+ this(x, ts)
+ case tree @ SharedTree(shared) =>
+ sharedMemo get tree match {
+ case Some(x1) => x1
+ case None =>
+ val x1 = this(x, shared)
+ sharedMemo = sharedMemo.updated(tree, x1)
+ x1
+ }
+ }
}
- def derivedSharedTree(shared: Tree[T]): SharedTree[T] = tree match {
- case tree: SharedTree[_] if (shared eq tree.shared) => tree
- case _ => SharedTree(shared).withPos(tree.pos)
+
+ /** Fold `f` over all tree nodes, in depth-first, prefix order */
+ class DeepFolder[X](f: (X, Tree) => X) extends TreeAccumulator[X] {
+ def apply(x: X, tree: Tree): X = foldOver(f(x, tree), tree)
}
- def derivedThicket(trees: List[Tree[T]]): Thicket[T] = tree match {
- case tree: Thicket[_] if (trees eq tree.trees) => tree
- case _ => Thicket(trees).withPos(tree.pos)
+
+ /** Fold `f` over all tree nodes, in depth-first, prefix order, but don't visit
+ * subtrees where `f` returns a different result for the root, i.e. `f(x, root) ne x`.
+ */
+ class ShallowFolder[X](f: (X, Tree) => X) extends TreeAccumulator[X] {
+ def apply(x: X, tree: Tree): X = {
+ val x1 = f(x, tree)
+ if (x1.asInstanceOf[AnyRef] ne x1.asInstanceOf[AnyRef]) x1
+ else foldOver(x1, tree)
+ }
}
}
+}
+ // ----- Helper functions and classes ---------------------------------------
+/*
abstract class FullTreeTransformer[T >: Untyped, C] {
var sharedMemo: Map[SharedTree[T], SharedTree[T]] = Map()
@@ -1068,250 +1381,5 @@ object Trees {
def finishEmptyTree(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree
def finishSharedTree(tree: Tree[T], old: Tree[T], c: C, plugins: Plugins) = tree
}
+*/
- def flatten[T >: Untyped](trees: List[Tree[T]]): List[Tree[T]] = {
- var buf: ListBuffer[Tree[T]] = null
- def add(tree: Tree[T]) = {
- assert(!tree.isInstanceOf[Thicket[_]])
- buf += tree
- }
- var xs = trees
- while (xs.nonEmpty) {
- xs.head match {
- case Thicket(elems) =>
- if (buf == null) {
- buf = new ListBuffer
- var ys = trees
- while (ys ne xs) {
- buf += ys.head
- ys = ys.tail
- }
- }
- for (elem <- elems) {
- assert(!elem.isInstanceOf[Thicket[_]])
- buf += elem
- }
- case tree =>
- if (buf != null) buf += tree
- }
- xs = xs.tail
- }
- if (buf != null) buf.toList else trees
- }
-
- abstract class TreeTransformer[T >: Untyped] {
- var sharedMemo: Map[SharedTree[T], SharedTree[T]] = Map()
-
- def transform(tree: Tree[T]): Tree[T] = tree match {
- case Ident(name) =>
- tree
- case Select(qualifier, name) =>
- tree.derivedSelect(transform(qualifier), name)
- case This(qual) =>
- tree
- case Super(qual, mix) =>
- tree.derivedSuper(transform(qual), mix)
- case Apply(fun, args) =>
- tree.derivedApply(transform(fun), transform(args))
- case TypeApply(fun, args) =>
- tree.derivedTypeApply(transform(fun), transform(args))
- case Literal(const) =>
- tree
- case New(tpt) =>
- tree.derivedNew(transform(tpt))
- case Pair(left, right) =>
- tree.derivedPair(transform(left), transform(right))
- case Typed(expr, tpt) =>
- tree.derivedTyped(transform(expr), transform(tpt))
- case NamedArg(name, arg) =>
- tree.derivedNamedArg(name, transform(arg))
- case Assign(lhs, rhs) =>
- tree.derivedAssign(transform(lhs), transform(rhs))
- case Block(stats, expr) =>
- tree.derivedBlock(transformStats(stats), transform(expr))
- case If(cond, thenp, elsep) =>
- tree.derivedIf(transform(cond), transform(thenp), transform(elsep))
- case Closure(env, meth) =>
- tree.derivedClosure(transform(env), transformSub(meth))
- case Match(selector, cases) =>
- tree.derivedMatch(transform(selector), transformSub(cases))
- case CaseDef(pat, guard, body) =>
- tree.derivedCaseDef(transform(pat), transform(guard), transform(body))
- case Return(expr, from) =>
- tree.derivedReturn(transform(expr), transformSub(from))
- case Try(block, handler, finalizer) =>
- tree.derivedTry(transform(block), transform(handler), transform(finalizer))
- case Throw(expr) =>
- tree.derivedThrow(transform(expr))
- case SeqLiteral(elems) =>
- tree.derivedSeqLiteral(transform(elems))
- case TypeTree(original) =>
- tree
- case SingletonTypeTree(ref) =>
- tree.derivedSingletonTypeTree(transform(ref))
- case SelectFromTypeTree(qualifier, name) =>
- tree.derivedSelectFromTypeTree(transform(qualifier), name)
- case AndTypeTree(left, right) =>
- tree.derivedAndTypeTree(transform(left), transform(right))
- case OrTypeTree(left, right) =>
- tree.derivedOrTypeTree(transform(left), transform(right))
- case RefinedTypeTree(tpt, refinements) =>
- tree.derivedRefinedTypeTree(transform(tpt), transformSub(refinements))
- case AppliedTypeTree(tpt, args) =>
- tree.derivedAppliedTypeTree(transform(tpt), transform(args))
- case TypeBoundsTree(lo, hi) =>
- tree.derivedTypeBoundsTree(transform(lo), transform(hi))
- case Bind(name, body) =>
- tree.derivedBind(name, transform(body))
- case Alternative(trees) =>
- tree.derivedAlternative(transform(trees))
- case UnApply(fun, args) =>
- tree.derivedUnApply(transform(fun), transform(args))
- case ValDef(mods, name, tpt, rhs) =>
- tree.derivedValDef(mods, name, transform(tpt), transform(rhs))
- case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- tree.derivedDefDef(mods, name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt), transform(rhs))
- case tree @ TypeDef(mods, name, rhs) =>
- tree.derivedTypeDef(mods, name, transform(rhs), tree.tparams)
- case Template(constr, parents, self, body) =>
- tree.derivedTemplate(transformSub(constr), transform(parents), transformSub(self), transformStats(body))
- case Import(expr, selectors) =>
- tree.derivedImport(transform(expr), selectors)
- case PackageDef(pid, stats) =>
- tree.derivedPackageDef(transformSub(pid), transformStats(stats))
- case Annotated(annot, arg) =>
- tree.derivedAnnotated(transform(annot), transform(arg))
- case Thicket(trees) =>
- val trees1 = transform(trees)
- if (trees1 eq trees) tree else Thicket(trees1)
- case tree @ SharedTree(shared) =>
- sharedMemo get tree match {
- case Some(tree1) => tree1
- case None =>
- val tree1 = tree.derivedSharedTree(transform(shared))
- sharedMemo = sharedMemo.updated(tree, tree1)
- tree1
- }
- }
- def transformStats(trees: List[Tree[T]]): List[Tree[T]] =
- transform(trees)
- def transform(trees: List[Tree[T]]): List[Tree[T]] =
- flatten(trees mapConserve (transform(_)))
- def transformSub(tree: Tree[T]): tree.ThisTree[T] =
- transform(tree).asInstanceOf[tree.ThisTree[T]]
- def transformSub[TT <: Tree[T]](trees: List[TT]): List[TT] =
- transform(trees).asInstanceOf[List[TT]]
- }
-
- abstract class TreeAccumulator[X, T >: Untyped] extends ((X, Tree[T]) => X) {
- var sharedMemo: Map[SharedTree[T], X] = Map()
- def apply(x: X, tree: Tree[T]): X
- def apply(x: X, trees: Traversable[Tree[T]]): X = (x /: trees)(apply)
- def foldOver(x: X, tree: Tree[T]): X = tree match {
- case Ident(name) =>
- x
- case Select(qualifier, name) =>
- this(x, qualifier)
- case This(qual) =>
- x
- case Super(qual, mix) =>
- this(x, qual)
- case Apply(fun, args) =>
- this(this(x, fun), args)
- case TypeApply(fun, args) =>
- this(this(x, fun), args)
- case Literal(const) =>
- x
- case New(tpt) =>
- this(x, tpt)
- case Pair(left, right) =>
- this(this(x, left), right)
- case Typed(expr, tpt) =>
- this(this(x, expr), tpt)
- case NamedArg(name, arg) =>
- this(x, arg)
- case Assign(lhs, rhs) =>
- this(this(x, lhs), rhs)
- case Block(stats, expr) =>
- this(this(x, stats), expr)
- case If(cond, thenp, elsep) =>
- this(this(this(x, cond), thenp), elsep)
- case Closure(env, meth) =>
- this(this(x, env), meth)
- case Match(selector, cases) =>
- this(this(x, selector), cases)
- case CaseDef(pat, guard, body) =>
- this(this(this(x, pat), guard), body)
- case Return(expr, from) =>
- this(this(x, expr), from)
- case Try(block, handler, finalizer) =>
- this(this(this(x, block), handler), finalizer)
- case Throw(expr) =>
- this(x, expr)
- case SeqLiteral(elems) =>
- this(x, elems)
- case TypeTree(original) =>
- x
- case SingletonTypeTree(ref) =>
- this(x, ref)
- case SelectFromTypeTree(qualifier, name) =>
- this(x, qualifier)
- case AndTypeTree(left, right) =>
- this(this(x, left), right)
- case OrTypeTree(left, right) =>
- this(this(x, left), right)
- case RefinedTypeTree(tpt, refinements) =>
- this(this(x, tpt), refinements)
- case AppliedTypeTree(tpt, args) =>
- this(this(x, tpt), args)
- case TypeBoundsTree(lo, hi) =>
- this(this(x, lo), hi)
- case Bind(name, body) =>
- this(x, body)
- case Alternative(trees) =>
- this(x, trees)
- case UnApply(fun, args) =>
- this(this(x, fun), args)
- case ValDef(mods, name, tpt, rhs) =>
- this(this(x, tpt), rhs)
- case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- this(this((this(x, tparams) /: vparamss)(apply), tpt), rhs)
- case TypeDef(mods, name, rhs) =>
- this(x, rhs)
- case Template(constr, parents, self, body) =>
- this(this(this(this(x, constr), parents), self), body)
- case Import(expr, selectors) =>
- this(x, expr)
- case PackageDef(pid, stats) =>
- this(this(x, pid), stats)
- case Annotated(annot, arg) =>
- this(this(x, annot), arg)
- case Thicket(ts) =>
- this(x, ts)
- case tree @ SharedTree(shared) =>
- sharedMemo get tree match {
- case Some(x1) => x1
- case None =>
- val x1 = this(x, shared)
- sharedMemo = sharedMemo.updated(tree, x1)
- x1
- }
- }
- }
-
- /** Fold `f` over all tree nodes, in depth-first, prefix order */
- class DeepFolder[X, T >: Untyped](f: (X, Tree[T]) => X) extends TreeAccumulator[X, T] {
- def apply(x: X, tree: Tree[T]): X = foldOver(f(x, tree), tree)
- }
-
- /** Fold `f` over all tree nodes, in depth-first, prefix order, but don't visit
- * subtrees where `f` returns a different result for the root, i.e. `f(x, root) ne x`.
- */
- class ShallowFolder[X, T >: Untyped](f: (X, Tree[T]) => X) extends TreeAccumulator[X, T] {
- def apply(x: X, tree: Tree[T]): X = {
- val x1 = f(x, tree)
- if (x1.asInstanceOf[AnyRef] ne x1.asInstanceOf[AnyRef]) x1
- else foldOver(x1, tree)
- }
- }
-}
diff --git a/src/dotty/tools/dotc/ast/TypedTrees.scala b/src/dotty/tools/dotc/ast/TypedTrees.scala
index c3eadeb8d..e4488ac79 100644
--- a/src/dotty/tools/dotc/ast/TypedTrees.scala
+++ b/src/dotty/tools/dotc/ast/TypedTrees.scala
@@ -5,28 +5,37 @@ package ast
import core._
import util.Positions._, Types._, Contexts._, Constants._, Names._, Flags._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
-import CheckTrees._
+import CheckTrees._, Denotations._
-object tpd extends Trees.Instance[Type] {
+object tpd extends Trees.Instance[Type] with TypedTreeInfo {
- def Modifiers(sym: Symbol)(implicit ctx: Context): Modifiers = Trees.Modifiers[Type](
+ def Modifiers(sym: Symbol)(implicit ctx: Context): Modifiers = Modifiers(
sym.flags & ModifierFlags,
if (sym.privateWithin.exists) sym.privateWithin.asType.name else tpnme.EMPTY,
sym.annotations map (_.tree))
- def Modifiers(flags: FlagSet = EmptyFlags, privateWithin: TypeName = tpnme.EMPTY, annotations: List[Tree] = Nil) =
- Trees.Modifiers(flags, privateWithin, annotations)
+ override def Ident(name: Name)(implicit ctx: Context): Ident = unsupported("Ident")
+ override def BackquotedIdent(name: Name)(implicit ctx: Context): BackquotedIdent = unsupported("BackquotedIdent")
def Ident(tp: NamedType)(implicit ctx: Context): Ident =
- Trees.Ident(tp.name).withType(tp.underlyingIfRepeated).checked
+ super.Ident(tp.name).withType(tp.underlyingIfRepeated).checked
+
+ override def Select(qualifier: Tree, name: Name)(implicit ctx: Context): Select =
+ Select(qualifier, NamedType(qualifier.tpe, name))
def Select(pre: Tree, tp: NamedType)(implicit ctx: Context): Select =
- Trees.Select(pre, tp.name).withType(tp).checked
+ super.Select(pre, tp.name).withType(tp).checked
+
+ override def SelectWithSig(qualifier: Tree, name: Name, sig: Signature)(implicit ctx: Context) =
+ super.SelectWithSig(qualifier, name, sig)
+ .withType(TermRef.withSig(qualifier.tpe, name.asTermName, sig))
+
+ override def This(qual: TypeName)(implicit ctx: Context): This = unsupported("This")
def This(cls: ClassSymbol)(implicit ctx: Context): This =
- Trees.This(cls.name).withType(cls.thisType).checked
+ super.This(cls.name).withType(cls.thisType).checked
- def Super(qual: Tree, mix: TypeName)(implicit ctx: Context): Super = {
+ override def Super(qual: Tree, mix: TypeName)(implicit ctx: Context): Super = {
val owntype =
if (mix.isEmpty) ctx.glb(qual.tpe.parents)
else {
@@ -34,10 +43,10 @@ object tpd extends Trees.Instance[Type] {
check(mixParents.length == 1)
mixParents.head
}
- Trees.Super(qual, mix).withType(SuperType(qual.tpe, owntype)).checked
+ super.Super(qual, mix).withType(SuperType(qual.tpe, owntype)).checked
}
- def Apply(fn: Tree, args: List[Tree])(implicit ctx: Context): Apply = {
+ override def Apply(fn: Tree, args: List[Tree])(implicit ctx: Context): Apply = {
val owntype = fn.tpe.widen match {
case fntpe @ MethodType(pnames, ptypes) =>
check(sameLength(ptypes, args), s"${fn.show}: ${fntpe.show} to ${args.map(_.show).mkString(", ")}")
@@ -46,10 +55,10 @@ object tpd extends Trees.Instance[Type] {
check(false)
ErrorType
}
- Trees.Apply(fn, args).withType(owntype).checked
+ super.Apply(fn, args).withType(owntype).checked
}
- def TypeApply(fn: Tree, args: List[Tree])(implicit ctx: Context): TypeApply = {
+ override def TypeApply(fn: Tree, args: List[Tree])(implicit ctx: Context): TypeApply = {
val owntype = fn.tpe.widen match {
case fntpe @ PolyType(pnames) =>
check(sameLength(pnames, args))
@@ -58,30 +67,32 @@ object tpd extends Trees.Instance[Type] {
check(false)
ErrorType
}
- Trees.TypeApply(fn, args).withType(owntype).checked
+ super.TypeApply(fn, args).withType(owntype).checked
}
- def Literal(const: Constant)(implicit ctx: Context): Literal =
- Trees.Literal(const).withType(const.tpe).checked
+ override def Literal(const: Constant)(implicit ctx: Context): Literal =
+ super.Literal(const).withType(const.tpe).checked
+
+ override def New(tpt: Tree)(implicit ctx: Context): New =
+ super.New(tpt).withType(tpt.tpe).checked
- def New(tp: Type)(implicit ctx: Context): New =
- Trees.New(TypeTree(tp)).withType(tp).checked
+ def New(tp: Type)(implicit ctx: Context): New = New(TypeTree(tp))
- def Pair(left: Tree, right: Tree)(implicit ctx: Context): Pair =
- Trees.Pair(left, right).withType(defn.PairType.appliedTo(left.tpe, right.tpe)).checked
+ override def Pair(left: Tree, right: Tree)(implicit ctx: Context): Pair =
+ super.Pair(left, right).withType(defn.PairType.appliedTo(left.tpe, right.tpe)).checked
- def Typed(expr: Tree, tpt: Tree)(implicit ctx: Context): Typed =
- Trees.Typed(expr, tpt).withType(tpt.tpe).checked
+ override def Typed(expr: Tree, tpt: Tree)(implicit ctx: Context): Typed =
+ super.Typed(expr, tpt).withType(tpt.tpe).checked
- def NamedArg(name: TermName, arg: Tree)(implicit ctx: Context) =
- Trees.NamedArg(name, arg).withType(arg.tpe).checked
+ override def NamedArg(name: Name, arg: Tree)(implicit ctx: Context) =
+ super.NamedArg(name, arg).withType(arg.tpe).checked
- def Assign(lhs: Tree, rhs: Tree)(implicit ctx: Context): Assign =
- Trees.Assign(lhs, rhs).withType(defn.UnitType).checked
+ override def Assign(lhs: Tree, rhs: Tree)(implicit ctx: Context): Assign =
+ super.Assign(lhs, rhs).withType(defn.UnitType).checked
- def Block(stats: List[Tree], expr: Tree)(implicit ctx: Context): Block = {
+ override def Block(stats: List[Tree], expr: Tree)(implicit ctx: Context): Block = {
lazy val locals = localSyms(stats).toSet
- val blk = Trees.Block(stats, expr)
+ val blk = super.Block(stats, expr)
def widen(tp: Type): Type = tp match {
case tp: TermRef if locals contains tp.symbol =>
widen(tp.info)
@@ -93,8 +104,18 @@ object tpd extends Trees.Instance[Type] {
def maybeBlock(stats: List[Tree], expr: Tree)(implicit ctx: Context): Tree =
if (stats.isEmpty) expr else Block(stats, expr)
- def If(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If =
- Trees.If(cond, thenp, elsep).withType(thenp.tpe | elsep.tpe).checked
+ override def If(cond: Tree, thenp: Tree, elsep: Tree)(implicit ctx: Context): If =
+ super.If(cond, thenp, elsep).withType(thenp.tpe | elsep.tpe).checked
+
+ override def Closure(env: List[Tree], meth: RefTree)(implicit ctx: Context): Closure = {
+ val ownType = meth.tpe.widen match {
+ case mt @ MethodType(_, formals) =>
+ assert(!mt.isDependent)
+ val formals1 = formals mapConserve (_.underlyingIfRepeated)
+ defn.FunctionType(formals1, mt.resultType)
+ }
+ super.Closure(env, meth).withType(ownType).checked
+ }
/** A function def
*
@@ -107,90 +128,97 @@ object tpd extends Trees.Instance[Type] {
* where the closure's type is the target type of the expression (FunctionN, unless
* otherwise specified).
*/
- def Closure(meth: TermSymbol, bodyFn: List[Tree] => Tree, target: Type = NoType)(implicit ctx: Context): Block = {
- val funtpe =
- if (target.exists) target
- else meth.info match {
- case mt @ MethodType(_, formals) =>
- assert(!mt.isDependent)
- val formals1 = formals mapConserve (_.underlyingIfRepeated)
- defn.FunctionType(formals1, mt.resultType)
- }
+ def Closure(meth: TermSymbol, bodyFn: List[Tree] => Tree)(implicit ctx: Context): Block = {
val rhsFn: List[List[Tree]] => Tree = { case args :: Nil => bodyFn(args) }
Block(
DefDef(meth, rhsFn) :: Nil,
- Trees.Closure(Nil, Ident(TermRef.withSym(NoPrefix, meth)))).withType(funtpe).checked
+ Closure(Nil, Ident(TermRef.withSym(NoPrefix, meth))))
}
- def Match(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match =
- Trees.Match(selector, cases).withType(ctx.lub(cases map (_.body.tpe))).checked
+ override def Match(selector: Tree, cases: List[CaseDef])(implicit ctx: Context): Match =
+ super.Match(selector, cases).withType(ctx.lub(cases map (_.body.tpe))).checked
- def CaseDef(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef =
- Trees.CaseDef(pat, guard, body).withType(body.tpe).checked
+ override def CaseDef(pat: Tree, guard: Tree, body: Tree)(implicit ctx: Context): CaseDef =
+ super.CaseDef(pat, guard, body).withType(body.tpe).checked
- def Return(expr: Tree, from: Ident)(implicit ctx: Context): Return =
- Trees.Return(expr, from).withType(defn.NothingType).checked
+ override def Return(expr: Tree, from: Tree)(implicit ctx: Context): Return =
+ super.Return(expr, from).withType(defn.NothingType).checked
- def Try(block: Tree, handler: Tree, finalizer: Tree)(implicit ctx: Context): Try =
- Trees.Try(block, handler, finalizer).withType(block.tpe | handler.tpe).checked
+ override def Try(block: Tree, handler: Tree, finalizer: Tree)(implicit ctx: Context): Try =
+ super.Try(block, handler, finalizer).withType(block.tpe | handler.tpe).checked
- def Throw(expr: Tree)(implicit ctx: Context): Throw =
- Trees.Throw(expr).withType(defn.NothingType).checked
+ override def Throw(expr: Tree)(implicit ctx: Context): Throw =
+ super.Throw(expr).withType(defn.NothingType).checked
- def SeqLiteral(tpe: Type, elems: List[Tree])(implicit ctx: Context): SeqLiteral =
- Trees.SeqLiteral(elems).withType(tpe).checked
-
- def SeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral =
+ override def SeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral =
SeqLiteral(defn.SeqClass.typeConstructor.appliedTo(
ctx.lub(elems map (_.tpe)) :: Nil), elems)
+ // TODO: Split into Java/Scala eq literals
+ def SeqLiteral(tpe: Type, elems: List[Tree])(implicit ctx: Context): SeqLiteral =
+ super.SeqLiteral(elems).withType(tpe).checked
+
+ override def TypeTree(): TypeTree = unsupported("TypeTree()")
+
+ override def TypeTree(original: Tree)(implicit ctx: Context): TypeTree =
+ TypeTree(original.tpe, original)
+
def TypeTree(tp: Type, original: Tree = EmptyTree)(implicit ctx: Context): TypeTree =
- Trees.TypeTree(original).withType(tp).checked
+ super.TypeTree(original).withType(tp).checked
+
+ override def SingletonTypeTree(ref: Tree)(implicit ctx: Context): SingletonTypeTree =
+ super.SingletonTypeTree(ref).withType(ref.tpe).checked
- def SingletonTypeTree(ref: Tree)(implicit ctx: Context): SingletonTypeTree =
- Trees.SingletonTypeTree(ref).withType(ref.tpe).checked
+ override def SelectFromTypeTree(qualifier: Tree, name: Name)(implicit ctx: Context): SelectFromTypeTree =
+ SelectFromTypeTree(qualifier, NamedType(qualifier.tpe, name))
def SelectFromTypeTree(qualifier: Tree, tp: NamedType)(implicit ctx: Context): SelectFromTypeTree =
- Trees.SelectFromTypeTree(qualifier, tp.name).withType(tp).checked
+ super.SelectFromTypeTree(qualifier, tp.name).withType(tp).checked
- def AndTypeTree(left: Tree, right: Tree)(implicit ctx: Context): AndTypeTree =
- Trees.AndTypeTree(left, right).withType(left.tpe & right.tpe).checked
+ override def AndTypeTree(left: Tree, right: Tree)(implicit ctx: Context): AndTypeTree =
+ super.AndTypeTree(left, right).withType(left.tpe & right.tpe).checked
- def OrTypeTree(left: Tree, right: Tree)(implicit ctx: Context): OrTypeTree =
- Trees.OrTypeTree(left, right).withType(left.tpe | right.tpe).checked
+ override def OrTypeTree(left: Tree, right: Tree)(implicit ctx: Context): OrTypeTree =
+ super.OrTypeTree(left, right).withType(left.tpe | right.tpe).checked
- def RefinedTypeTree(tpt: Tree, refinements: List[DefTree])(implicit ctx: Context): RefinedTypeTree = {
+ override def RefinedTypeTree(tpt: Tree, refinements: List[Tree])(implicit ctx: Context): RefinedTypeTree = {
def refineType(tp: Type, refinement: Symbol): Type =
RefinedType(tp, refinement.name, refinement.info)
- Trees.RefinedTypeTree(tpt, refinements)
+ super.RefinedTypeTree(tpt, refinements)
.withType((tpt.tpe /: (refinements map (_.symbol)))(refineType)).checked
}
def refineType(tp: Type, refinement: Symbol)(implicit ctx: Context): Type =
RefinedType(tp, refinement.name, refinement.info)
- def AppliedTypeTree(tpt: Tree, args: List[Tree])(implicit ctx: Context): AppliedTypeTree =
- Trees.AppliedTypeTree(tpt, args).withType(tpt.tpe.appliedTo(args map (_.tpe))).checked
+ override def AppliedTypeTree(tpt: Tree, args: List[Tree])(implicit ctx: Context): AppliedTypeTree =
+ super.AppliedTypeTree(tpt, args).withType(tpt.tpe.appliedTo(args map (_.tpe))).checked
- def TypeBoundsTree(lo: Tree, hi: Tree)(implicit ctx: Context): TypeBoundsTree =
- Trees.TypeBoundsTree(lo, hi).withType(TypeBounds(lo.tpe, hi.tpe)).checked
+ override def TypeBoundsTree(lo: Tree, hi: Tree)(implicit ctx: Context): TypeBoundsTree =
+ super.TypeBoundsTree(lo, hi).withType(TypeBounds(lo.tpe, hi.tpe)).checked
+
+ override def Bind(name: Name, body: Tree)(implicit ctx: Context): Bind = unsupported("Bind")
def Bind(sym: TermSymbol, body: Tree)(implicit ctx: Context): Bind =
- Trees.Bind(sym.name, body).withType(refType(sym)).checked
+ super.Bind(sym.name, body).withType(refType(sym)).checked
- def Alternative(trees: List[Tree])(implicit ctx: Context): Alternative =
- Trees.Alternative(trees).withType(ctx.lub(trees map (_.tpe))).checked
+ override def Alternative(trees: List[Tree])(implicit ctx: Context): Alternative =
+ super.Alternative(trees).withType(ctx.lub(trees map (_.tpe))).checked
- def UnApply(fun: Tree, args: List[Tree])(implicit ctx: Context): UnApply = {
+ override def UnApply(fun: Tree, args: List[Tree])(implicit ctx: Context): UnApply = {
val owntype = fun.tpe.widen match {
case MethodType(_, paramType :: Nil) => paramType
case _ => check(false); ErrorType
}
- Trees.UnApply(fun, args).withType(owntype).checked
+ super.UnApply(fun, args).withType(owntype).checked
}
+ override def ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree)(implicit ctx: Context): ValDef = unsupported("ValDef")
+
def ValDef(sym: TermSymbol, rhs: Tree = EmptyTree)(implicit ctx: Context): ValDef =
- Trees.ValDef(Modifiers(sym), sym.name, TypeTree(sym.info), rhs).withType(refType(sym)).checked
+ super.ValDef(Modifiers(sym), sym.name, TypeTree(sym.info), rhs).withType(refType(sym)).checked
+
+ override def DefDef(mods: Modifiers, name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree)(implicit ctx: Context): DefDef = unsupported("DefDef")
def DefDef(sym: TermSymbol, rhs: Tree = EmptyTree)(implicit ctx: Context): DefDef =
DefDef(sym, Function.const(rhs) _)
@@ -215,14 +243,16 @@ object tpd extends Trees.Instance[Type] {
}
val (vparamss, rtp) = valueParamss(mtp)
val argss = vparamss map (_ map (vparam => Ident(vparam.symRef)))
- Trees.DefDef(
+ super.DefDef(
Modifiers(sym), sym.name, tparams map TypeDef,
vparamss map (_ map (ValDef(_))), TypeTree(rtp), rhsFn(argss))
.withType(refType(sym)).checked
}
+ override def TypeDef(mods: Modifiers, name: TypeName, rhs: Tree)(implicit ctx: Context): TypeDef = unsupported("TypeDef")
+
def TypeDef(sym: TypeSymbol)(implicit ctx: Context): TypeDef =
- Trees.TypeDef(Modifiers(sym), sym.name, TypeTree(sym.info))
+ super.TypeDef(Modifiers(sym), sym.name, TypeTree(sym.info))
.withType(refType(sym)).checked
def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], constr: DefDef, body: List[Tree])(implicit ctx: Context): TypeDef = {
@@ -241,32 +271,29 @@ object tpd extends Trees.Instance[Type] {
val findLocalDummy = new FindLocalDummyAccumulator(cls)
val localDummy = ((NoSymbol: Symbol) /: body)(findLocalDummy)
.orElse(ctx.newLocalDummy(cls))
- val impl = Trees.Template(constr, parents, selfType, rest)
+ val impl = super.Template(constr, parents, selfType, rest)
.withType(refType(localDummy)).checked
- Trees.TypeDef(Modifiers(cls), cls.name, impl) // !!! todo: revise
+ super.TypeDef(Modifiers(cls), cls.name, impl) // !!! todo: revise
.withType(refType(cls)).checked
}
- def Import(expr: Tree, selectors: List[untpd.Tree])(implicit ctx: Context): Import =
- Trees.Import(expr, selectors).withType(refType(ctx.newImportSymbol(SharedTree(expr)))).checked
+ override def Import(expr: Tree, selectors: List[untpd.Tree])(implicit ctx: Context): Import =
+ super.Import(expr, selectors).withType(refType(ctx.newImportSymbol(SharedTree(expr)))).checked
- def PackageDef(pid: RefTree, stats: List[Tree])(implicit ctx: Context): PackageDef =
- Trees.PackageDef(pid, stats).withType(refType(pid.symbol)).checked
+ override def PackageDef(pid: RefTree, stats: List[Tree])(implicit ctx: Context): PackageDef =
+ super.PackageDef(pid, stats).withType(refType(pid.symbol)).checked
- def Annotated(annot: Tree, arg: Tree)(implicit ctx: Context): Annotated =
- Trees.Annotated(annot, arg).withType(AnnotatedType(Annotation(annot), arg.tpe)).checked
+ override def Annotated(annot: Tree, arg: Tree)(implicit ctx: Context): Annotated =
+ super.Annotated(annot, arg).withType(AnnotatedType(Annotation(annot), arg.tpe)).checked
- val EmptyTree: Tree = emptyTree[Type]()
+ override def SharedTree(tree: Tree)(implicit ctx: Context): SharedTree =
+ Trees.SharedTree(tree).withType(tree.tpe)
- val EmptyValDef: ValDef = Trees.EmptyValDef().withType(NoType)
- def SharedTree(tree: Tree): SharedTree =
- Trees.SharedTree(tree).withType(tree.tpe)
+ // ------ Making references ------------------------------------------------------
def refType(sym: Symbol)(implicit ctx: Context): NamedType = NamedType.withSym(sym.owner.thisType, sym)
- // ------ Creating typed equivalents of trees that exist only in untyped form -------
-
/** A tree representing the same reference as the given type */
def ref(tp: NamedType)(implicit ctx: Context): NameTree =
if (tp.symbol.isStatic) Ident(tp)
@@ -278,6 +305,8 @@ object tpd extends Trees.Instance[Type] {
def ref(sym: Symbol)(implicit ctx: Context): tpd.NameTree =
ref(NamedType(sym.owner.thisType, sym.name).withDenot(sym))
+ // ------ Creating typed equivalents of trees that exist only in untyped form -------
+
/** new C(args) */
def New(tp: Type, args: List[Tree])(implicit ctx: Context): Apply =
Apply(
@@ -331,6 +360,13 @@ object tpd extends Trees.Instance[Type] {
} else foldOver(sym, tree)
}
+ override val cpy = new TypedTreeCopier
+
+ class TypedTreeCopier extends TreeCopier {
+ def postProcess(tree: Tree, copied: untpd.Tree): copied.ThisTree[Type] =
+ copied.withType(tree.tpe)
+ }
+
implicit class TreeOps[ThisTree <: tpd.Tree](val tree: ThisTree) extends AnyVal {
def isValue(implicit ctx: Context): Boolean =
@@ -366,7 +402,7 @@ object tpd extends Trees.Instance[Type] {
}
class TreeMapper(val typeMap: TypeMap = IdentityTypeMap, val ownerMap: Symbol => Symbol = identity)(implicit ctx: Context) extends TreeTransformer {
- override def transform(tree: tpd.Tree): tpd.Tree = super.transform {
+ override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = super.transform {
tree.withType(typeMap(tree.tpe)) match {
case bind: tpd.Bind =>
val sym = bind.symbol
@@ -380,7 +416,7 @@ object tpd extends Trees.Instance[Type] {
tree1
}
}
- override def transformStats(trees: List[tpd.Tree]) = {
+ override def transformStats(trees: List[tpd.Tree])(implicit ctx: Context) = {
val locals = localSyms(trees)
val mapped = ctx.mapSymbols(locals, typeMap, ownerMap)
if (locals eq mapped) super.transform(trees)
@@ -406,10 +442,5 @@ object tpd extends Trees.Instance[Type] {
def localSyms(stats: List[tpd.Tree])(implicit ctx: Context): List[Symbol] =
for (stat <- stats if (stat.isDef)) yield stat.symbol
-
- type TreeAccumulator[U] = Trees.TreeAccumulator[U, Type]
- type TreeCopier = Trees.TreeCopier[Type]
- type TreeTransformer = Trees.TreeTransformer[Type]
-
}
diff --git a/src/dotty/tools/dotc/ast/UntypedTrees.scala b/src/dotty/tools/dotc/ast/UntypedTrees.scala
index 9449392dd..f8a03385e 100644
--- a/src/dotty/tools/dotc/ast/UntypedTrees.scala
+++ b/src/dotty/tools/dotc/ast/UntypedTrees.scala
@@ -5,14 +5,11 @@ package ast
import core._
import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
-import TreeInfo._
import Decorators._
import language.higherKinds
import collection.mutable.ListBuffer
-object untpd extends Trees.Instance[Untyped] {
-
- val EmptyTree = emptyTree[Untyped]()
+object untpd extends Trees.Instance[Untyped] with TreeInfo[Untyped] {
// ----- Tree cases that exist in untyped form only ------------------
@@ -22,8 +19,8 @@ object untpd extends Trees.Instance[Untyped] {
/** mods object name impl */
case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
extends MemberDef {
- type ThisTree[T >: Untyped] <: Trees.NameTree[T] with Trees.MemberDef[T] with ModuleDef
- def withName(name: Name) = this.derivedModuleDef(mods, name.toTermName, impl)
+ type ThisTree[-T >: Untyped] <: Trees.NameTree[T] with Trees.MemberDef[T] with ModuleDef
+ def withName(name: Name)(implicit ctx: Context) = cpy.ModuleDef(this, mods, name.toTermName, impl)
}
case class SymbolLit(str: String) extends Tree
@@ -44,24 +41,32 @@ object untpd extends Trees.Instance[Untyped] {
case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends Tree
class PolyTypeDef(mods: Modifiers, name: TypeName, override val tparams: List[TypeDef], rhs: Tree)
- extends TypeDef(mods, name, rhs)
+ extends TypeDef(mods, name, rhs) {
+ override def withName(name: Name)(implicit ctx: Context) = cpy.PolyTypeDef(this, mods, name.toTypeName, tparams, rhs)
+ }
+
+// ------ Additional creation methods for untyped only -----------------
+
+ def Literal(const: Constant) = new Literal(const)
- def typeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree): TypeDef =
+ def TypeTree(tpe: Type)(implicit ctx: Context): TypedSplice = TypedSplice(TypeTree().withType(tpe))
+
+ def TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree)(implicit ctx: Context): TypeDef =
if (tparams.isEmpty) TypeDef(mods, name, rhs) else new PolyTypeDef(mods, name, tparams, rhs)
// ------ Untyped tree values and creation methods ---------------------
- val unitLiteral = Literal(Constant())
+ def unitLiteral(implicit ctx: Context) = Literal(Constant())
def ref(tp: NamedType)(implicit ctx: Context): Tree =
TypedSplice(tpd.ref(tp))
def scalaUnit(implicit ctx: Context) = ref(defn.UnitClass.typeConstructor)
- def makeConstructor(mods: Modifiers, tparams: List[TypeDef], vparamss: List[List[ValDef]], rhs: Tree = EmptyTree): DefDef =
+ def makeConstructor(mods: Modifiers, tparams: List[TypeDef], vparamss: List[List[ValDef]], rhs: Tree = EmptyTree)(implicit ctx: Context): DefDef =
DefDef(mods, nme.CONSTRUCTOR, tparams, vparamss, TypeTree(), rhs)
- def emptyConstructor: DefDef =
+ def emptyConstructor(implicit ctx: Context): DefDef =
makeConstructor(Modifiers(), Nil, Nil)
def makeSelfDef(name: TermName, tpt: Tree)(implicit ctx: Context) =
@@ -77,13 +82,13 @@ object untpd extends Trees.Instance[Untyped] {
case _ => Tuple(ts)
}
- def makeParameter(pname: TermName, tpe: Tree, mods: Modifiers = Modifiers()): ValDef =
- ValDef(mods | Param, pname, tpe, emptyTree())
+ def makeParameter(pname: TermName, tpe: Tree, mods: Modifiers = Modifiers())(implicit ctx: Context): ValDef =
+ ValDef(mods | Param, pname, tpe, EmptyTree)
def makeSyntheticParameter(n: Int = 1, tpt: Tree = EmptyTree)(implicit ctx: Context): ValDef =
ValDef(Modifiers(SyntheticTermParam), nme.syntheticParamName(n), TypeTree(), EmptyTree)
- def refOfDef(tree: NameTree) = Ident(tree.name)
+ def refOfDef(tree: NameTree)(implicit ctx: Context) = Ident(tree.name)
// ------- A decorator for producing a path to a location --------------
@@ -102,125 +107,130 @@ object untpd extends Trees.Instance[Untyped] {
// --------- Copier/Transformer/Accumulator classes for untyped trees -----
- implicit class UntypedTreeCopier(val tree: Tree) extends AnyVal {
- def derivedModuleDef(mods: Modifiers, name: TermName, impl: Template) = tree match {
+ override val cpy: UntypedTreeCopier = new UntypedTreeCopier
+
+ class UntypedTreeCopier extends TreeCopier {
+ def postProcess(tree: Tree, copied: Tree): copied.ThisTree[Untyped] =
+ copied.asInstanceOf[copied.ThisTree[Untyped]]
+
+ def ModuleDef(tree: Tree, mods: Modifiers, name: TermName, impl: Template) = tree match {
case tree: ModuleDef if (mods eq tree.mods) && (name eq tree.name) && (impl eq tree.impl) => tree
- case _ => ModuleDef(mods, name, impl).withPos(tree.pos)
+ case _ => untpd.ModuleDef(mods, name, impl).withPos(tree.pos)
}
- def derivedPolyTypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree) = tree match {
+ def PolyTypeDef(tree: Tree, mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree) = tree match {
case tree: PolyTypeDef if (mods eq tree.mods) && (name eq tree.name) && (tparams eq tree.tparams) && (rhs eq tree.rhs) => tree
case _ => new PolyTypeDef(mods, name, tparams, rhs).withPos(tree.pos)
}
- def derivedSymbolLit(str: String) = tree match {
+ def SymbolLit(tree: Tree, str: String) = tree match {
case tree: SymbolLit if (str == tree.str) => tree
- case _ => SymbolLit(str).withPos(tree.pos)
+ case _ => untpd.SymbolLit(str).withPos(tree.pos)
}
- def derivedInterpolatedString(id: TermName, strings: List[Literal], elems: List[Tree]) = tree match {
+ def InterpolatedString(tree: Tree, id: TermName, strings: List[Literal], elems: List[Tree]) = tree match {
case tree: InterpolatedString if (id eq tree.id) && (strings eq tree.strings) && (elems eq tree.elems) => tree
- case _ => InterpolatedString(id, strings, elems).withPos(tree.pos)
+ case _ => untpd.InterpolatedString(id, strings, elems).withPos(tree.pos)
}
- def derivedFunction(args: List[Tree], body: Tree) = tree match {
+ def Function(tree: Tree, args: List[Tree], body: Tree) = tree match {
case tree: Function if (args eq tree.args) && (body eq tree.body) => tree
- case _ => Function(args, body).withPos(tree.pos)
+ case _ => untpd.Function(args, body).withPos(tree.pos)
}
- def derivedInfixOp(left: Tree, op: Name, right: Tree) = tree match {
+ def InfixOp(tree: Tree, left: Tree, op: Name, right: Tree) = tree match {
case tree: InfixOp if (left eq tree.left) && (op eq tree.op) && (right eq tree.right) => tree
- case _ => InfixOp(left, op, right).withPos(tree.pos)
+ case _ => untpd.InfixOp(left, op, right).withPos(tree.pos)
}
- def derivedPostfixOp(od: Tree, op: Name) = tree match {
+ def PostfixOp(tree: Tree, od: Tree, op: Name) = tree match {
case tree: PostfixOp if (od eq tree.od) && (op eq tree.op) => tree
- case _ => PostfixOp(od, op).withPos(tree.pos)
+ case _ => untpd.PostfixOp(od, op).withPos(tree.pos)
}
- def derivedPrefixOp(op: Name, od: Tree) = tree match {
+ def PrefixOp(tree: Tree, op: Name, od: Tree) = tree match {
case tree: PrefixOp if (op eq tree.op) && (od eq tree.od) => tree
- case _ => PrefixOp(op, od).withPos(tree.pos)
+ case _ => untpd.PrefixOp(op, od).withPos(tree.pos)
}
- def derivedParens(t: Tree) = tree match {
+ def Parens(tree: Tree, t: Tree) = tree match {
case tree: Parens if (t eq tree.t) => tree
- case _ => Parens(t).withPos(tree.pos)
+ case _ => untpd.Parens(t).withPos(tree.pos)
}
- def derivedTuple(trees: List[Tree]) = tree match {
+ def Tuple(tree: Tree, trees: List[Tree]) = tree match {
case tree: Tuple if (trees eq tree.trees) => tree
- case _ => Tuple(trees).withPos(tree.pos)
+ case _ => untpd.Tuple(trees).withPos(tree.pos)
}
- def derivedWhileDo(cond: Tree, body: Tree) = tree match {
+ def WhileDo(tree: Tree, cond: Tree, body: Tree) = tree match {
case tree: WhileDo if (cond eq tree.cond) && (body eq tree.body) => tree
- case _ => WhileDo(cond, body).withPos(tree.pos)
+ case _ => untpd.WhileDo(cond, body).withPos(tree.pos)
}
- def derivedDoWhile(body: Tree, cond: Tree) = tree match {
+ def DoWhile(tree: Tree, body: Tree, cond: Tree) = tree match {
case tree: DoWhile if (body eq tree.body) && (cond eq tree.cond) => tree
- case _ => DoWhile(body, cond).withPos(tree.pos)
+ case _ => untpd.DoWhile(body, cond).withPos(tree.pos)
}
- def derivedForYield(enums: List[Tree], expr: Tree) = tree match {
+ def ForYield(tree: Tree, enums: List[Tree], expr: Tree) = tree match {
case tree: ForYield if (enums eq tree.enums) && (expr eq tree.expr) => tree
- case _ => ForYield(enums, expr).withPos(tree.pos)
+ case _ => untpd.ForYield(enums, expr).withPos(tree.pos)
}
- def derivedForDo(enums: List[Tree], body: Tree) = tree match {
+ def ForDo(tree: Tree, enums: List[Tree], body: Tree) = tree match {
case tree: ForDo if (enums eq tree.enums) && (body eq tree.body) => tree
- case _ => ForDo(enums, body).withPos(tree.pos)
+ case _ => untpd.ForDo(enums, body).withPos(tree.pos)
}
- def derivedGenFrom(pat: Tree, expr: Tree) = tree match {
+ def GenFrom(tree: Tree, pat: Tree, expr: Tree) = tree match {
case tree: GenFrom if (pat eq tree.pat) && (expr eq tree.expr) => tree
- case _ => GenFrom(pat, expr).withPos(tree.pos)
+ case _ => untpd.GenFrom(pat, expr).withPos(tree.pos)
}
- def derivedGenAlias(pat: Tree, expr: Tree) = tree match {
+ def GenAlias(tree: Tree, pat: Tree, expr: Tree) = tree match {
case tree: GenAlias if (pat eq tree.pat) && (expr eq tree.expr) => tree
- case _ => GenAlias(pat, expr).withPos(tree.pos)
+ case _ => untpd.GenAlias(pat, expr).withPos(tree.pos)
}
- def derivedContextBounds(bounds: TypeBoundsTree, cxBounds: List[Tree]) = tree match {
+ def ContextBounds(tree: Tree, bounds: TypeBoundsTree, cxBounds: List[Tree]) = tree match {
case tree: ContextBounds if (bounds eq tree.bounds) && (cxBounds eq tree.cxBounds) => tree
- case _ => ContextBounds(bounds, cxBounds).withPos(tree.pos)
+ case _ => untpd.ContextBounds(bounds, cxBounds).withPos(tree.pos)
}
- def derivedPatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) = tree match {
+ def PatDef(tree: Tree, mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) = tree match {
case tree: PatDef if (mods eq tree.mods) && (pats eq tree.pats) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
- case _ => PatDef(mods, pats, tpt, rhs).withPos(tree.pos)
+ case _ => untpd.PatDef(mods, pats, tpt, rhs).withPos(tree.pos)
}
}
- abstract class TreeTransformer extends Trees.TreeTransformer[Untyped] {
- override def transform(tree: Tree): Tree = tree match {
+ abstract class UntypedTreeTransformer(cpy: UntypedTreeCopier = untpd.cpy) extends TreeTransformer(cpy) {
+ override def transform(tree: Tree)(implicit ctx: Context): Tree = tree match {
case ModuleDef(mods, name, impl) =>
- tree.derivedModuleDef(mods, name, transformSub(impl))
+ cpy.ModuleDef(tree, mods, name, transformSub(impl))
case SymbolLit(str) =>
- tree.derivedSymbolLit(str)
+ cpy.SymbolLit(tree, str)
case InterpolatedString(id, strings, elems) =>
- tree.derivedInterpolatedString(id, transformSub(strings), transform(elems))
+ cpy.InterpolatedString(tree, id, transformSub(strings), transform(elems))
case Function(args, body) =>
- tree.derivedFunction(transform(args), transform(body))
+ cpy.Function(tree, transform(args), transform(body))
case InfixOp(left, op, right) =>
- tree.derivedInfixOp(transform(left), op, transform(right))
+ cpy.InfixOp(tree, transform(left), op, transform(right))
case PostfixOp(od, op) =>
- tree.derivedPostfixOp(transform(od), op)
+ cpy.PostfixOp(tree, transform(od), op)
case PrefixOp(op, od) =>
- tree.derivedPrefixOp(op, transform(od))
+ cpy.PrefixOp(tree, op, transform(od))
case Parens(t) =>
- tree.derivedParens(transform(t))
+ cpy.Parens(tree, transform(t))
case Tuple(trees) =>
- tree.derivedTuple(transform(trees))
+ cpy.Tuple(tree, transform(trees))
case WhileDo(cond, body) =>
- tree.derivedWhileDo(transform(cond), transform(body))
+ cpy.WhileDo(tree, transform(cond), transform(body))
case DoWhile(body, cond) =>
- tree.derivedDoWhile(transform(body), transform(cond))
+ cpy.DoWhile(tree, transform(body), transform(cond))
case ForYield(enums, expr) =>
- tree.derivedForYield(transform(enums), transform(expr))
+ cpy.ForYield(tree, transform(enums), transform(expr))
case ForDo(enums, body) =>
- tree.derivedForDo(transform(enums), transform(body))
+ cpy.ForDo(tree, transform(enums), transform(body))
case GenFrom(pat, expr) =>
- tree.derivedGenFrom(transform(pat), transform(expr))
+ cpy.GenFrom(tree, transform(pat), transform(expr))
case GenAlias(pat, expr) =>
- tree.derivedGenAlias(transform(pat), transform(expr))
+ cpy.GenAlias(tree, transform(pat), transform(expr))
case ContextBounds(bounds, cxBounds) =>
- tree.derivedContextBounds(transformSub(bounds), transform(cxBounds))
+ cpy.ContextBounds(tree, transformSub(bounds), transform(cxBounds))
case PatDef(mods, pats, tpt, rhs) =>
- tree.derivedPatDef(mods, transform(pats), transform(tpt), transform(rhs))
+ cpy.PatDef(tree, mods, transform(pats), transform(tpt), transform(rhs))
case tree: PolyTypeDef =>
- tree.derivedPolyTypeDef(tree.mods, tree.name, transformSub(tree.tparams), transform(tree.rhs))
+ cpy.PolyTypeDef(tree, tree.mods, tree.name, transformSub(tree.tparams), transform(tree.rhs))
case _ =>
super.transform(tree)
}
}
- abstract class TreeAccumulator[X] extends Trees.TreeAccumulator[X, Untyped] {
+ abstract class UntypedTreeAccumulator[X] extends TreeAccumulator[X] {
override def foldOver(x: X, tree: Tree): X = tree match {
case ModuleDef(mods, name, impl) =>
this(x, impl)
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index 133db4268..a488e0e18 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -10,7 +10,7 @@ import java.lang.Double.longBitsToDouble
import Contexts._, Symbols._, Types._, Scopes._, SymDenotations._, Names._, NameOps._
import StdNames._, Denotations._, NameOps._, Flags._, Constants._, Annotations._
import util.Positions._
-import ast.Trees, ast.tpd._
+import ast.Trees, ast.tpd._, ast.untpd
import printing.Texts._
import printing.Printer
import io.AbstractFile
@@ -938,9 +938,9 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
val selectors = until(end, () => {
val fromName = readNameRef()
val toName = readNameRef()
- val from = Trees.Ident(fromName)
- val to = Trees.Ident(toName)
- if (toName.isEmpty) from else Trees.Pair(from, Trees.Ident(toName))
+ val from = untpd.Ident(fromName)
+ val to = untpd.Ident(toName)
+ if (toName.isEmpty) from else untpd.Pair(from, untpd.Ident(toName))
})
Import(expr, selectors)
@@ -950,7 +950,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
val parents = times(readNat(), readTreeRef)
val self = readValDefRef()
val body = until(end, readTreeRef)
- Trees.Template[Type](???, parents, self, body) // !!! TODO: pull out primary constructor
+ untpd.Template(???, parents, self, body) // !!! TODO: pull out primary constructor
.withType(refType(symbol))
case BLOCKtree =>
@@ -992,7 +992,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
val vparams = until(end, readValDefRef)
val applyType = MethodType(vparams map (_.name), vparams map (_.tpt.tpe), body.tpe)
val applyMeth = cctx.newSymbol(symbol.owner, nme.apply, Method, applyType)
- Closure(applyMeth, Function.const(body.changeOwner(symbol, applyMeth)), tpe)
+ Closure(applyMeth, Function.const(body.changeOwner(symbol, applyMeth)) _)
case ASSIGNtree =>
val lhs = readTreeRef()
diff --git a/src/dotty/tools/dotc/parsing/MarkupParsers.scala b/src/dotty/tools/dotc/parsing/MarkupParsers.scala
index f74ebb509..ef9c81cdb 100644
--- a/src/dotty/tools/dotc/parsing/MarkupParsers.scala
+++ b/src/dotty/tools/dotc/parsing/MarkupParsers.scala
@@ -7,7 +7,6 @@ import mutable.{ Buffer, ArrayBuffer, ListBuffer }
import scala.util.control.ControlThrowable
import util.SourceFile
import scala.xml.{ Text, TextBuffer }
-import scala.xml.parsing.MarkupParserCommon
import scala.xml.Utility.{ isNameStart, isNameChar, isSpace }
import scala.reflect.internal.Chars.{ SU, LF }
import Parsers._
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index 04932c7f0..abba1be37 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -276,9 +276,9 @@ object Parsers {
*/
def convertToTypeId(tree: Tree): Tree = tree match {
case id @ Ident(name) =>
- id.derivedIdent(name.toTypeName)
+ cpy.Ident(id, name.toTypeName)
case id @ Select(qual, name) =>
- id.derivedSelect(qual, name.toTypeName)
+ cpy.Select(id, qual, name.toTypeName)
case _ =>
syntaxError("identifier expected", tree.pos)
tree
@@ -336,7 +336,7 @@ object Parsers {
var opStack: List[OpInfo] = Nil
def checkAssoc(offset: Int, op: Name, leftAssoc: Boolean) =
- if (TreeInfo.isLeftAssoc(op) != leftAssoc)
+ if (isLeftAssoc(op) != leftAssoc)
syntaxError(
"left- and right-associative operators with same precedence may not be mixed", offset)
@@ -376,7 +376,7 @@ object Parsers {
var top = first
while (isIdent && in.name != notAnOperator) {
val op = in.name
- top = reduceStack(base, top, precedence(op), TreeInfo.isLeftAssoc(op))
+ top = reduceStack(base, top, precedence(op), isLeftAssoc(op))
opStack = OpInfo(top, op, in.offset) :: opStack
ident()
newLineOptWhenFollowing(canStartOperand)
@@ -417,7 +417,7 @@ object Parsers {
}
private def makeIdent(tok: Token, name: Name) =
- if (tok == BACKQUOTED_IDENT) new BackquotedIdent(name)
+ if (tok == BACKQUOTED_IDENT) BackquotedIdent(name)
else Ident(name)
/** IdentOrWildcard ::= id | `_' */
@@ -618,7 +618,7 @@ object Parsers {
atPos(start, in.skipToken()) { Function(ts, typ()) }
else {
for (t <- ts)
- if (TreeInfo.isByNameParamType(t))
+ if (isByNameParamType(t))
syntaxError("no by-name parameter type allowed here", t.pos)
val tuple = atPos(start) { makeTupleOrParens(ts) }
infixTypeRest(refinedTypeRest(withTypeRest(simpleTypeRest(tuple))))
@@ -1047,7 +1047,7 @@ object Parsers {
if (in.token == LBRACE) blockExpr() :: Nil else parArgumentExprs()
val argumentExpr = () => exprInParens() match {
- case a @ Assign(Ident(id), rhs) => a.derivedNamedArg(id, rhs)
+ case a @ Assign(Ident(id), rhs) => cpy.NamedArg(a, id, rhs)
case e => e
}
@@ -1192,14 +1192,14 @@ object Parsers {
*/
def pattern1(): Tree = {
val p = pattern2()
- if (TreeInfo.isVarPattern(p) && in.token == COLON) ascription(p, Location.InPattern)
+ if (isVarPattern(p) && in.token == COLON) ascription(p, Location.InPattern)
else p
}
/** Pattern2 ::= [varid `@'] InfixPattern
*/
val pattern2 = () => infixPattern() match {
- case p @ Ident(name) if TreeInfo.isVarPattern(p) && in.token == AT =>
+ case p @ Ident(name) if isVarPattern(p) && in.token == AT =>
atPos(p.pos.start, in.skipToken()) { Bind(name, infixPattern()) }
case p =>
p
@@ -1355,8 +1355,8 @@ object Parsers {
/** Adjust start of annotation or constructor to position of preceding @ or new */
def adjustStart(start: Offset)(tree: Tree): Tree = {
val tree1 = tree match {
- case Apply(fn, args) => tree.derivedApply(adjustStart(start)(fn), args)
- case Select(qual, name) => tree.derivedSelect(adjustStart(start)(qual), name)
+ case Apply(fn, args) => cpy.Apply(tree, adjustStart(start)(fn), args)
+ case Select(qual, name) => cpy.Select(tree, adjustStart(start)(qual), name)
case _ => tree
}
if (start < tree1.pos.start) tree1.withPos(tree1.pos.withStart(start))
@@ -1427,7 +1427,7 @@ object Parsers {
val bounds =
if (isConcreteOwner) typeParamBounds(name)
else typeBounds()
- typeDef(mods, name, hkparams, bounds)
+ TypeDef(mods, name, hkparams, bounds)
}
}
commaSeparated(typeParam)
@@ -1546,7 +1546,7 @@ object Parsers {
imp
case sel @ Select(qual, name) =>
val selector = atPos(sel.pos.point) { Ident(name) }
- sel.derivedImport(qual, selector :: Nil)
+ cpy.Import(sel, qual, selector :: Nil)
case t =>
accept(DOT)
Import(t, Ident(nme.WILDCARD) :: Nil)
@@ -1565,7 +1565,7 @@ object Parsers {
else {
val sel = importSelector()
sel :: {
- if (!TreeInfo.isWildcardArg(sel) && in.token == COMMA) {
+ if (!isWildcardArg(sel) && in.token == COMMA) {
in.nextToken()
importSelectors()
}
@@ -1628,7 +1628,7 @@ object Parsers {
}
} else EmptyTree
lhs match {
- case (id @ Ident(name: TermName)) :: Nil => id.derivedValDef(mods, name, tpt, rhs)
+ case (id @ Ident(name: TermName)) :: Nil => cpy.ValDef(id, mods, name, tpt, rhs)
case _ => PatDef(mods, lhs, tpt, rhs)
}
}
@@ -1708,9 +1708,9 @@ object Parsers {
in.token match {
case EQUALS =>
in.nextToken()
- typeDef(mods, name, tparams, typ())
+ TypeDef(mods, name, tparams, typ())
case SUPERTYPE | SUBTYPE | SEMI | NEWLINE | NEWLINES | COMMA | RBRACE | EOF =>
- typeDef(mods, name, tparams, typeBounds())
+ TypeDef(mods, name, tparams, typeBounds())
case _ =>
syntaxErrorOrIncomplete("`=', `>:', or `<:' expected")
EmptyTree
@@ -1783,7 +1783,7 @@ object Parsers {
*/
def template(constr: DefDef): Template = templateOrNew(constr) match {
case impl: Template => impl
- case parent => Template(constr, parent :: Nil, EmptyValDef(), Nil)
+ case parent => Template(constr, parent :: Nil, EmptyValDef, Nil)
}
/** Same as template, but if {...} is missing and there's only one
@@ -1807,14 +1807,14 @@ object Parsers {
else {
newLineOptWhenFollowedBy(LBRACE)
if (in.token == LBRACE) template(constr)
- else Template(constr, Nil, EmptyValDef(), Nil).withPos(constr.pos.toSynthetic)
+ else Template(constr, Nil, EmptyValDef, Nil).withPos(constr.pos.toSynthetic)
}
/** TemplateBody ::= [nl] `{' TemplateStatSeq `}'
*/
def templateBodyOpt(constr: DefDef, parents: List[Tree]) = atPos(constr.pos.start) {
val (self, stats) =
- if (in.token == LBRACE) templateBody() else (EmptyValDef(), Nil)
+ if (in.token == LBRACE) templateBody() else (EmptyValDef, Nil)
Template(constr, parents, self, stats)
}
@@ -1884,7 +1884,7 @@ object Parsers {
* |
*/
def templateStatSeq(): (ValDef, List[Tree]) = {
- var self: ValDef = EmptyValDef()
+ var self: ValDef = EmptyValDef
val stats = new ListBuffer[Tree]
if (isExprIntro) {
val first = expr1()
@@ -2048,6 +2048,6 @@ object Parsers {
override def blockExpr(): Tree = skipBraces(EmptyTree)
- override def templateBody() = skipBraces((EmptyValDef(), List(EmptyTree)))
+ override def templateBody() = skipBraces((EmptyValDef, List(EmptyTree)))
}
}
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index d0b9dc6bd..a8c6d5bcf 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -16,7 +16,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
protected val PrintableFlags = (ModifierFlags | Label | Module).toCommonFlags
/** The closest enclosing DefDef, TypeDef, or ClassDef node */
- private var currentOwner: Tree[_ >: Untyped] = emptyTree()
+ private var currentOwner: untpd.Tree = untpd.EmptyTree
def atOwner(owner: Tree[_ >: Untyped])(op: => Text): Text = {
val saved = currentOwner
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 3ce735c12..6424b96e4 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -27,7 +27,7 @@ import language.implicitConversions
object Applications {
- import tpd._
+ import tpd.{ cpy => _, _ }
private val isNamedArg = (arg: Any) => arg.isInstanceOf[Trees.NamedArg[_]]
def hasNamedArg(args: List[Any]) = args exists isNamedArg
@@ -44,10 +44,9 @@ object Applications {
* 3. there is an implicit conversion from `tp` to `pt`.
*/
def isCompatible(tp: Type, pt: Type)(implicit ctx: Context): Boolean = (
- tp <:< pt
- || pt.typeSymbol == defn.ByNameParamClass && tp <:< pt.typeArgs.head
- || viewExists(tp, pt)
- )
+ tp <:< pt
+ || pt.typeSymbol == defn.ByNameParamClass && tp <:< pt.typeArgs.head
+ || viewExists(tp, pt))
}
/** The normalized form of a type
@@ -82,15 +81,15 @@ object Applications {
import Applications._
-trait Applications extends Compatibility{ self: Typer =>
+trait Applications extends Compatibility { self: Typer =>
import Applications._
- import tpd._
+ import tpd.{ cpy => _, _ }
+ import untpd.cpy
private def state(implicit ctx: Context) = ctx.typerState
- /**
- * @param Arg the type of arguments, could be tpd.Tree, untpd.Tree, or Type
+ /** @param Arg the type of arguments, could be tpd.Tree, untpd.Tree, or Type
* @param methRef the reference to the method of the application
* @param funType the type of the function part of the application
* @param args the arguments of the application
@@ -206,7 +205,7 @@ trait Applications extends Compatibility{ self: Typer =>
args match {
case (arg @ NamedArg(aname, _)) :: args1 =>
if (namedToArg contains aname)
- emptyTree[T]() :: recur(pnames1, args)
+ genericEmptyTree :: recur(pnames1, args)
else {
badNamedArg(arg)
recur(pnames1, args1)
@@ -222,8 +221,7 @@ trait Applications extends Compatibility{ self: Typer =>
val (namedArgs, otherArgs) = args partition isNamedArg
namedArgs foreach badNamedArg
otherArgs
- }
- else args
+ } else args
}
recur(methodType.paramNames, args)
@@ -289,14 +287,14 @@ trait Applications extends Compatibility{ self: Typer =>
}
def tryDefault(n: Int, args1: List[Arg]): Unit = {
- findDefaultGetter(n + TreeInfo.numArgs(normalizedFun)) match {
+ findDefaultGetter(n + numArgs(normalizedFun)) match {
case dref: NamedType =>
liftFun()
addTyped(treeToArg(spliceMeth(Ident(dref), normalizedFun)), formal)
matchArgs(args1, formals1, n + 1)
case _ =>
missingArg(n)
- }
+ }
}
if (formal.isRepeatedParam)
@@ -377,7 +375,7 @@ trait Applications extends Compatibility{ self: Typer =>
*/
trait TreeApplication[T >: Untyped] extends Application[Trees.Tree[T]] {
type TypeArg = Tree
- def isVarArg(arg: Trees.Tree[T]): Boolean = TreeInfo.isWildcardStarArg(arg)
+ def isVarArg(arg: Trees.Tree[T]): Boolean = isWildcardStarArg(arg)
}
/** Subclass of Application for applicability tests with trees as arguments. */
@@ -471,7 +469,7 @@ trait Applications extends Compatibility{ self: Typer =>
typedArgs = args.asInstanceOf[List[Tree]]
methodType.instantiate(typedArgs map (_.tpe))
}
- val app1 = app.withType(ownType).derivedApply(normalizedFun, typedArgs)
+ val app1 = cpy.Apply(app, normalizedFun, typedArgs).withType(ownType)
if (liftedDefs != null && liftedDefs.nonEmpty) Block(liftedDefs.toList, app1)
else app1
}
@@ -495,7 +493,7 @@ trait Applications extends Compatibility{ self: Typer =>
new ApplyToTyped(app, fun, methRef, args, resultType).result
def typedApply(fun: Tree, methRef: TermRef, args: List[Tree], resultType: Type)(implicit ctx: Context): Tree =
- typedApply(Trees.Apply(untpd.TypedSplice(fun), Nil), fun, methRef, args, resultType)
+ typedApply(untpd.Apply(untpd.TypedSplice(fun), Nil), fun, methRef, args, resultType)
def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = {
if (ctx.mode is Mode.Pattern)
@@ -505,7 +503,7 @@ trait Applications extends Compatibility{ self: Typer =>
def realApply(implicit ctx: Context) = {
val proto = new FunProtoType(tree.args, pt, this)
val fun1 = typedExpr(tree.fun, proto)
- TreeInfo.methPart(fun1).tpe match {
+ methPart(fun1).tpe match {
case funRef: TermRef =>
val app =
if (proto.argsAreTyped) new ApplyToTyped(tree, fun1, funRef, proto.typedArgs, pt)
@@ -525,12 +523,12 @@ trait Applications extends Compatibility{ self: Typer =>
val lhs1 = typedExpr(lhs)
val lifted = new mutable.ListBuffer[Tree]
val lhs2 = untpd.TypedSplice(liftApp(lifted, lhs1))
- val assign = Trees.Assign(lhs2, Trees.Apply(Trees.Select(lhs2, name.init), rhss))
+ val assign = untpd.Assign(lhs2, untpd.Apply(untpd.Select(lhs2, name.init), rhss))
typed(assign)
}
realApply
- if (TreeInfo.isOpAssign(tree))
+ if (untpd.isOpAssign(tree))
tryEither {
implicit ctx => realApply
} { failed =>
@@ -555,7 +553,7 @@ trait Applications extends Compatibility{ self: Typer =>
ctx.error(s"${err.exprStr(typedFn)} does not take type parameters", tree.pos)
ErrorType
}
- tree.withType(ownType).derivedTypeApply(typedFn, typedArgs)
+ cpy.TypeApply(tree, typedFn, typedArgs).withType(ownType)
}
def typedUnApply(qual: untpd.Tree, args: List[untpd.Tree], tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = {
@@ -586,7 +584,7 @@ trait Applications extends Compatibility{ self: Typer =>
ctx.error(s"${unapplyResult.show} is not a valid result type of an unapply method of an extractor", tree.pos)
Nil
}
- }
+ }
recur(unapplyResult)
}
@@ -595,13 +593,14 @@ trait Applications extends Compatibility{ self: Typer =>
val dummyArg = untpd.TypedSplice(dummyTreeOfType(WildcardType))
val unappProto = FunProtoType(dummyArg :: Nil, pt, this)
tryEither {
- implicit ctx => typedExpr(Trees.Select(qual, nme.unapply), unappProto)
+ implicit ctx => typedExpr(untpd.Select(qual, nme.unapply), unappProto)
} {
- s => tryEither {
- implicit ctx => typedExpr(Trees.Select(qual, nme.unapplySeq), unappProto) // for backwards compatibility; will be dropped
- } {
- _ => errorTree(s.value, s"${qual.show} cannot be used as an extractor in a pattern because it lacks an unapply or unapplySeq method")
- }
+ s =>
+ tryEither {
+ implicit ctx => typedExpr(untpd.Select(qual, nme.unapplySeq), unappProto) // for backwards compatibility; will be dropped
+ } {
+ _ => errorTree(s.value, s"${qual.show} cannot be used as an extractor in a pattern because it lacks an unapply or unapplySeq method")
+ }
}
}
fn.tpe.widen match {
@@ -610,7 +609,7 @@ trait Applications extends Compatibility{ self: Typer =>
ownType <:< pt // done for registering the constraints; error message would come later
var argTypes = unapplyArgs(ownType)
val bunchedArgs = argTypes match {
- case argType :: Nil if argType.isRepeatedParam => Trees.SeqLiteral(args) :: Nil
+ case argType :: Nil if argType.isRepeatedParam => untpd.SeqLiteral(args) :: Nil
case _ => args
}
if (argTypes.length != bunchedArgs.length) {
@@ -619,7 +618,7 @@ trait Applications extends Compatibility{ self: Typer =>
List.fill(argTypes.length - args.length)(WildcardType)
}
val typedArgs = (bunchedArgs, argTypes).zipped map (typed(_, _))
- Trees.UnApply(fn, typedArgs).withPos(tree.pos).withType(ownType)
+ untpd.UnApply(fn, typedArgs).withPos(tree.pos).withType(ownType)
case et: ErrorType =>
tree.withType(ErrorType)
}
@@ -713,7 +712,7 @@ trait Applications extends Compatibility{ self: Typer =>
best :: asGood(alts1)
}
- private val dummyTree = Trees.Literal(Constant(null))
+ private val dummyTree = untpd.Literal(Constant(null))
def dummyTreeOfType(tp: Type): Tree = dummyTree withType tp
/** Resolve overloaded alternative `alts`, given expected type `pt`. */
@@ -735,7 +734,7 @@ trait Applications extends Compatibility{ self: Typer =>
def treeShape(tree: untpd.Tree): Tree = tree match {
case NamedArg(name, arg) =>
val argShape = treeShape(arg)
- tree.withType(argShape.tpe).derivedNamedArg(name, argShape)
+ cpy.NamedArg(tree, name, argShape).withType(argShape.tpe)
case _ =>
dummyTreeOfType(typeShape(tree))
}
@@ -783,7 +782,7 @@ trait Applications extends Compatibility{ self: Typer =>
}
case pt @ PolyProtoType(nargs, _) =>
- alts filter ( alt => alt.widen match {
+ alts filter (alt => alt.widen match {
case PolyType(pnames) if pnames.length == nargs => true
case _ => false
})
diff --git a/src/dotty/tools/dotc/typer/EtaExpansion.scala b/src/dotty/tools/dotc/typer/EtaExpansion.scala
index 48b7a063e..6a2b2060e 100644
--- a/src/dotty/tools/dotc/typer/EtaExpansion.scala
+++ b/src/dotty/tools/dotc/typer/EtaExpansion.scala
@@ -21,7 +21,7 @@ object EtaExpansion {
import tpd._
def lift(defs: mutable.ListBuffer[Tree], expr: Tree, prefix: String = "")(implicit ctx: Context): Tree =
- if (TreeInfo.isIdempotentExpr(expr)) expr
+ if (isIdempotentExpr(expr)) expr
else {
val name = ctx.freshName(prefix).toTermName
val sym = ctx.newSymbol(ctx.owner, name, EmptyFlags, expr.tpe, coord = positionCoord(expr.pos))
@@ -46,11 +46,11 @@ object EtaExpansion {
def liftApp(defs: mutable.ListBuffer[Tree], tree: Tree)(implicit ctx: Context): Tree = tree match {
case Apply(fn, args) =>
- tree.derivedApply(liftApp(defs, fn), liftArgs(defs, fn.tpe, args))
+ cpy.Apply(tree, liftApp(defs, fn), liftArgs(defs, fn.tpe, args))
case TypeApply(fn, targs) =>
- tree.derivedTypeApply(liftApp(defs, fn), targs)
+ cpy.TypeApply(tree, liftApp(defs, fn), targs)
case Select(pre, name) =>
- tree.derivedSelect(lift(defs, pre), name)
+ cpy.Select(tree, lift(defs, pre), name)
case Ident(name) =>
lift(defs, tree)
case Block(stats, expr) =>
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index 1279fcf03..716de5f3c 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -178,8 +178,8 @@ class Namer { typer: Typer =>
case Some(cdef) =>
val Thicket((mcls @ TypeDef(_, _, impl: Template)) :: mrest) = expandedTree(mdef)
val Thicket(cls :: TypeDef(_, _, compimpl: Template) :: crest) = expandedTree(cdef)
- val mcls1 = mcls.derivedTypeDef(mcls.mods, mcls.name,
- impl.derivedTemplate(impl.constr, impl.parents, impl.self,
+ val mcls1 = cpy.TypeDef(mcls, mcls.mods, mcls.name,
+ cpy.Template(impl, impl.constr, impl.parents, impl.self,
compimpl.body ++ impl.body))
expandedTree(mdef) = Thicket(mcls1 :: mrest)
expandedTree(cdef) = Thicket(cls :: crest)
@@ -311,7 +311,7 @@ class Namer { typer: Typer =>
def classDefSig(cdef: TypeDef, cls: ClassSymbol)(implicit ctx: Context): Type = {
def parentType(constr: untpd.Tree): Type = {
- val Trees.Select(Trees.New(tpt), _) = TreeInfo.methPart(constr)
+ val Trees.Select(Trees.New(tpt), _) = methPart(constr)
val ptype = typedAheadType(tpt).tpe
if (ptype.uninstantiatedTypeParams.isEmpty) ptype
else typedAheadExpr(constr).tpe
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 6d6211daf..733eac739 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -31,7 +31,7 @@ trait TyperContextOps { ctx: Context => }
object Typer {
- import tpd._
+ import tpd.{cpy => _, _}
object BindingPrec {
val definition = 4
@@ -59,8 +59,9 @@ object Typer {
class Typer extends Namer with Applications with Implicits {
- import tpd._
import Typer._
+ import tpd.{cpy => _, _}
+ import untpd.cpy
/** A temporary data item valid for a single typed ident:
* The set of all root import symbols that have been
@@ -300,7 +301,7 @@ class Typer extends Namer with Applications with Implicits {
val qual1 = typedExpr(tree.qualifier, RefinedType(WildcardType, tree.name, pt))
val ownType = typedSelection(qual1.exprType, tree.name, tree.pos)
if (!ownType.isError) checkAccessible(ownType, qual1.isInstanceOf[Super], tree.pos)
- tree.withType(ownType).derivedSelect(qual1, tree.name)
+ cpy.Select(tree, qual1, tree.name).withType(ownType)
}
def typedThis(tree: untpd.This)(implicit ctx: Context): Tree = {
@@ -326,7 +327,7 @@ class Typer extends Namer with Applications with Implicits {
else if (ctx.mode is Mode.InSuperInit) cls.info.firstParent
else cls.info.parents.reduceLeft((x: Type, y: Type) => AndType(x, y))
- tree.withType(SuperType(cls.thisType, owntype)).derivedSuper(qual1, mix)
+ cpy.Super(tree, qual1, mix).withType(SuperType(cls.thisType, owntype))
}
def typedLiteral(tree: untpd.Literal)(implicit ctx: Context) =
@@ -336,24 +337,24 @@ class Typer extends Namer with Applications with Implicits {
val tpt1 = typedType(tree.tpt)
val cls = checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos)
checkInstantiatable(cls, tpt1.pos)
- tree.withType(tpt1.tpe).derivedNew(tpt1)
+ cpy.New(tree, tpt1).withType(tpt1.tpe)
}
def typedPair(tree: untpd.Pair)(implicit ctx: Context) = {
val left1 = typed(tree.left)
val right1 = typed(tree.right)
- tree.withType(defn.PairType.appliedTo(left1.tpe :: right1.tpe :: Nil)).derivedPair(left1, right1)
+ cpy.Pair(tree, left1, right1).withType(defn.PairType.appliedTo(left1.tpe :: right1.tpe :: Nil))
}
def TypedTyped(tree: untpd.Typed)(implicit ctx: Context) = {
val tpt1 = typedType(tree.tpt)
val expr1 = typedExpr(tree.expr, tpt1.tpe)
- tree.withType(tpt1.tpe).derivedTyped(tpt1, expr1)
+ cpy.Typed(tree, tpt1, expr1).withType(tpt1.tpe)
}
def NamedArg(tree: untpd.NamedArg, pt: Type)(implicit ctx: Context) = {
val arg1 = typed(tree.arg, pt)
- tree.withType(arg1.tpe).derivedNamedArg(tree.name, arg1)
+ cpy.NamedArg(tree, tree.name, arg1).withType(arg1.tpe)
}
def Assign(tree: untpd.Assign)(implicit ctx: Context) = {
@@ -375,7 +376,7 @@ class Typer extends Namer with Applications with Implicits {
val tpt1 = typedType(tpt)
val rhs1 = typedExpr(rhs, tpt1.tpe)
val pt = if (sym.exists) sym.symRef else NoType
- vdef.withType(pt).derivedValDef(mods1, name, tpt1, rhs1)
+ cpy.ValDef(vdef, mods1, name, tpt1, rhs1).withType(pt)
}
def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = {
@@ -385,7 +386,7 @@ class Typer extends Namer with Applications with Implicits {
val vparamss1 = vparamss.mapconserve(_ mapconserve (typed(_).asInstanceOf[ValDef]))
val tpt1 = typedType(tpt)
val rhs1 = typedExpr(rhs, tpt1.tpe)
- ddef.withType(sym.symRef).derivedDefDef(mods1, name, tparams1, vparamss1, tpt1, rhs1)
+ cpy.DefDef(ddef, mods1, name, tparams1, vparamss1, tpt1, rhs1).withType(sym.symRef)
//todo: make sure dependent method types do not depend on implicits or by-name params
}
@@ -393,7 +394,7 @@ class Typer extends Namer with Applications with Implicits {
val TypeDef(mods, name, rhs) = tdef
val mods1 = typedModifiers(mods)
val rhs1 = typedType(rhs)
- tdef.withType(sym.symRef).derivedTypeDef(mods1, name, rhs1)
+ cpy.TypeDef(tdef, mods1, name, rhs1).withType(sym.symRef)
}
def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context) = {
@@ -401,15 +402,15 @@ class Typer extends Namer with Applications with Implicits {
val mods1 = typedModifiers(mods)
val constr1 = typed(constr).asInstanceOf[DefDef]
val parents1 = parents mapconserve (typed(_))
- val self1 = self.withType(NoType).derivedValDef(
- typedModifiers(self.mods), self.name, typedType(self.tpt), EmptyTree)
+ val self1 = cpy.ValDef(self, typedModifiers(self.mods), self.name, typedType(self.tpt), EmptyTree)
+ .withType(NoType)
val localDummy = ctx.newLocalDummy(cls, impl.pos)
val body1 = typedStats(body, localDummy)(inClassContext(cls, self.name))
- val impl1 = impl.withType(localDummy.symRef).derivedTemplate(
- constr1, parents1, self1, body1)
+ val impl1 = cpy.Template(impl, constr1, parents1, self1, body1)
+ .withType(localDummy.symRef)
- cdef.withType(cls.symRef).derivedTypeDef(mods1, name, impl1)
+ cpy.TypeDef(cdef, mods1, name, impl1).withType(cls.symRef)
// todo later: check that
// 1. If class is non-abstract, it is instantiatable:
@@ -422,7 +423,7 @@ class Typer extends Namer with Applications with Implicits {
def typedImport(imp: untpd.Import, sym: Symbol)(implicit ctx: Context): Import = {
val expr1 = typedExpr(imp.expr)
- imp.withType(sym.symRef).derivedImport(expr1, imp.selectors)
+ cpy.Import(imp, expr1, imp.selectors).withType(sym.symRef)
}
def typedExpanded(tree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = {
@@ -509,7 +510,7 @@ class Typer extends Namer with Applications with Implicits {
def tryInsertApply(tree: Tree, pt: Type)(fallBack: StateFul[Tree] => Tree)(implicit ctx: Context): Tree =
tryEither {
- implicit ctx => typedSelect(Trees.Select(untpd.TypedSplice(tree), nme.apply), pt)
+ implicit ctx => typedSelect(untpd.Select(untpd.TypedSplice(tree), nme.apply), pt)
} {
fallBack
}
@@ -582,7 +583,7 @@ class Typer extends Namer with Applications with Implicits {
def adaptToArgs(tp: Type, pt: FunProtoType) = tp match {
case _: MethodType => tree
case _ => tryInsertApply(tree, pt) {
- def fn = err.refStr(TreeInfo.methPart(tree).tpe)
+ def fn = err.refStr(methPart(tree).tpe)
val more = tree match {
case Apply(_, _) => " more"
case _ => ""
diff --git a/test/test/ContravariantTrees.scala b/test/test/ContravariantTrees.scala
new file mode 100644
index 000000000..5fd45bce2
--- /dev/null
+++ b/test/test/ContravariantTrees.scala
@@ -0,0 +1,65 @@
+package test
+
+import language.higherKinds
+import dotty.tools.dotc.core._
+import Flags._, Names._, StdNames._
+import annotation.unchecked.uncheckedVariance
+
+object ContravariantTrees {
+
+ type Untyped = Null
+
+ case class Modifiers[-T >: Untyped] (
+ flags: FlagSet = EmptyFlags,
+ privateWithin: TypeName = tpnme.EMPTY,
+ annotations: List[Tree[T]] = Nil) {
+
+ def is(fs: FlagSet): Boolean = flags is fs
+ def is(fc: FlagConjunction): Boolean = flags is fc
+
+ def | (fs: FlagSet): Modifiers[T] = withFlags(flags | fs)
+ def & (fs: FlagSet): Modifiers[T] = withFlags(flags & fs)
+ def &~(fs: FlagSet): Modifiers[T] = withFlags(flags &~ fs)
+
+ def toTypeFlags: Modifiers[T] = withFlags(flags.toTypeFlags)
+ def toTermFlags: Modifiers[T] = withFlags(flags.toTermFlags)
+
+ private def withFlags(flags: FlagSet) =
+ if (this.flags == flags) this
+ else copy(flags = flags)
+
+ def withPrivateWithin(pw: TypeName) =
+ if (pw.isEmpty) this
+ else copy(privateWithin = pw)
+
+ def hasFlags = flags != EmptyFlags
+ def hasAnnotations = annotations.nonEmpty
+ def hasPrivateWithin = privateWithin != tpnme.EMPTY
+ }
+
+ abstract class Tree[-T >: Untyped] {
+ private[this] var myTpe: T = _
+ private def setMyTpe(tpe: T) = myTpe = tpe
+
+ def tpe: T @uncheckedVariance = {
+ if (myTpe == null) throw new Error()
+ myTpe
+ }
+ }
+
+ trait TermTree[-T >: Untyped] extends Tree[T] {
+ type ThisTree[T >: Untyped] <: TermTree[T]
+ }
+
+ case class Select[-T >: Untyped](qualifier: Tree[T], name: Name)
+ extends TermTree[T] {
+ type ThisTree[T >: Untyped] = Select[T]
+ }
+
+ /** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
+ case class DefDef[-T >: Untyped](mods: Modifiers[T], name: TermName, tparams: List[Tree[T]], vparamss: List[List[Tree[T]]], tpt: Tree[T], rhs: Tree[T])
+ extends Tree[T] {
+ type ThisTree[T >: Untyped] = DefDef[T]
+ }
+
+} \ No newline at end of file
diff --git a/test/test/DeSugarTest.scala b/test/test/DeSugarTest.scala
index b408d4b34..ba6be7cef 100644
--- a/test/test/DeSugarTest.scala
+++ b/test/test/DeSugarTest.scala
@@ -5,12 +5,12 @@ import dotty.tools.dotc.util._
import dotty.tools.dotc.core._
import dotty.tools.dotc.parsing._
import Tokens._, Parsers._
-import org.junit.Test
import dotty.tools.dotc._
import ast.Trees._
import ast.desugar
import ast.desugar._
import typer.Mode
+import Contexts.Context
import scala.collection.mutable.ListBuffer
@@ -22,7 +22,7 @@ class DeSugarTest extends ParserTest {
val Expr = Mode(0)
- object DeSugar extends TreeTransformer {
+ object DeSugar extends UntypedTreeTransformer {
var curMode: Mode = Expr
def withMode[T](mode: Mode)(op: => T) = {
val saved = curMode
@@ -31,10 +31,10 @@ class DeSugarTest extends ParserTest {
finally curMode = saved
}
- def transform(tree: Tree, mode: Mode): Tree = withMode(mode) { transform(tree) }
- def transform(trees: List[Tree], mode: Mode): List[Tree] = withMode(mode) { transform(trees) }
+ def transform(tree: Tree, mode: Mode)(implicit ctx: Context): Tree = withMode(mode) { transform(tree) }
+ def transform(trees: List[Tree], mode: Mode)(implicit ctx: Context): List[Tree] = withMode(mode) { transform(trees) }
- override def transform(tree: Tree): Tree = {
+ override def transform(tree: Tree)(implicit ctx: Context): Tree = {
val tree1 = desugar(tree)(ctx.withMode(curMode))
tree1 match {
case TypedSplice(t) =>
@@ -42,29 +42,29 @@ class DeSugarTest extends ParserTest {
case PostfixOp(od, op) =>
PostfixOp(transform(od), op)
case Select(qual, name) =>
- tree1.derivedSelect(transform(qual, Expr), name)
+ cpy.Select(tree1, transform(qual, Expr), name)
case Apply(fn, args) =>
- tree1.derivedApply(transform(fn, Expr), transform(args))
+ cpy.Apply(tree1, transform(fn, Expr), transform(args))
case TypeApply(fn, args) =>
- tree1.derivedTypeApply(transform(fn, Expr), transform(args, Type))
+ cpy.TypeApply(tree1, transform(fn, Expr), transform(args, Type))
case New(tpt) =>
- tree1.derivedNew(transform(tpt, Type))
+ cpy.New(tree1, transform(tpt, Type))
case Typed(expr, tpt) =>
- tree1.derivedTyped(transform(expr), transform(tpt, Type))
+ cpy.Typed(tree1, transform(expr), transform(tpt, Type))
case CaseDef(pat, guard, body) =>
- tree1.derivedCaseDef(transform(pat, Pattern), transform(guard), transform(body))
+ cpy.CaseDef(tree1, transform(pat, Pattern), transform(guard), transform(body))
case SeqLiteral(elems) =>
- tree1.derivedSeqLiteral(transform(elems))
+ cpy.SeqLiteral(tree1, transform(elems))
case UnApply(fun, args) =>
- tree1.derivedUnApply(transform(fun, Expr), transform(args))
+ cpy.UnApply(tree1, transform(fun, Expr), transform(args))
case ValDef(mods, name, tpt, rhs) =>
- tree1.derivedValDef(mods, name, transform(tpt, Type), transform(rhs))
+ cpy.ValDef(tree1, mods, name, transform(tpt, Type), transform(rhs))
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- tree1.derivedDefDef(mods, name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt, Type), transform(rhs))
+ cpy.DefDef(tree1, mods, name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt, Type), transform(rhs))
case tree1 @ TypeDef(mods, name, rhs) =>
- tree1.derivedTypeDef(mods, name, transform(rhs, Type), transformSub(tree1.tparams))
+ cpy.TypeDef(tree1, mods, name, transform(rhs, Type), transformSub(tree1.tparams))
case Template(constr, parents, self, body) =>
- tree1.derivedTemplate(transformSub(constr), transform(parents), transformSub(self), transform(body, Expr))
+ cpy.Template(tree1, transformSub(constr), transform(parents), transformSub(self), transform(body, Expr))
case Thicket(trees) =>
Thicket(flatten(trees mapConserve super.transform))
case tree1 =>
@@ -93,4 +93,4 @@ class DeSugarTest extends ParserTest {
}
def desugarAll() = parsedTrees foreach (desugarTree(_).show)
-} \ No newline at end of file
+}
diff --git a/test/test/DottyTest.scala b/test/test/DottyTest.scala
index 2d9397fa6..3121909e4 100644
--- a/test/test/DottyTest.scala
+++ b/test/test/DottyTest.scala
@@ -7,7 +7,6 @@ import dotty.tools.dotc.core.Flags._
import Types._, Symbols._, Decorators._
import dotty.tools.dotc.printing.Texts._
import dotty.tools.dotc.core.Decorators._
-import org.junit.Test
class DottyTest {
diff --git a/test/test/parsePackage.scala b/test/test/parsePackage.scala
index c9f0a0651..5c74c87ff 100644
--- a/test/test/parsePackage.scala
+++ b/test/test/parsePackage.scala
@@ -3,6 +3,7 @@ package test
import dotty.tools.dotc._
import core._, ast._
import Trees._
+import Contexts.Context
object parsePackage extends ParserTest {
@@ -10,8 +11,8 @@ object parsePackage extends ParserTest {
var nodes = 0
- val transformer = new TreeTransformer {
- override def transform(tree: Tree): Tree = {
+ val transformer = new UntypedTreeTransformer {
+ override def transform(tree: Tree)(implicit ctx: Context): Tree = {
nodes += 1
tree match {
case Ident(name) =>