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 <: p.s[args] * there exists a typeref p'.s[args'] in ts such that * t <: p'.s['args] <: p.s[args], * and * for all singleton types p.s such that t <: p.s * there exists a singleton type p'.s in ts such that * t <: p'.s <: 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 + -
显示快捷键?