types.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 1,661 行 · 第 1/5 页

SCALA
1,661
字号
    /** For a classtype or refined type, its defined or declared members;     *  inherited by subtypes and typerefs.     *  The empty scope for all other types */    def decls: Scope = EmptyScope    /** The defined or declared members with name `name' in this type;     *  an OverloadedSymbol if several exist, NoSymbol if none exist.     *  Alternatives of overloaded symbol appear in the order they are declared.     */    def decl(name: Name): Symbol = findDecl(name, 0)    /** The non-private defined or declared members with name `name' in this type;     *  an OverloadedSymbol if several exist, NoSymbol if none exist.     *  Alternatives of overloaded symbol appear in the order they are declared.     */    def nonPrivateDecl(name: Name): Symbol = findDecl(name, PRIVATE)    /** A list of all members of this type (defined or inherited)     *  Members appear in linearization order of their owners.     *  Members with the same owner appear in reverse order of their declarations.     */    def members: List[Symbol] = findMember(nme.ANYNAME, 0, 0, false).alternatives    /** A list of all non-private members of this type (defined or inherited) */    def nonPrivateMembers: List[Symbol] =      findMember(nme.ANYNAME, PRIVATE | BRIDGE, 0, false).alternatives    /** A list of all implicit symbols of this type  (defined or inherited) */    def implicitMembers: List[Symbol] =      findMember(nme.ANYNAME, BRIDGE, IMPLICIT, false).alternatives    /** The member with given name,      *  an OverloadedSymbol if several exist, NoSymbol if none exist */    def member(name: Name): Symbol = findMember(name, BRIDGE, 0, false)    /** The non-private member with given name,     *  an OverloadedSymbol if several exist, NoSymbol if none exist */    def nonPrivateMember(name: Name): Symbol =      findMember(name, PRIVATE | BRIDGE, 0, false)    /** The non-local member with given name,     *  an OverloadedSymbol if several exist, NoSymbol if none exist */    def nonLocalMember(name: Name): Symbol =      findMember(name, LOCAL | BRIDGE, 0, false)    /** The least type instance of given class which is a supertype     *  of this type */    def baseType(clazz: Symbol): Type = NoType    /** This type as seen from prefix `pre' and class     *  `clazz'. This means:     *  Replace all thistypes of `clazz' or one of its subclasses     *  by `pre' and instantiate all parameters by arguments of     *  `pre'.     *  Proceed analogously for thistypes referring to outer classes.     */    def asSeenFrom(pre: Type, clazz: Symbol): Type =      if (!isTrivial && (!phase.erasedTypes || pre.typeSymbol == ArrayClass)) {        val m = new AsSeenFromMap(pre, clazz)        val tp = m apply this        existentialAbstraction(m.capturedParams, tp)      } else this    /** The info of `sym', seen as a member of this type.     */    def memberInfo(sym: Symbol): Type =      sym.info.asSeenFrom(this, sym.owner)    /** The type of `sym', seen as a member of this type. */    def memberType(sym: Symbol): Type = {      trackTypeIDE(sym)      //@M don't prematurely instantiate higher-kinded types, they will be instantiated by transform, typedTypeApply, etc. when really necessary     sym.tpeHK match {         case ov @ OverloadedType(pre, alts) =>          OverloadedType(this, alts)/*          val pre1 = pre match {            case ClassInfoType(_, _, clazz) => clazz.tpe            case _ => pre          }          if (this =:= pre1) ov          else if (this =:= pre1.narrow) OverloadedType(this, alts)          else {            Console.println("bad memberType of overloaded symbol: "+this+"/"+pre1+"/"+pre1.narrow)            assert(false)            ov          }*/        case tp =>//          if (sym.name.toString == "c") print(this + ".memberType(" + sym +":" + sym.tpe +")" + sym.ownerChain);//debug          val res = tp.asSeenFrom(this, sym.owner)          res      }    }    /** Substitute types `to' for occurrences of references to     *  symbols `from' in this type.     */    def subst(from: List[Symbol], to: List[Type]): Type =      new SubstTypeMap(from, to) apply this    /** Substitute symbols `to' for occurrences of symbols     *  `from' in this type.     * !!! NOTE !!!: If you need to do a substThis and a substSym, the substThis has to come     * first, as otherwise symbols will immediately get rebound in typeRef to the old      * symbol.     */    def substSym(from: List[Symbol], to: List[Symbol]): Type = if (from eq to) this    else new SubstSymMap(from, to) apply this    /** Substitute all occurrences of `ThisType(from)' in this type     *  by `to'.     * !!! NOTE !!!: If you need to do a substThis and a substSym, the substThis has to come     * first, as otherwise symbols will immediately get rebound in typeRef to the old      * symbol.     */    def substThis(from: Symbol, to: Type): Type =      new SubstThisMap(from, to) apply this    def substSuper(from: Type, to: Type): Type =      new SubstSuperMap(from, to) apply this    /** Returns all parts of this type which satisfy predicate `p' */    def filter(p: Type => Boolean): List[Type] = {      new FilterTypeTraverser(p).traverse(this).hits.toList    }    /** Returns optionally first type (in a preorder traversal) which satisfies predicate `p',     *  or None if none exists.      */    def find(p: Type => Boolean): Option[Type] = {      new FindTypeTraverser(p).traverse(this).result    }    /** Apply `f' to each part of this type */    def foreach(f: Type => Unit) { new ForEachTypeTraverser(f).traverse(this) }    /** Is there part of this type which satisfies predicate `p'? */    def exists(p: Type => Boolean): Boolean = !find(p).isEmpty    /** Does this type contain a reference to this symbol? */    def contains(sym: Symbol): Boolean =      new ContainsTraverser(sym).traverse(this).result    /** Does this type contain a reference to this type */    def containsTp(tp: Type): Boolean =      new ContainsTypeTraverser(tp).traverse(this).result    /** Is this type a subtype of that type? */    def <:<(that: Type): Boolean = {      if (util.Statistics.enabled) subtypeCount += 1      val startTime = if (util.Statistics.enabled) currentTime else 0l      val result =        ((this eq that) ||         (if (explainSwitch) explain("<", isSubType, this, that)          else isSubType(this, that)));      if (util.Statistics.enabled)        subtypeMillis = subtypeMillis + currentTime - startTime      result    }    /** Is this type equivalent to that type? */    def =:=(that: Type): Boolean = (      (this eq that) ||      (if (explainSwitch) explain("=", isSameType, this, that)       else isSameType(this, that))    );    /** Does this type implement symbol `sym' with same or stronger type?     */    def specializes(sym: Symbol): Boolean =      if (explainSwitch) explain("specializes", specializesSym, this, sym)      else specializesSym(this, sym)    /** Is this type close enough to that type so that      *  members with the two type would override each other?     *  This means:      *    - Either both types are polytypes with the same number of     *      type parameters and their result types match after renaming      *      corresponding type parameters     *    - Or both types are method types with equivalent type parameter types     *      and matching result types     *    - Or both types are equivalent     *    - Or phase.erasedTypes is false and both types are neither method nor     *      poly types.     */    def matches(that: Type): Boolean = matchesType(this, that, !phase.erasedTypes)    /** Same as matches, except that non-method types are always assumed to match.     */    def looselyMatches(that: Type): Boolean = matchesType(this, that, true)    /** The shortest sorted upwards closed array of types that contains     *  this type as first element.     *     *  A list or array of types ts is upwards closed if     *     *    for all t in ts:     *      for all typerefs p.s[args] such that t &lt;: p.s[args]      *      there exists a typeref p'.s[args'] in ts such that      *      t &lt;: p'.s['args] &lt;: p.s[args],     *      and     *      for all singleton types p.s such that t &lt;: p.s      *      there exists a singleton type p'.s in ts such that      *      t &lt;: p'.s &lt;: p.s     *     *  Sorting is with respect to Symbol.isLess() on type symbols.     */    def closure: Array[Type] = Array(this)    /** The maximum depth (@see maxDepth) of each type in the closure of this type. */    def closureDepth: Int = 1    def baseClasses: List[Symbol] = List()    /**     *  @param sym the class symbol     *  @return    the index of given class symbol in the closure of this type,     *             or -1 if no base type with given class symbol exists.     */    def closurePos(sym: Symbol): Int = {      val cl = closure      var lo = 0      var hi = cl.length - 1      while (lo <= hi) {        val mid = (lo + hi) / 2        val clsym = cl(mid).typeSymbol        if (sym == clsym) return mid        else if (sym isLess clsym) hi = mid - 1        else if (clsym isLess sym) lo = mid + 1        else throw new Error()      }      -1    }    /** If this is a polytype, a copy with cloned type parameters owned     *  by `owner'. Identity for all other types.     */    def cloneInfo(owner: Symbol) = this    protected def objectPrefix = "object "    protected def packagePrefix = "package "    def trimPrefix(str: String) =      if (str.startsWith(objectPrefix)) str.substring(objectPrefix.length)      else if (str.startsWith(packagePrefix)) str.substring(packagePrefix.length)      else str    /** The string representation of this type used as a prefix */    def prefixString = trimPrefix(toString) + "#"    /** The string representation of this type, with singletypes explained */    def toLongString = {      val str = toString      if (str endsWith ".type") str + " (with underlying type " + widen + ")"      else str    }    /** Is this type completed (i.e. not a lazy type)?     */    def isComplete: Boolean = true    /** If this is a lazy type, assign a new type to `sym'. */    def complete(sym: Symbol) {}    /** If this is a symbol loader type, load and assign a new type to     *  `sym'.     */    def load(sym: Symbol) {}    private def findDecl(name: Name, excludedFlags: Int): Symbol = {      var alts: List[Symbol] = List()      var sym: Symbol = NoSymbol      var e: ScopeEntry = decls.lookupEntry(name)      while (e ne null) {        if (!e.sym.hasFlag(excludedFlags)) {          if (sym == NoSymbol) sym = e.sym          else {            if (alts.isEmpty) alts = List(sym)            alts = e.sym :: alts          }        }        e = decls.lookupNextEntry(e)      }      if (alts.isEmpty) sym      else (baseClasses.head.newOverloaded(this, alts))    }    /**     *  @param name          ...     *  @param excludedFlags ...     *  @param requiredFlags ...     *  @param stableOnly    ...     *  @return              ...     */    //TODO: use narrow only for modules? (correct? efficiency gain?)    def findMember(name: Name, excludedFlags: Int, requiredFlags: Long, stableOnly: Boolean): Symbol = {      if (inIDE) trackTypeIDE(typeSymbol)      if (util.Statistics.enabled) findMemberCount += 1      val startTime = if (util.Statistics.enabled) currentTime else 0l      //Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG      var members: Scope = null      var member: Symbol = NoSymbol      var excluded = excludedFlags | DEFERRED      var self: Type = null      var continue = true      var savedCheckMalformedSwitch = checkMalformedSwitch      checkMalformedSwitch = false      while (continue) {        continue = false        val bcs0 = baseClasses        var bcs = bcs0        while (!bcs.isEmpty) {          val decls = bcs.head.info.decls          var entry =            if (name == nme.ANYNAME) decls.elems else decls lookupEntry name          while (entry ne null) {            val sym = entry.sym            if (sym.getFlag(requiredFlags) == requiredFlags) {              val excl = sym.getFlag(excluded)              if (excl == 0 &&                   (// omit PRIVATE LOCALS unless selector class is contained in class owning the def.                   (bcs eq bcs0) ||                    sym.getFlag(PRIVATE | LOCAL) != (PRIVATE | LOCAL) ||                   (bcs0.head.hasTransOwner(bcs.head)))) {                if (name.isTypeName || stableOnly && sym.isStable) {                  checkMalformedSwitch = savedCheckMalformedSwitch                  if (util.Statistics.enabled)                    findMemberMillis = findMemberMillis + currentTime - startTime                  return sym                } else if (member == NoSymbol) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?