scala.tools.nsc.ast.Trees.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.servicemix.bundles.scala-compiler
Show all versions of org.apache.servicemix.bundles.scala-compiler
This OSGi bundle wraps ${pkgArtifactId} ${pkgVersion} jar file.
/* NSC -- new Scala compiler
* Copyright 2005-2011 LAMP/EPFL
* @author Martin Odersky
*/
package scala.tools.nsc
package ast
import scala.collection.mutable.ListBuffer
import scala.tools.nsc.symtab.SymbolTable
import scala.tools.nsc.symtab.Flags._
import scala.tools.nsc.util.{ FreshNameCreator, HashSet, SourceFile }
trait Trees extends reflect.generic.Trees { self: SymbolTable =>
trait CompilationUnitTrait {
var body: Tree
val source: SourceFile
def fresh : FreshNameCreator
def freshTermName(prefix: String): TermName
def freshTypeName(prefix: String): TypeName
}
type CompilationUnit <: CompilationUnitTrait
protected def flagsIntoString(flags: Long, privateWithin: String): String = flagsToString(flags, privateWithin)
// sub-components --------------------------------------------------
lazy val treePrinter = newTreePrinter()
object treeInfo extends {
val trees: Trees.this.type = Trees.this
} with TreeInfo
val treeCopy = new LazyTreeCopier()
implicit def treeWrapper(tree: Tree): TreeOps = new TreeOps(tree)
class TreeOps(tree: Tree) {
def isTerm: Boolean = tree match {
case _: TermTree => true
case Bind(name, _) => name.isTermName
case Select(_, name) => name.isTermName
case Ident(name) => name.isTermName
case Annotated(_, arg) => arg.isTerm
case DocDef(_, defn) => defn.isTerm
case _ => false
}
def isType: Boolean = tree match {
case _: TypTree => true
case Bind(name, _) => name.isTypeName
case Select(_, name) => name.isTypeName
case Ident(name) => name.isTypeName
case Annotated(_, arg) => arg.isType
case DocDef(_, defn) => defn.isType
case _ => false
}
def isErroneous = (tree.tpe ne null) && tree.tpe.isErroneous
def isTyped = (tree.tpe ne null) && !tree.tpe.isErroneous
/** Apply `f' to each subtree */
def foreach(f: Tree => Unit) { new ForeachTreeTraverser(f).traverse(tree) }
/** If 'pf' is defined for a given subtree, call super.traverse(pf(tree)),
* otherwise super.traverse(tree).
*/
def foreachPartial(pf: PartialFunction[Tree, Tree]) { new ForeachPartialTreeTraverser(pf).traverse(tree) }
/** Find all subtrees matching predicate `p' */
def filter(f: Tree => Boolean): List[Tree] = {
val ft = new FilterTreeTraverser(f)
ft.traverse(tree)
ft.hits.toList
}
/** Returns optionally first tree (in a preorder traversal) which satisfies predicate `p',
* or None if none exists.
*/
def find(p: Tree => Boolean): Option[Tree] = {
val ft = new FindTreeTraverser(p)
ft.traverse(tree)
ft.result
}
def changeOwner(pairs: (Symbol, Symbol)*): Tree = {
pairs.foldLeft(tree) { case (t, (oldOwner, newOwner)) =>
new ChangeOwnerTraverser(oldOwner, newOwner) apply t
}
}
/** Is there part of this tree which satisfies predicate `p'? */
def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty
def equalsStructure(that : Tree) = equalsStructure0(that)(_ eq _)
def equalsStructure0(that: Tree)(f: (Tree,Tree) => Boolean): Boolean =
f(tree, that) || ((tree.productArity == that.productArity) && {
def equals0(this0: Any, that0: Any): Boolean = (this0, that0) match {
case (x: Tree, y: Tree) => f(x, y) || (x equalsStructure0 y)(f)
case (xs: List[_], ys: List[_]) => (xs corresponds ys)(equals0)
case _ => this0 == that0
}
def compareOriginals() = (tree, that) match {
case (x: TypeTree, y: TypeTree) if x.original != null && y.original != null =>
(x.original equalsStructure0 y.original)(f)
case _ =>
true
}
(tree.productIterator zip that.productIterator forall { case (x, y) => equals0(x, y) }) && compareOriginals()
})
def shallowDuplicate: Tree = new ShallowDuplicator(tree) transform tree
def shortClass: String = tree.getClass.getName split "[.$]" last
}
private[scala] override def duplicateTree(tree: Tree): Tree = duplicator transform tree
// ---- values and creators ---------------------------------------
/** @param sym the class symbol
* @return the implementation template
*/
def ClassDef(sym: Symbol, impl: Template): ClassDef =
atPos(sym.pos) {
ClassDef(Modifiers(sym.flags),
sym.name.toTypeName,
sym.typeParams map TypeDef,
impl) setSymbol sym
}
/** Construct class definition with given class symbol, value parameters,
* supercall arguments and template body.
*
* @param sym the class symbol
* @param constrMods the modifiers for the class constructor, i.e. as in `class C private (...)'
* @param vparamss the value parameters -- if they have symbols they
* should be owned by `sym'
* @param argss the supercall arguments
* @param body the template statements without primary constructor
* and value parameter fields.
*/
def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef =
ClassDef(sym,
Template(sym.info.parents map TypeTree,
if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym),
constrMods, vparamss, argss, body, superPos))
/**
* @param sym the class symbol
* @param impl the implementation template
*/
def ModuleDef(sym: Symbol, impl: Template): ModuleDef =
atPos(sym.pos) {
ModuleDef(Modifiers(sym.flags), sym.name, impl) setSymbol sym
}
def ValDef(sym: Symbol, rhs: Tree): ValDef =
atPos(sym.pos) {
ValDef(Modifiers(sym.flags), sym.name,
TypeTree(sym.tpe) setPos sym.pos.focus,
rhs) setSymbol sym
}
def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree)
object emptyValDef extends ValDef(Modifiers(PRIVATE), nme.WILDCARD, TypeTree(NoType), EmptyTree) {
override def isEmpty = true
super.setPos(NoPosition)
override def setPos(pos: Position) = { assert(false); this }
}
def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef =
atPos(sym.pos) {
assert(sym != NoSymbol)
DefDef(Modifiers(sym.flags),
sym.name,
sym.typeParams map TypeDef,
vparamss,
TypeTree(sym.tpe.finalResultType) setPos sym.pos.focus,
rhs) setSymbol sym
}
def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef =
DefDef(sym, Modifiers(sym.flags), vparamss, rhs)
def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef =
DefDef(sym, mods, sym.paramss map (_.map(ValDef)), rhs)
def DefDef(sym: Symbol, rhs: Tree): DefDef =
DefDef(sym, Modifiers(sym.flags), rhs)
def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = {
DefDef(sym, rhs(sym.info.paramss))
}
/** A TypeDef node which defines given `sym' with given tight hand side `rhs'. */
def TypeDef(sym: Symbol, rhs: Tree): TypeDef =
atPos(sym.pos) {
TypeDef(Modifiers(sym.flags), sym.name.toTypeName, sym.typeParams map TypeDef, rhs) setSymbol sym
}
/** A TypeDef node which defines abstract type or type parameter for given `sym' */
def TypeDef(sym: Symbol): TypeDef =
TypeDef(sym, TypeBoundsTree(TypeTree(sym.info.bounds.lo), TypeTree(sym.info.bounds.hi)))
def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef =
atPos(sym.pos) {
LabelDef(sym.name, params map Ident, rhs) setSymbol sym
}
/** Generates a template with constructor corresponding to
*
* constrmods (vparams1_) ... (vparams_n) preSuper { presupers }
* extends superclass(args_1) ... (args_n) with mixins { self => body }
*
* This gets translated to
*
* extends superclass with mixins { self =>
* presupers' // presupers without rhs
* vparamss // abstract fields corresponding to value parameters
* def (vparamss) {
* presupers
* super.(args)
* }
* body
* }
*/
def Template(parents: List[Tree], self: ValDef, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): Template = {
/* Add constructor to template */
// create parameters for as synthetic trees.
var vparamss1 =
vparamss map (vps => vps.map { vd =>
atPos(vd.pos.focus) {
ValDef(
Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) withAnnotations vd.mods.annotations,
vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
}})
val (edefs, rest) = body span treeInfo.isEarlyDef
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
val (lvdefs, gvdefs) = evdefs map {
case vdef @ ValDef(mods, name, tpt, rhs) =>
val fld = treeCopy.ValDef(
vdef.duplicate, mods, name,
atPos(vdef.pos.focus) { TypeTree() setOriginal tpt setPos tpt.pos.focus }, // atPos in case
EmptyTree)
val local = treeCopy.ValDef(vdef, Modifiers(PRESUPER), name, tpt, rhs)
(local, fld)
} unzip
val constrs = {
if (constrMods hasFlag TRAIT) {
if (body forall treeInfo.isInterfaceMember) List()
else List(
atPos(wrappingPos(superPos, lvdefs)) (
DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), List(List()), TypeTree(), Block(lvdefs, Literal(())))))
} else {
// convert (implicit ... ) to ()(implicit ... ) if its the only parameter section
if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
vparamss1 = List() :: vparamss1;
val superRef: Tree = atPos(superPos) {
Select(Super(This(tpnme.EMPTY), tpnme.EMPTY), nme.CONSTRUCTOR)
}
val superCall = (superRef /: argss) (Apply)
List(
atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) (
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(())))))
}
}
// println("typed template, gvdefs = "+gvdefs+", parents = "+parents+", constrs = "+constrs)
constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs))
// vparamss2 are used as field definitions for the class. remove defaults
val vparamss2 = vparamss map (vps => vps map { vd =>
treeCopy.ValDef(vd, vd.mods &~ DEFAULTPARAM, vd.name, vd.tpt, EmptyTree)
})
Template(parents, self, gvdefs ::: vparamss2.flatten ::: constrs ::: etdefs ::: rest)
}
/** casedef shorthand */
def CaseDef(pat: Tree, body: Tree): CaseDef = CaseDef(pat, EmptyTree, body)
def Bind(sym: Symbol, body: Tree): Bind =
Bind(sym.name, body) setSymbol sym
/** Factory method for object creation `new tpt(args_1)...(args_n)`
* A `New(t, as)` is expanded to: `(new t).(as)`
*/
def New(tpt: Tree, argss: List[List[Tree]]): Tree = {
assert(!argss.isEmpty)
val superRef: Tree = Select(New(tpt), nme.CONSTRUCTOR)
(superRef /: argss) (Apply)
}
def Super(sym: Symbol, mix: TypeName): Tree = Super(This(sym), mix)
def This(sym: Symbol): Tree = This(sym.name.toTypeName) setSymbol sym
def Select(qualifier: Tree, sym: Symbol): Select =
Select(qualifier, sym.name) setSymbol sym
def Ident(sym: Symbol): Ident =
Ident(sym.name) setSymbol sym
/** Block factory that flattens directly nested blocks.
*/
def Block(stats: Tree*): Block = stats match {
case Seq(b @ Block(_, _)) => b
case Seq(stat) => Block(stats.toList, Literal(Constant(())))
case Seq(_, rest @ _*) => Block(stats.init.toList, stats.last)
}
/** A synthetic term holding an arbitrary type. Not to be confused with
* with TypTree, the trait for trees that are only used for type trees.
* TypeTree's are inserted in several places, but most notably in
* RefCheck
, where the arbitrary type trees are all replaced by
* TypeTree's. */
case class TypeTree() extends AbsTypeTree {
private var orig: Tree = null
private[Trees] var wasEmpty: Boolean = false
def original: Tree = orig
def setOriginal(tree: Tree): this.type = {
def followOriginal(t: Tree): Tree = t match {
case tt: TypeTree => followOriginal(tt.original)
case t => t
}
orig = followOriginal(tree); setPos(tree.pos);
this
}
override def defineType(tp: Type): this.type = {
wasEmpty = isEmpty
setType(tp)
}
}
object TypeTree extends TypeTreeExtractor
def TypeTree(tp: Type): TypeTree = TypeTree() setType tp
/** Documented definition, eliminated by analyzer */
case class DocDef(comment: DocComment, definition: Tree)
extends Tree {
override def symbol: Symbol = definition.symbol
override def symbol_=(sym: Symbol) { definition.symbol = sym }
// sean: seems to be important to the IDE
override def isDef = definition.isDef
}
/** Either an assignment or a named argument. Only appears in argument lists,
* eliminated by typecheck (doTypedApply)
*/
case class AssignOrNamedArg(lhs: Tree, rhs: Tree)
extends TermTree
case class Parens(args: List[Tree]) extends Tree // only used during parsing
/** emitted by typer, eliminated by refchecks */
case class TypeTreeWithDeferredRefCheck()(val check: () => TypeTree) extends AbsTypeTree
// ----- subconstructors --------------------------------------------
class ApplyToImplicitArgs(fun: Tree, args: List[Tree]) extends Apply(fun, args)
class ApplyImplicitView(fun: Tree, args: List[Tree]) extends Apply(fun, args)
// ----- auxiliary objects and methods ------------------------------
abstract class TreeCopier {
def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template): ClassDef
def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]): PackageDef
def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template): ModuleDef
def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree): ValDef
def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef
def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree): TypeDef
def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree): LabelDef
def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]): Import
def DocDef(tree: Tree, comment: DocComment, definition: Tree): DocDef
def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]): Template
def Block(tree: Tree, stats: List[Tree], expr: Tree): Block
def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree): CaseDef
def Alternative(tree: Tree, trees: List[Tree]): Alternative
def Star(tree: Tree, elem: Tree): Star
def Bind(tree: Tree, name: Name, body: Tree): Bind
def UnApply(tree: Tree, fun: Tree, args: List[Tree]): UnApply
def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]): ArrayValue
def Function(tree: Tree, vparams: List[ValDef], body: Tree): Function
def Assign(tree: Tree, lhs: Tree, rhs: Tree): Assign
def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree): AssignOrNamedArg
def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree): If
def Match(tree: Tree, selector: Tree, cases: List[CaseDef]): Match
def Return(tree: Tree, expr: Tree): Return
def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree): Try
def Throw(tree: Tree, expr: Tree): Throw
def New(tree: Tree, tpt: Tree): New
def Typed(tree: Tree, expr: Tree, tpt: Tree): Typed
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]): TypeApply
def Apply(tree: Tree, fun: Tree, args: List[Tree]): Apply
def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]): ApplyDynamic
def Super(tree: Tree, qual: Tree, mix: TypeName): Super
def This(tree: Tree, qual: Name): This
def Select(tree: Tree, qualifier: Tree, selector: Name): Select
def Ident(tree: Tree, name: Name): Ident
def Literal(tree: Tree, value: Constant): Literal
def TypeTree(tree: Tree): TypeTree
def TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck
def Annotated(tree: Tree, annot: Tree, arg: Tree): Annotated
def SingletonTypeTree(tree: Tree, ref: Tree): SingletonTypeTree
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name): SelectFromTypeTree
def CompoundTypeTree(tree: Tree, templ: Template): CompoundTypeTree
def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]): AppliedTypeTree
def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree): TypeBoundsTree
def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]): ExistentialTypeTree
def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type): SelectFromArray
}
class StrictTreeCopier extends TreeCopier {
def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) =
new ClassDef(mods, name.toTypeName, tparams, impl).copyAttrs(tree)
def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]) =
new PackageDef(pid, stats).copyAttrs(tree)
def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) =
new ModuleDef(mods, name, impl).copyAttrs(tree)
def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) =
new ValDef(mods, name, tpt, rhs).copyAttrs(tree)
def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) =
new DefDef(mods, name, tparams, vparamss, tpt, rhs).copyAttrs(tree)
def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) =
new TypeDef(mods, name.toTypeName, tparams, rhs).copyAttrs(tree)
def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) =
new LabelDef(name, params, rhs).copyAttrs(tree)
def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) =
new Import(expr, selectors).copyAttrs(tree)
def DocDef(tree: Tree, comment: DocComment, definition: Tree) =
new DocDef(comment, definition).copyAttrs(tree)
def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]) =
new Template(parents, self, body).copyAttrs(tree)
def Block(tree: Tree, stats: List[Tree], expr: Tree) =
new Block(stats, expr).copyAttrs(tree)
def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) =
new CaseDef(pat, guard, body).copyAttrs(tree)
def Alternative(tree: Tree, trees: List[Tree]) =
new Alternative(trees).copyAttrs(tree)
def Star(tree: Tree, elem: Tree) =
new Star(elem).copyAttrs(tree)
def Bind(tree: Tree, name: Name, body: Tree) =
new Bind(name, body).copyAttrs(tree)
def UnApply(tree: Tree, fun: Tree, args: List[Tree]) =
new UnApply(fun, args).copyAttrs(tree)
def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]) =
new ArrayValue(elemtpt, trees).copyAttrs(tree)
def Function(tree: Tree, vparams: List[ValDef], body: Tree) =
new Function(vparams, body).copyAttrs(tree)
def Assign(tree: Tree, lhs: Tree, rhs: Tree) =
new Assign(lhs, rhs).copyAttrs(tree)
def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) =
new AssignOrNamedArg(lhs, rhs).copyAttrs(tree)
def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) =
new If(cond, thenp, elsep).copyAttrs(tree)
def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) =
new Match(selector, cases).copyAttrs(tree)
def Return(tree: Tree, expr: Tree) =
new Return(expr).copyAttrs(tree)
def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) =
new Try(block, catches, finalizer).copyAttrs(tree)
def Throw(tree: Tree, expr: Tree) =
new Throw(expr).copyAttrs(tree)
def New(tree: Tree, tpt: Tree) =
new New(tpt).copyAttrs(tree)
def Typed(tree: Tree, expr: Tree, tpt: Tree) =
new Typed(expr, tpt).copyAttrs(tree)
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) =
new TypeApply(fun, args).copyAttrs(tree)
def Apply(tree: Tree, fun: Tree, args: List[Tree]) =
(tree match {
case _: ApplyToImplicitArgs => new ApplyToImplicitArgs(fun, args)
case _: ApplyImplicitView => new ApplyImplicitView(fun, args)
case _ => new Apply(fun, args)
}).copyAttrs(tree)
def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) =
new ApplyDynamic(qual, args).copyAttrs(tree)
def Super(tree: Tree, qual: Tree, mix: TypeName) =
new Super(qual, mix).copyAttrs(tree)
def This(tree: Tree, qual: Name) =
new This(qual.toTypeName).copyAttrs(tree)
def Select(tree: Tree, qualifier: Tree, selector: Name) =
new Select(qualifier, selector).copyAttrs(tree)
def Ident(tree: Tree, name: Name) =
new Ident(name).copyAttrs(tree)
def Literal(tree: Tree, value: Constant) =
new Literal(value).copyAttrs(tree)
def TypeTree(tree: Tree) =
new TypeTree().copyAttrs(tree)
def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match {
case dc@TypeTreeWithDeferredRefCheck() => new TypeTreeWithDeferredRefCheck()(dc.check).copyAttrs(tree)
}
def Annotated(tree: Tree, annot: Tree, arg: Tree) =
new Annotated(annot, arg).copyAttrs(tree)
def SingletonTypeTree(tree: Tree, ref: Tree) =
new SingletonTypeTree(ref).copyAttrs(tree)
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) =
new SelectFromTypeTree(qualifier, selector.toTypeName).copyAttrs(tree)
def CompoundTypeTree(tree: Tree, templ: Template) =
new CompoundTypeTree(templ).copyAttrs(tree)
def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) =
new AppliedTypeTree(tpt, args).copyAttrs(tree)
def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) =
new TypeBoundsTree(lo, hi).copyAttrs(tree)
def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) =
new ExistentialTypeTree(tpt, whereClauses).copyAttrs(tree)
def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type) =
new SelectFromArray(qualifier, selector, erasure).copyAttrs(tree)
}
class LazyTreeCopier(treeCopy: TreeCopier) extends TreeCopier {
def this() = this(new StrictTreeCopier)
def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) = tree match {
case t @ ClassDef(mods0, name0, tparams0, impl0)
if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (impl0 == impl) => t
case _ => treeCopy.ClassDef(tree, mods, name, tparams, impl)
}
def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]) = tree match {
case t @ PackageDef(pid0, stats0)
if (pid0 == pid) && (stats0 == stats) => t
case _ => treeCopy.PackageDef(tree, pid, stats)
}
def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) = tree match {
case t @ ModuleDef(mods0, name0, impl0)
if (mods0 == mods) && (name0 == name) && (impl0 == impl) => t
case _ => treeCopy.ModuleDef(tree, mods, name, impl)
}
def ValDef(tree: Tree, mods: Modifiers, name: Name, tpt: Tree, rhs: Tree) = tree match {
case t @ ValDef(mods0, name0, tpt0, rhs0)
if (mods0 == mods) && (name0 == name) && (tpt0 == tpt) && (rhs0 == rhs) => t
case _ => treeCopy.ValDef(tree, mods, name, tpt, rhs)
}
def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) = tree match {
case t @ DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0)
if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) &&
(vparamss0 == vparamss) && (tpt0 == tpt) && (rhs == rhs0) => t
case _ => treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs)
}
def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) = tree match {
case t @ TypeDef(mods0, name0, tparams0, rhs0)
if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (rhs0 == rhs) => t
case _ => treeCopy.TypeDef(tree, mods, name, tparams, rhs)
}
def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = tree match {
case t @ LabelDef(name0, params0, rhs0)
if (name0 == name) && (params0 == params) && (rhs0 == rhs) => t
case _ => treeCopy.LabelDef(tree, name, params, rhs)
}
def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) = tree match {
case t @ Import(expr0, selectors0)
if (expr0 == expr) && (selectors0 == selectors) => t
case _ => treeCopy.Import(tree, expr, selectors)
}
def DocDef(tree: Tree, comment: DocComment, definition: Tree) = tree match {
case t @ DocDef(comment0, definition0)
if (comment0 == comment) && (definition0 == definition) => t
case _ => treeCopy.DocDef(tree, comment, definition)
}
def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]) = tree match {
case t @ Template(parents0, self0, body0)
if (parents0 == parents) && (self0 == self) && (body0 == body) => t
case _ => treeCopy.Template(tree, parents, self, body)
}
def Block(tree: Tree, stats: List[Tree], expr: Tree) = tree match {
case t @ Block(stats0, expr0)
if ((stats0 == stats) && (expr0 == expr)) => t
case _ => treeCopy.Block(tree, stats, expr)
}
def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) = tree match {
case t @ CaseDef(pat0, guard0, body0)
if (pat0 == pat) && (guard0 == guard) && (body0 == body) => t
case _ => treeCopy.CaseDef(tree, pat, guard, body)
}
def Alternative(tree: Tree, trees: List[Tree]) = tree match {
case t @ Alternative(trees0)
if trees0 == trees => t
case _ => treeCopy.Alternative(tree, trees)
}
def Star(tree: Tree, elem: Tree) = tree match {
case t @ Star(elem0)
if elem0 == elem => t
case _ => treeCopy.Star(tree, elem)
}
def Bind(tree: Tree, name: Name, body: Tree) = tree match {
case t @ Bind(name0, body0)
if (name0 == name) && (body0 == body) => t
case _ => treeCopy.Bind(tree, name, body)
}
def UnApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
case t @ UnApply(fun0, args0)
if (fun0 == fun) && (args0 == args) => t
case _ => treeCopy.UnApply(tree, fun, args)
}
def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]) = tree match {
case t @ ArrayValue(elemtpt0, trees0)
if (elemtpt0 == elemtpt) && (trees0 == trees) => t
case _ => treeCopy.ArrayValue(tree, elemtpt, trees)
}
def Function(tree: Tree, vparams: List[ValDef], body: Tree) = tree match {
case t @ Function(vparams0, body0)
if (vparams0 == vparams) && (body0 == body) => t
case _ => treeCopy.Function(tree, vparams, body)
}
def Assign(tree: Tree, lhs: Tree, rhs: Tree) = tree match {
case t @ Assign(lhs0, rhs0)
if (lhs0 == lhs) && (rhs0 == rhs) => t
case _ => treeCopy.Assign(tree, lhs, rhs)
}
def AssignOrNamedArg(tree: Tree, lhs: Tree, rhs: Tree) = tree match {
case t @ AssignOrNamedArg(lhs0, rhs0)
if (lhs0 == lhs) && (rhs0 == rhs) => t
case _ => treeCopy.AssignOrNamedArg(tree, lhs, rhs)
}
def If(tree: Tree, cond: Tree, thenp: Tree, elsep: Tree) = tree match {
case t @ If(cond0, thenp0, elsep0)
if (cond0 == cond) && (thenp0 == thenp) && (elsep0 == elsep) => t
case _ => treeCopy.If(tree, cond, thenp, elsep)
}
def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) = tree match {
case t @ Match(selector0, cases0)
if (selector0 == selector) && (cases0 == cases) => t
case _ => treeCopy.Match(tree, selector, cases)
}
def Return(tree: Tree, expr: Tree) = tree match {
case t @ Return(expr0)
if expr0 == expr => t
case _ => treeCopy.Return(tree, expr)
}
def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) = tree match {
case t @ Try(block0, catches0, finalizer0)
if (block0 == block) && (catches0 == catches) && (finalizer0 == finalizer) => t
case _ => treeCopy.Try(tree, block, catches, finalizer)
}
def Throw(tree: Tree, expr: Tree) = tree match {
case t @ Throw(expr0)
if expr0 == expr => t
case _ => treeCopy.Throw(tree, expr)
}
def New(tree: Tree, tpt: Tree) = tree match {
case t @ New(tpt0)
if tpt0 == tpt => t
case _ => treeCopy.New(tree, tpt)
}
def Typed(tree: Tree, expr: Tree, tpt: Tree) = tree match {
case t @ Typed(expr0, tpt0)
if (expr0 == expr) && (tpt0 == tpt) => t
case _ => treeCopy.Typed(tree, expr, tpt)
}
def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
case t @ TypeApply(fun0, args0)
if (fun0 == fun) && (args0 == args) => t
case _ => treeCopy.TypeApply(tree, fun, args)
}
def Apply(tree: Tree, fun: Tree, args: List[Tree]) = tree match {
case t @ Apply(fun0, args0)
if (fun0 == fun) && (args0 == args) => t
case _ => treeCopy.Apply(tree, fun, args)
}
def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) = tree match {
case t @ ApplyDynamic(qual0, args0)
if (qual0 == qual) && (args0 == args) => t
case _ => treeCopy.ApplyDynamic(tree, qual, args)
}
def Super(tree: Tree, qual: Tree, mix: TypeName) = tree match {
case t @ Super(qual0, mix0)
if (qual0 == qual) && (mix0 == mix) => t
case _ => treeCopy.Super(tree, qual, mix)
}
def This(tree: Tree, qual: Name) = tree match {
case t @ This(qual0)
if qual0 == qual => t
case _ => treeCopy.This(tree, qual)
}
def Select(tree: Tree, qualifier: Tree, selector: Name) = tree match {
case t @ Select(qualifier0, selector0)
if (qualifier0 == qualifier) && (selector0 == selector) => t
case _ => treeCopy.Select(tree, qualifier, selector)
}
def Ident(tree: Tree, name: Name) = tree match {
case t @ Ident(name0)
if name0 == name => t
case _ => treeCopy.Ident(tree, name)
}
def Literal(tree: Tree, value: Constant) = tree match {
case t @ Literal(value0)
if value0 == value => t
case _ => treeCopy.Literal(tree, value)
}
def TypeTree(tree: Tree) = tree match {
case t @ TypeTree() => t
case _ => treeCopy.TypeTree(tree)
}
def TypeTreeWithDeferredRefCheck(tree: Tree) = tree match {
case t @ TypeTreeWithDeferredRefCheck() => t
case _ => treeCopy.TypeTreeWithDeferredRefCheck(tree)
}
def Annotated(tree: Tree, annot: Tree, arg: Tree) = tree match {
case t @ Annotated(annot0, arg0)
if (annot0==annot) => t
case _ => treeCopy.Annotated(tree, annot, arg)
}
def SingletonTypeTree(tree: Tree, ref: Tree) = tree match {
case t @ SingletonTypeTree(ref0)
if ref0 == ref => t
case _ => treeCopy.SingletonTypeTree(tree, ref)
}
def SelectFromTypeTree(tree: Tree, qualifier: Tree, selector: Name) = tree match {
case t @ SelectFromTypeTree(qualifier0, selector0)
if (qualifier0 == qualifier) && (selector0 == selector) => t
case _ => treeCopy.SelectFromTypeTree(tree, qualifier, selector)
}
def CompoundTypeTree(tree: Tree, templ: Template) = tree match {
case t @ CompoundTypeTree(templ0)
if templ0 == templ => t
case _ => treeCopy.CompoundTypeTree(tree, templ)
}
def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) = tree match {
case t @ AppliedTypeTree(tpt0, args0)
if (tpt0 == tpt) && (args0 == args) => t
case _ => treeCopy.AppliedTypeTree(tree, tpt, args)
}
def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) = tree match {
case t @ TypeBoundsTree(lo0, hi0)
if (lo0 == lo) && (hi0 == hi) => t
case _ => treeCopy.TypeBoundsTree(tree, lo, hi)
}
def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[Tree]) = tree match {
case t @ ExistentialTypeTree(tpt0, whereClauses0)
if (tpt0 == tpt) && (whereClauses0 == whereClauses) => t
case _ => treeCopy.ExistentialTypeTree(tree, tpt, whereClauses)
}
def SelectFromArray(tree: Tree, qualifier: Tree, selector: Name, erasure: Type) = tree match {
case t @ SelectFromArray(qualifier0, selector0, _)
if (qualifier0 == qualifier) && (selector0 == selector) => t
case _ => treeCopy.SelectFromArray(tree, qualifier, selector, erasure)
}
}
abstract class Transformer {
val treeCopy: TreeCopier = new LazyTreeCopier
protected var currentOwner: Symbol = definitions.RootClass
protected def currentMethod = currentOwner.enclMethod
protected def currentClass = currentOwner.enclClass
protected def currentPackage = currentOwner.toplevelClass.owner
def transform(tree: Tree): Tree = tree match {
case EmptyTree =>
tree
case PackageDef(pid, stats) =>
treeCopy.PackageDef(
tree, transform(pid).asInstanceOf[RefTree],
atOwner(tree.symbol.moduleClass) {
transformStats(stats, currentOwner)
}
)
case ClassDef(mods, name, tparams, impl) =>
atOwner(tree.symbol) {
treeCopy.ClassDef(tree, transformModifiers(mods), name,
transformTypeDefs(tparams), transformTemplate(impl))
}
case ModuleDef(mods, name, impl) =>
atOwner(tree.symbol.moduleClass) {
treeCopy.ModuleDef(tree, transformModifiers(mods),
name, transformTemplate(impl))
}
case ValDef(mods, name, tpt, rhs) =>
atOwner(tree.symbol) {
treeCopy.ValDef(tree, transformModifiers(mods),
name, transform(tpt), transform(rhs))
}
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
atOwner(tree.symbol) {
treeCopy.DefDef(tree, transformModifiers(mods), name,
transformTypeDefs(tparams), transformValDefss(vparamss),
transform(tpt), transform(rhs))
}
case TypeDef(mods, name, tparams, rhs) =>
atOwner(tree.symbol) {
treeCopy.TypeDef(tree, transformModifiers(mods), name,
transformTypeDefs(tparams), transform(rhs))
}
case LabelDef(name, params, rhs) =>
treeCopy.LabelDef(tree, name, transformIdents(params), transform(rhs)) //bq: Martin, once, atOwner(...) works, also change `LamdaLifter.proxy'
case Import(expr, selectors) =>
treeCopy.Import(tree, transform(expr), selectors)
case DocDef(comment, definition) =>
treeCopy.DocDef(tree, comment, transform(definition))
case Template(parents, self, body) =>
treeCopy.Template(tree, transformTrees(parents), transformValDef(self), transformStats(body, tree.symbol))
case Block(stats, expr) =>
treeCopy.Block(tree, transformStats(stats, currentOwner), transform(expr))
case CaseDef(pat, guard, body) =>
treeCopy.CaseDef(tree, transform(pat), transform(guard), transform(body))
case Alternative(trees) =>
treeCopy.Alternative(tree, transformTrees(trees))
case Star(elem) =>
treeCopy.Star(tree, transform(elem))
case Bind(name, body) =>
treeCopy.Bind(tree, name, transform(body))
case UnApply(fun, args) =>
treeCopy.UnApply(tree, fun, transformTrees(args)) // bq: see test/.../unapplyContexts2.scala
case ArrayValue(elemtpt, trees) =>
treeCopy.ArrayValue(tree, transform(elemtpt), transformTrees(trees))
case Function(vparams, body) =>
atOwner(tree.symbol) {
treeCopy.Function(tree, transformValDefs(vparams), transform(body))
}
case Assign(lhs, rhs) =>
treeCopy.Assign(tree, transform(lhs), transform(rhs))
case AssignOrNamedArg(lhs, rhs) =>
treeCopy.AssignOrNamedArg(tree, transform(lhs), transform(rhs))
case If(cond, thenp, elsep) =>
treeCopy.If(tree, transform(cond), transform(thenp), transform(elsep))
case Match(selector, cases) =>
treeCopy.Match(tree, transform(selector), transformCaseDefs(cases))
case Return(expr) =>
treeCopy.Return(tree, transform(expr))
case Try(block, catches, finalizer) =>
treeCopy.Try(tree, transform(block), transformCaseDefs(catches), transform(finalizer))
case Throw(expr) =>
treeCopy.Throw(tree, transform(expr))
case New(tpt) =>
treeCopy.New(tree, transform(tpt))
case Typed(expr, tpt) =>
treeCopy.Typed(tree, transform(expr), transform(tpt))
case TypeApply(fun, args) =>
treeCopy.TypeApply(tree, transform(fun), transformTrees(args))
case Apply(fun, args) =>
treeCopy.Apply(tree, transform(fun), transformTrees(args))
case ApplyDynamic(qual, args) =>
treeCopy.ApplyDynamic(tree, transform(qual), transformTrees(args))
case Super(qual, mix) =>
treeCopy.Super(tree, transform(qual), mix)
case This(qual) =>
treeCopy.This(tree, qual)
case Select(qualifier, selector) =>
treeCopy.Select(tree, transform(qualifier), selector)
case Ident(name) =>
treeCopy.Ident(tree, name)
case Literal(value) =>
treeCopy.Literal(tree, value)
case TypeTree() =>
treeCopy.TypeTree(tree)
case TypeTreeWithDeferredRefCheck() =>
treeCopy.TypeTreeWithDeferredRefCheck(tree)
case Annotated(annot, arg) =>
treeCopy.Annotated(tree, transform(annot), transform(arg))
case SingletonTypeTree(ref) =>
treeCopy.SingletonTypeTree(tree, transform(ref))
case SelectFromTypeTree(qualifier, selector) =>
treeCopy.SelectFromTypeTree(tree, transform(qualifier), selector)
case CompoundTypeTree(templ) =>
treeCopy.CompoundTypeTree(tree, transformTemplate(templ))
case AppliedTypeTree(tpt, args) =>
treeCopy.AppliedTypeTree(tree, transform(tpt), transformTrees(args))
case TypeBoundsTree(lo, hi) =>
treeCopy.TypeBoundsTree(tree, transform(lo), transform(hi))
case ExistentialTypeTree(tpt, whereClauses) =>
treeCopy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses))
case SelectFromArray(qualifier, selector, erasure) =>
treeCopy.SelectFromArray(tree, transform(qualifier), selector, erasure)
}
def transformTrees(trees: List[Tree]): List[Tree] =
trees mapConserve (transform(_))
def transformTemplate(tree: Template): Template =
transform(tree: Tree).asInstanceOf[Template]
def transformTypeDefs(trees: List[TypeDef]): List[TypeDef] =
trees mapConserve (tree => transform(tree).asInstanceOf[TypeDef])
def transformValDef(tree: ValDef): ValDef =
if (tree.isEmpty) tree else transform(tree).asInstanceOf[ValDef]
def transformValDefs(trees: List[ValDef]): List[ValDef] =
trees mapConserve (transformValDef(_))
def transformValDefss(treess: List[List[ValDef]]): List[List[ValDef]] =
treess mapConserve (transformValDefs(_))
def transformCaseDefs(trees: List[CaseDef]): List[CaseDef] =
trees mapConserve (tree => transform(tree).asInstanceOf[CaseDef])
def transformIdents(trees: List[Ident]): List[Ident] =
trees mapConserve (tree => transform(tree).asInstanceOf[Ident])
def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
stats mapConserve (stat =>
if (exprOwner != currentOwner && stat.isTerm) atOwner(exprOwner)(transform(stat))
else transform(stat)) filter (EmptyTree !=)
def transformUnit(unit: CompilationUnit) { unit.body = transform(unit.body) }
def transformModifiers(mods: Modifiers): Modifiers =
Modifiers(mods.flags, mods.privateWithin, transformTrees(mods.annotations), mods.positions)
def atOwner[A](owner: Symbol)(trans: => A): A = {
val prevOwner = currentOwner
currentOwner = owner
val result = trans
currentOwner = prevOwner
result
}
}
class Traverser extends super.Traverser {
/** Compiler specific tree types are handled here: the remainder are in
* the library's abstract tree traverser.
*/
override def traverse(tree: Tree): Unit = tree match {
case AssignOrNamedArg(lhs, rhs) =>
traverse(lhs); traverse(rhs)
case DocDef(comment, definition) =>
traverse(definition)
case Parens(ts) =>
traverseTrees(ts)
case TypeTreeWithDeferredRefCheck() => // TODO: should we traverse the wrapped tree?
// (and rewrap the result? how to update the deferred check? would need to store wrapped tree instead of returning it from check)
case Super(qual, _) =>
traverse(qual) // !!! remove when Super is done
case _ => super.traverse(tree)
}
/** The abstract traverser is not aware of Tree.isTerm, so we override this one.
*/
override def traverseStats(stats: List[Tree], exprOwner: Symbol) {
stats foreach (stat =>
if (exprOwner != currentOwner && stat.isTerm) atOwner(exprOwner)(traverse(stat))
else traverse(stat)
)
}
/** Leave apply available in the generic traverser to do something else.
*/
def apply[T <: Tree](tree: T): T = { traverse(tree); tree }
}
private lazy val duplicator = new Transformer {
override val treeCopy = new StrictTreeCopier
override def transform(t: Tree) = {
val t1 = super.transform(t)
if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus
t1
}
}
private class ShallowDuplicator(orig: Tree) extends Transformer {
override val treeCopy = new StrictTreeCopier
override def transform(tree: Tree) =
if (tree eq orig) super.transform(tree)
else tree
}
// Create a readable string describing a substitution.
private def substituterString(fromStr: String, toStr: String, from: List[Any], to: List[Any]): String = {
"subst[%s, %s](%s)".format(fromStr, toStr, (from, to).zipped map (_ + " -> " + _) mkString ", ")
}
class TreeSubstituter(from: List[Symbol], to: List[Tree]) extends Transformer {
override def transform(tree: Tree): Tree = tree match {
case Ident(_) =>
def subst(from: List[Symbol], to: List[Tree]): Tree =
if (from.isEmpty) tree
else if (tree.symbol == from.head) to.head
else subst(from.tail, to.tail);
subst(from, to)
case _ =>
super.transform(tree)
}
override def toString = substituterString("Symbol", "Tree", from, to)
}
class TreeTypeSubstituter(val from: List[Symbol], val to: List[Type]) extends Traverser {
val typeSubst = new SubstTypeMap(from, to)
def fromContains = typeSubst.fromContains
def isEmpty = from.isEmpty && to.isEmpty
override def traverse(tree: Tree) {
if (tree.tpe ne null) tree.tpe = typeSubst(tree.tpe)
if (tree.isDef) {
val sym = tree.symbol
val info1 = typeSubst(sym.info)
if (info1 ne sym.info) sym.setInfo(info1)
}
super.traverse(tree)
}
override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate)
override def toString() = "TreeTypeSubstituter("+from+","+to+")"
}
lazy val EmptyTreeTypeSubstituter = new TreeTypeSubstituter(List(), List())
class TreeSymSubstTraverser(val from: List[Symbol], val to: List[Symbol]) extends Traverser {
val subst = new SubstSymMap(from, to)
override def traverse(tree: Tree) {
if (tree.tpe ne null) tree.tpe = subst(tree.tpe)
if (tree.isDef) {
val sym = tree.symbol
val info1 = subst(sym.info)
if (info1 ne sym.info) sym.setInfo(info1)
}
super.traverse(tree)
}
override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate)
override def toString() = "TreeSymSubstTraverser/" + substituterString("Symbol", "Symbol", from, to)
}
/** Substitute symbols in 'from' with symbols in 'to'. Returns a new
* tree using the new symbols and whose Ident and Select nodes are
* name-consistent with the new symbols.
*/
class TreeSymSubstituter(from: List[Symbol], to: List[Symbol]) extends Transformer {
val symSubst = new SubstSymMap(from, to)
override def transform(tree: Tree): Tree = {
def subst(from: List[Symbol], to: List[Symbol]) {
if (!from.isEmpty)
if (tree.symbol == from.head) tree setSymbol to.head
else subst(from.tail, to.tail)
}
if (tree.tpe ne null) tree.tpe = symSubst(tree.tpe)
if (tree.hasSymbol) {
subst(from, to)
tree match {
case Ident(name0) if tree.symbol != NoSymbol =>
treeCopy.Ident(tree, tree.symbol.name)
case Select(qual, name0) =>
treeCopy.Select(tree, transform(qual), tree.symbol.name)
case _ =>
super.transform(tree)
}
} else
super.transform(tree)
}
def apply[T <: Tree](tree: T): T = transform(tree).asInstanceOf[T]
override def toString() = "TreeSymSubstituter/" + substituterString("Symbol", "Symbol", from, to)
}
class ChangeOwnerTraverser(val oldowner: Symbol, val newowner: Symbol) extends Traverser {
def changeOwner(tree: Tree) = {
if ((tree.isDef || tree.isInstanceOf[Function]) &&
tree.symbol != NoSymbol && tree.symbol.owner == oldowner)
tree.symbol.owner = newowner
}
override def traverse(tree: Tree) {
changeOwner(tree)
super.traverse(tree)
}
}
object posAssigner extends Traverser {
var pos: Position = _
override def traverse(t: Tree) {
if (t != EmptyTree && t.pos == NoPosition) {
t.setPos(pos)
super.traverse(t)
}
}
}
def atPos[T <: Tree](pos: Position)(tree: T): T = {
posAssigner.pos = pos
posAssigner.traverse(tree)
tree
}
class ForeachPartialTreeTraverser(pf: PartialFunction[Tree, Tree]) extends Traverser {
override def traverse(tree: Tree) {
val t = if (pf isDefinedAt tree) pf(tree) else tree
super.traverse(t)
}
}
class ForeachTreeTraverser(f: Tree => Unit) extends Traverser {
override def traverse(t: Tree) {
f(t)
super.traverse(t)
}
}
class FilterTreeTraverser(p: Tree => Boolean) extends Traverser {
val hits = new ListBuffer[Tree]
override def traverse(t: Tree) {
if (p(t)) hits += t
super.traverse(t)
}
}
class FindTreeTraverser(p: Tree => Boolean) extends Traverser {
var result: Option[Tree] = None
override def traverse(t: Tree) {
if (result.isEmpty) {
if (p(t)) result = Some(t)
super.traverse(t)
}
}
}
object resetPos extends Traverser {
override def traverse(t: Tree) {
if (t != EmptyTree) t.setPos(NoPosition)
super.traverse(t)
}
}
/** resets symbol and tpe fields in a tree, @see ResetAttrsTraverse
*/
def resetAllAttrs[A<:Tree](x:A): A = { new ResetAttrsTraverser().traverse(x); x }
def resetLocalAttrs[A<:Tree](x:A): A = { new ResetLocalAttrsTraverser().traverse(x); x }
/** A traverser which resets symbol and tpe fields of all nodes in a given tree
* except for (1) TypeTree nodes, whose .tpe
field is kept, and
* (2) This(pkg) nodes, where pkg refers to a package symbol -- their attributes are kept, and
* (3) if a .symbol
field refers to a symbol which is defined
* outside the tree, it is also kept.
*
* (2) is necessary because some This(pkg) are generated where pkg is not
* an enclosing package.n In that case, resetting the symbol would cause the
* next type checking run to fail. See #3152.
*
* (bq:) This traverser has mutable state and should be discarded after use
*/
private class ResetAttrsTraverser extends Traverser {
protected def isLocal(sym: Symbol): Boolean = true
protected def resetDef(tree: Tree) {
tree.symbol = NoSymbol
}
override def traverse(tree: Tree): Unit = {
tree match {
case _: DefTree | Function(_, _) | Template(_, _, _) =>
resetDef(tree)
tree.tpe = null
case tpt: TypeTree =>
if (tpt.wasEmpty) tree.tpe = null
case This(_) if tree.symbol != null && tree.symbol.isPackageClass =>
;
case EmptyTree =>
;
case _ =>
if (tree.hasSymbol && isLocal(tree.symbol)) tree.symbol = NoSymbol
tree.tpe = null
}
super.traverse(tree)
}
}
private class ResetLocalAttrsTraverser extends ResetAttrsTraverser {
private val erasedSyms = HashSet[Symbol](8)
override protected def isLocal(sym: Symbol) = erasedSyms(sym)
override protected def resetDef(tree: Tree) {
erasedSyms addEntry tree.symbol
super.resetDef(tree)
}
override def traverse(tree: Tree): Unit = tree match {
case Template(parents, self, body) =>
for (stat <- body)
if (stat.isDef) erasedSyms.addEntry(stat.symbol)
super.traverse(tree)
case _ =>
super.traverse(tree)
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy