trees.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 1,693 行 · 第 1/5 页
SCALA
1,693 行
/* NSC -- new Scala compiler * Copyright 2005-2008 LAMP/EPFL * @author Martin Odersky */// $Id: Trees.scala 14033 2008-02-17 07:29:11Z mcdirmid $package scala.tools.nsc.astimport java.io.{PrintWriter, StringWriter}import scala.collection.mutable.ListBufferimport scala.tools.nsc.symtab.{Flags, SymbolTable}import scala.tools.nsc.symtab.Flags._import scala.tools.nsc.util.{FreshNameCreator, HashSet, Position, NoPosition, SourceFile}trait Trees { self: SymbolTable => //statistics var nodeCount = 0 trait CompilationUnitTrait { var body: Tree val source: SourceFile def fresh : FreshNameCreator } type CompilationUnit <: CompilationUnitTrait // sub-components -------------------------------------------------- object treePrinters extends TreePrinters { val trees: Trees.this.type = Trees.this } val treePrinter = treePrinters.create() object treeInfo extends TreeInfo { val trees: Trees.this.type = Trees.this } val copy = new LazyTreeCopier() // modifiers -------------------------------------------------------- case class Modifiers(flags: Long, privateWithin: Name, annotations: List[Annotation]) { def isCovariant = hasFlag(COVARIANT ) def isContravariant = hasFlag(CONTRAVARIANT) def isPrivate = hasFlag(PRIVATE ) def isProtected = hasFlag(PROTECTED) def isVariable = hasFlag(MUTABLE ) def isArgument = hasFlag(PARAM ) def isAccessor = hasFlag(ACCESSOR ) def isOverride = hasFlag(OVERRIDE ) def isAbstract = hasFlag(ABSTRACT ) def isDeferred = hasFlag(DEFERRED ) def isCase = hasFlag(CASE ) def isSealed = hasFlag(SEALED ) def isFinal = hasFlag(FINAL ) def isTrait = hasFlag(TRAIT ) def isImplicit = hasFlag(IMPLICIT ) def isPublic = !isPrivate && !isProtected def hasFlag(flag: Long) = (flag & flags) != 0 def & (flag: Long): Modifiers = { val flags1 = flags & flag if (flags1 == flags) this else Modifiers(flags1, privateWithin, annotations) } def &~ (flag: Long): Modifiers = { val flags1 = flags & (~flag) if (flags1 == flags) this else Modifiers(flags1, privateWithin, annotations) } def | (flag: Long): Modifiers = { val flags1 = flags | flag if (flags1 == flags) this else Modifiers(flags1, privateWithin, annotations) } def withAnnotations(annots: List[Annotation]) = if (annots.isEmpty) this else Modifiers(flags, privateWithin, annotations ::: annots) } def Modifiers(flags: Long, privateWithin: Name): Modifiers = Modifiers(flags, privateWithin, List()) def Modifiers(flags: Long): Modifiers = Modifiers(flags, nme.EMPTY.toTypeName) val NoMods = Modifiers(0) // @M helper method for asserts that check consistency in kinding //def kindingIrrelevant(tp: Type) = (tp eq null) || phase.name == "erasure" || phase.erasedTypes abstract class Tree { { import util.Statistics if (Statistics.enabled) nodeCount += 1 } private var rawpos: Position = NoPosition def pos = rawpos var tpe: Type = _ def setPos(pos: Position): this.type = { rawpos = pos; this } def setType(tp: Type): this.type = { /*assert(kindingIrrelevant(tp) || !kindStar || !tp.isHigherKinded, tp+" should not be higher-kinded");*/ tpe = tp this } def symbol: Symbol = null def symbol_=(sym: Symbol) { throw new Error("symbol_= inapplicable for " + this) } def setSymbol(sym: Symbol): this.type = { symbol = sym; this } def hasSymbol = false def isDef = false def isTerm = false def isType = false def isEmpty = false def isErroneous = (tpe ne null) && tpe.isErroneous /** Apply `f' to each subtree */ def foreach(f: Tree => Unit) { new ForeachTreeTraverser(f).traverse(this) } /** Find all subtrees matching predicate `p' */ def filter(f: Tree => Boolean): List[Tree] = { val ft = new FilterTreeTraverser(f) ft.traverse(this) 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(this) ft.result } /** Is there part of this tree which satisfies predicate `p'? */ def exists(p: Tree => Boolean): Boolean = !find(p).isEmpty override def toString(): String = { val buffer = new StringWriter() val printer = treePrinters.create(new PrintWriter(buffer)) printer.print(this) printer.flush() buffer.toString } override def hashCode(): Int = super.hashCode() override def equals(that: Any): Boolean = that match { case t: Tree => this eq t case _ => false } def hashCodeStructure: Int = { var hc = getClass.hashCode def f(what : Any) : Unit = what match { case what : Tree => hc += what.hashCodeStructure case what : Iterable[_] => what.foreach(f) case what : Product => g(what) case null => case what => hc += what.hashCode } def g(what: Product) { hc += what.productArity var i = 0 while (i < what.productArity) { f(what.productElement(i)) i += 1 } } this match { case p : Product => g(p) case _ => } hc } def equalsStructure(that : Tree) = equalsStructure0(that){case (t0,t1) => false} def equalsStructure0(that: Tree)(f : (Tree,Tree) => Boolean): Boolean = { if (this == that) return true if (this.getClass != that.getClass) return false val this0 = this.asInstanceOf[Product] val that0 = that.asInstanceOf[Product] assert(this0.productArity == that0.productArity) def equals0(thiz: Any, that: Any): Boolean = thiz match { case thiz: Tree => f(thiz,that.asInstanceOf[Tree]) || thiz.equalsStructure0(that.asInstanceOf[Tree])(f) case thiz: List[_] => val that0 = that.asInstanceOf[List[Any]] if (thiz.length != that0.length) false else { val results0 = for (i <- 0.until(thiz.length).toList) yield equals0(thiz(i), that0(i)) results0.foldLeft(true)((x,y) => x && y) } case thiz => thiz == that } val results = for (i <- 0.until(this0.productArity).toList) yield equals0(this0.productElement(i), that0.productElement(i)) val b = results.foldLeft(true)((x,y) => x && y) if (b) (this,that) match { case (this0 : TypeTree,that0 : TypeTree) if this0.original != null && that0.original != null => this0.original.equalsStructure0(that0.original)(f) case _ => true } else false } def duplicate: this.type = (duplicator transform this).asInstanceOf[this.type] def shallowDuplicate: this.type = ((new ShallowDuplicator(this)) transform this).asInstanceOf[this.type] def copyAttrs(tree: Tree): this.type = { rawpos = tree.rawpos tpe = tree.tpe if (hasSymbol) symbol = tree.symbol this } } trait SymTree extends Tree { override def hasSymbol = true override var symbol: Symbol = NoSymbol } abstract class DefTree extends SymTree { def name: Name override def isDef = true } trait TermTree extends Tree { override def isTerm = true } /** A tree for a type. Note that not all type trees implement * this trait; in particular, Ident's are an exception. */ trait TypTree extends Tree { override def isType = true }// ----- auxiliary objects and methods ------------------------------ private lazy val duplicator = new Transformer { override val copy = new StrictTreeCopier } private class ShallowDuplicator(orig: Tree) extends Transformer { override val copy = new StrictTreeCopier override def transform(tree: Tree) = if (tree eq orig) super.transform(tree) else tree } private def syntheticParams(owner: Symbol, mtp: Type): List[List[Symbol]] = { var cnt = 0 def freshName() = { cnt += 1; newTermName("x$" + cnt) } def synthetics(mtp: Type): List[List[Symbol]] = mtp match { case PolyType(_, restp) => synthetics(restp) case MethodType(formals, restp) => (formals map (f => owner.newValueParameter(owner.pos, freshName()).setInfo(f))) :: synthetics(restp) case _ => List() } synthetics(mtp) }// def nextPhase = if (phase.id > globalPhase.id) phase else phase.next;// ----- tree node alternatives -------------------------------------- /** The empty tree */ case object EmptyTree extends TermTree { tpe = NoType override def isEmpty = true } abstract class MemberDef extends DefTree { def mods: Modifiers def keyword: String = this match { case TypeDef(_, _, _, _) => "type" case ClassDef(_, _, _, _) => "class" case DefDef(_, _, _, _, _, _) => "def" case ModuleDef(_, _, _) => "object" case PackageDef(_, _) => "package" case ValDef(mods, _, _, _) => if (mods.isVariable) "var" else "val" case _ => "" } final def hasFlag(mask: Long): Boolean = (mods.flags & mask) != 0 } /** Package clause */ case class PackageDef(name: Name, stats: List[Tree]) extends MemberDef { def mods = NoMods } def PackageDef(sym: Symbol, stats: List[Tree]): PackageDef = PackageDef(sym.name, stats) setSymbol sym abstract class ImplDef extends MemberDef { def impl: Template } /** Class definition */ case class ClassDef(mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) extends ImplDef /** * @param sym the class symbol * @param impl ... * @return ... */ def ClassDef(sym: Symbol, impl: Template): ClassDef = posAssigner.atPos(sym.pos) { ClassDef(Modifiers(sym.flags), sym.name, 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 vparamss the value parameters -- if they have symbols they
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?