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 + -
显示快捷键?