trees.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 1,693 行 · 第 1/5 页
SCALA
1,693 行
copy.Select(tree, transform(qualifier), selector) case Ident(name) => copy.Ident(tree, name) case Literal(value) => copy.Literal(tree, value) case TypeTree() => copy.TypeTree(tree) case Annotated(annot, arg) => copy.Annotated(tree, transform(annot).asInstanceOf[Annotation], transform(arg)) case SingletonTypeTree(ref) => copy.SingletonTypeTree(tree, transform(ref)) case SelectFromTypeTree(qualifier, selector) => copy.SelectFromTypeTree(tree, transform(qualifier), selector) case CompoundTypeTree(templ) => copy.CompoundTypeTree(tree, transformTemplate(templ)) case AppliedTypeTree(tpt, args) => copy.AppliedTypeTree(tree, transform(tpt), transformTrees(args)) case TypeBoundsTree(lo, hi) => copy.TypeBoundsTree(tree, transform(lo), transform(hi)) case ExistentialTypeTree(tpt, whereClauses) => copy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses)) case tree : StubTree => tree.symbol = NoSymbol tree.tpe = null tree } def transformTrees(trees: List[Tree]): List[Tree] = List.mapConserve(trees)(transform) def transformTemplate(tree: Template): Template = transform(tree: Tree).asInstanceOf[Template] def transformTypeDefs(trees: List[TypeDef]): List[TypeDef] = List.mapConserve(trees)(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] = List.mapConserve(trees)(transformValDef) def transformValDefss(treess: List[List[ValDef]]): List[List[ValDef]] = List.mapConserve(treess)(transformValDefs) def transformCaseDefs(trees: List[CaseDef]): List[CaseDef] = List.mapConserve(trees)(tree => transform(tree).asInstanceOf[CaseDef]) def transformIdents(trees: List[Ident]): List[Ident] = List.mapConserve(trees)(tree => transform(tree).asInstanceOf[Ident]) def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = List.mapConserve(stats)(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 atOwner[A](owner: Symbol)(trans: => A): A = { val prevOwner = currentOwner currentOwner = owner val result = trans currentOwner = prevOwner result } } class Traverser { protected var currentOwner: Symbol = definitions.RootClass def traverse(tree: Tree): Unit = tree match { case EmptyTree => ; case PackageDef(name, stats) => atOwner(tree.symbol.moduleClass) { traverseTrees(stats) } case ClassDef(mods, name, tparams, impl) => atOwner(tree.symbol) { traverseTrees(mods.annotations); traverseTrees(tparams); traverse(impl) } case ModuleDef(mods, name, impl) => atOwner(tree.symbol.moduleClass) { traverseTrees(mods.annotations); traverse(impl) } case ValDef(mods, name, tpt, rhs) => atOwner(tree.symbol) { traverseTrees(mods.annotations); traverse(tpt); traverse(rhs) } case DefDef(mods, name, tparams, vparamss, tpt, rhs) => atOwner(tree.symbol) { traverseTrees(mods.annotations); traverseTrees(tparams); traverseTreess(vparamss); traverse(tpt); traverse(rhs) } case TypeDef(mods, name, tparams, rhs) => atOwner(tree.symbol) { traverseTrees(mods.annotations); traverseTrees(tparams); traverse(rhs) } case LabelDef(name, params, rhs) => traverseTrees(params); traverse(rhs) case Import(expr, selectors) => traverse(expr) case Annotation(constr, elements) => traverse(constr); traverseTrees(elements) case Annotated(annot, arg) => traverse(annot); traverse(arg) case DocDef(comment, definition) => traverse(definition) case Template(parents, self, body) => traverseTrees(parents) if (!self.isEmpty) traverse(self) traverseStats(body, tree.symbol) case Block(stats, expr) => traverseTrees(stats); traverse(expr) case CaseDef(pat, guard, body) => traverse(pat); traverse(guard); traverse(body) case Sequence(trees) => traverseTrees(trees) case Alternative(trees) => traverseTrees(trees) case Star(elem) => traverse(elem) case Bind(name, body) => traverse(body) case UnApply(fun, args) => traverse(fun); traverseTrees(args) case ArrayValue(elemtpt, trees) => traverse(elemtpt); traverseTrees(trees) case Function(vparams, body) => atOwner(tree.symbol) { traverseTrees(vparams); traverse(body) } case Assign(lhs, rhs) => traverse(lhs); traverse(rhs) case If(cond, thenp, elsep) => traverse(cond); traverse(thenp); traverse(elsep) case Match(selector, cases) => traverse(selector); traverseTrees(cases) case Return(expr) => traverse(expr) case Try(block, catches, finalizer) => traverse(block); traverseTrees(catches); traverse(finalizer) case Throw(expr) => traverse(expr) case New(tpt) => traverse(tpt) case Typed(expr, tpt) => traverse(expr); traverse(tpt) case TypeApply(fun, args) => traverse(fun); traverseTrees(args) case Apply(fun, args) => traverse(fun); traverseTrees(args) case ApplyDynamic(qual, args) => traverse(qual); traverseTrees(args) case Super(_, _) => ; case This(_) => ; case Select(qualifier, selector) => traverse(qualifier) case Ident(_) => ; case Literal(_) => ; case TypeTree() => ; case SingletonTypeTree(ref) => traverse(ref) case SelectFromTypeTree(qualifier, selector) => traverse(qualifier) case CompoundTypeTree(templ) => traverse(templ) case AppliedTypeTree(tpt, args) => traverse(tpt); traverseTrees(args) case TypeBoundsTree(lo, hi) => traverse(lo); traverse(hi) case ExistentialTypeTree(tpt, whereClauses) => traverse(tpt); traverseTrees(whereClauses) case tree : StubTree => } def traverseTrees(trees: List[Tree]) { trees foreach traverse } def traverseTreess(treess: List[List[Tree]]) { treess foreach traverseTrees } def traverseStats(stats: List[Tree], exprOwner: Symbol) { stats foreach (stat => if (exprOwner != currentOwner && stat.isTerm) atOwner(exprOwner)(traverse(stat)) else traverse(stat)) } def apply[T <: Tree](tree: T): T = { traverse(tree); tree } def atOwner(owner: Symbol)(traverse: => Unit) { val prevOwner = currentOwner currentOwner = owner traverse currentOwner = prevOwner } } 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) } } class TreeTypeSubstituter(from: List[Symbol], to: List[Type]) extends Traverser { val typeSubst = new SubstTypeMap(from, to) override def traverse(tree: Tree) { if (tree.tpe ne null) tree.tpe = typeSubst(tree.tpe) super.traverse(tree) } override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate) } class TreeSymSubstituter(from: List[Symbol], to: List[Symbol]) extends Traverser { val symSubst = new SubstSymMap(from, to) override def traverse(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) super.traverse(tree) } override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate) } class ChangeOwnerTraverser(val oldowner: Symbol, val newowner: Symbol) extends Traverser { override def traverse(tree: Tree) { if ((tree.isDef || tree.isInstanceOf[Function]) && tree.symbol != NoSymbol && tree.symbol.owner == oldowner) tree.symbol.owner = newowner; super.traverse(tree) } } final class TreeList { private var trees = List[Tree]() def append(t: Tree): TreeList = { trees = t :: trees; this } def append(ts: List[Tree]): TreeList = { trees = ts reverse_::: trees; this } def toList: List[Tree] = trees.reverse } 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 = { this.pos = pos traverse(tree) tree } } 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 resetAttrs[A<:Tree](x:A):A = {new ResetAttrsTraverser().traverse(x); x} /** A traverser which resets symbol and tpe fields of all nodes in a given tree * except for (1) TypeTree nodes, whose <code>.tpe</code> field is kept and * (2) if a <code>.symbol</code> field refers to a symbol which is defined * outside the tree, it is also kept. * * (bq:) This traverser has mutable state and should be discarded after use */ class ResetAttrsTraverser extends Traverser { private val erasedSyms = new HashSet[Symbol](8) override def traverse(tree: Tree): Unit = tree match { case EmptyTree | TypeTree() => ; case Template(parents, self, body) => tree.symbol = NoSymbol tree.tpe = null for (stat <- body) if (stat.isDef) erasedSyms.addEntry(stat.symbol) super.traverse(tree) case _: DefTree => erasedSyms.addEntry(tree.symbol) tree.symbol = NoSymbol tree.tpe = null super.traverse(tree) case _ => if (tree.hasSymbol && erasedSyms.contains(tree.symbol)) tree.symbol = NoSymbol tree.tpe = null super.traverse(tree) } } /* hook to memoize trees in IDE */ trait TreeKind { def isType : Boolean def isTerm : Boolean def isDef : Boolean def hasSymbol : Boolean def isTop : Boolean } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?