symbols.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 1,613 行 · 第 1/4 页
SCALA
1,613 行
*/ def thisType: Type = NoPrefix /** Return every accessor of a primary constructor parameter in this case class */ final def caseFieldAccessors: List[Symbol] = info.decls.toList filter (sym => !(sym hasFlag PRIVATE) && sym.hasFlag(CASEACCESSOR)) final def constrParamAccessors: List[Symbol] = info.decls.toList filter (sym => !sym.isMethod && sym.hasFlag(PARAMACCESSOR)) /** The symbol accessed by this accessor function. */ final def accessed: Symbol = { assert(hasFlag(ACCESSOR)) owner.info.decl(nme.getterToLocal(if (isSetter) nme.setterToGetter(name) else name)) } /** The implementation class of a trait */ final def implClass: Symbol = owner.info.decl(nme.implClassName(name)) /** The class that is logically an outer class of given `clazz'. * This is the enclosing class, except for classes defined locally to constructors, * where it is the outer class of the enclosing class */ final def outerClass: Symbol = if (owner.isClass) owner else if (isClassLocalToConstructor) owner.enclClass.outerClass else owner.outerClass /** For a paramaccessor: a superclass paramaccessor for which this symbol * is an alias, NoSymbol for all others */ def alias: Symbol = NoSymbol /** For a lazy value, it's lazy accessor. NoSymbol for all others */ def lazyAccessor: Symbol = NoSymbol /** For an outer accessor: The class from which the outer originates. * For all other symbols: NoSymbol */ def outerSource: Symbol = NoSymbol /** The superclass of this class */ def superClass: Symbol = if (info.parents.isEmpty) NoSymbol else info.parents.head.typeSymbol /** The directly or indirectly inherited mixins of this class * except for mixin classes inherited by the superclass. Mixin classes appear * in linearlization order. */ def mixinClasses: List[Symbol] = { val sc = superClass info.baseClasses.tail.takeWhile(sc ne) } /** The package containing this symbol, or NoSymbol if there * is not one. */ def enclosingPackage: Symbol = if (this == NoSymbol) this else { var packSym = this.owner while ((packSym != NoSymbol) && !packSym.isPackageClass) packSym = packSym.owner if (packSym != NoSymbol) packSym = packSym.linkedModuleOfClass packSym } /** The top-level class containing this symbol */ def toplevelClass: Symbol = if (owner.isPackageClass) { if (isClass) this else moduleClass } else owner.toplevelClass /** Is this symbol defined in the same scope and compilation unit as `that' symbol? */ def isCoDefinedWith(that: Symbol) = (this.rawInfo ne NoType) && { val res = !this.owner.isPackageClass || (this.sourceFile eq null) || (that.sourceFile eq null) || (this.sourceFile eq that.sourceFile) || (this.sourceFile == that.sourceFile) res } /** The class with the same name in the same package as this module or * case class factory */ final def linkedClassOfModule: Symbol = { if (this != NoSymbol) owner.info.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) else NoSymbol } /** The module or case class factory with the same name in the same * package as this class. */ final def linkedModuleOfClass: Symbol = if (this.isClass && !this.isAnonymousClass && !this.isRefinementClass) { owner.rawInfo.decl(name.toTermName).suchThat( sym => (sym hasFlag MODULE) && (sym isCoDefinedWith this)) } else NoSymbol /** For a module its linked class, for a class its linked module or case * factory otherwise. */ final def linkedSym: Symbol = if (isTerm) linkedClassOfModule else if (isClass) owner.info.decl(name.toTermName).suchThat(_ isCoDefinedWith this) else NoSymbol /** For a module class its linked class, for a plain class * the module class of its linked module. */ final def linkedClassOfClass: Symbol = if (isModuleClass) linkedClassOfModule else linkedModuleOfClass.moduleClass /** If this symbol is an implementation class, its interface, otherwise the symbol itself * The method follows two strategies to determine the interface. * - during or after erasure, it takes the last parent of the implementatation class * (which is always the interface, by convention) * - before erasure, it looks up the interface name in the scope of the owner of the class. * This only works for implementation classes owned by other classes or traits. */ final def toInterface: Symbol = if (isImplClass) { val result = if (phase.next.erasedTypes) { assert(!tpe.parents.isEmpty, this) tpe.parents.last.typeSymbol } else { owner.info.decl(nme.interfaceName(name)) } assert(result != NoSymbol, this) result } else this /** The module corresponding to this module class (note that this * is not updated when a module is cloned). */ def sourceModule: Symbol = NoSymbol /** The module class corresponding to this module. */ def moduleClass: Symbol = NoSymbol /** The non-private symbol whose type matches the type of this symbol * in in given class. * * @param ofclazz The class containing the symbol's definition * @param site The base type from which member types are computed */ final def matchingSymbol(ofclazz: Symbol, site: Type): Symbol = ofclazz.info.nonPrivateDecl(name).filter(sym => !sym.isTerm || (site.memberType(this) matches site.memberType(sym))) /** The non-private member of `site' whose type and name match the type of this symbol */ final def matchingSymbol(site: Type): Symbol = site.nonPrivateMember(name).filter(sym => !sym.isTerm || (site.memberType(this) matches site.memberType(sym))) /** The symbol overridden by this symbol in given class `ofclazz' */ final def overriddenSymbol(ofclazz: Symbol): Symbol = matchingSymbol(ofclazz, owner.thisType) /** The symbol overriding this symbol in given subclass `ofclazz' */ final def overridingSymbol(ofclazz: Symbol): Symbol = matchingSymbol(ofclazz, ofclazz.thisType) final def allOverriddenSymbols: List[Symbol] = if (owner.isClass && !owner.info.baseClasses.isEmpty) for { bc <- owner.info.baseClasses.tail val s = overriddenSymbol(bc) if s != NoSymbol } yield s else List() /** The symbol accessed by a super in the definition of this symbol when * seen from class `base'. This symbol is always concrete. * pre: `this.owner' is in the base class sequence of `base'. */ final def superSymbol(base: Symbol): Symbol = { var bcs = base.info.baseClasses.dropWhile(owner !=).tail var sym: Symbol = NoSymbol while (!bcs.isEmpty && sym == NoSymbol) { if (!bcs.head.isImplClass) sym = matchingSymbol(bcs.head, base.thisType).suchThat(!_.isDeferred) bcs = bcs.tail } sym } /** The getter of this value or setter definition in class `base', or NoSymbol if * none exists. */ final def getter(base: Symbol): Symbol = { val getterName = if (isSetter) nme.setterToGetter(name) else nme.getterName(name) base.info.decl(getterName) filter (_.hasFlag(ACCESSOR)) } /** The setter of this value or getter definition, or NoSymbol if none exists */ final def setter(base: Symbol): Symbol = base.info.decl(nme.getterToSetter(nme.getterName(name))) filter (_.hasFlag(ACCESSOR)) /** The case module corresponding to this case class * @pre case class is a member of some other class or package */ final def caseModule: Symbol = { var modname = name.toTermName if (privateWithin.isClass && !privateWithin.isModuleClass && !hasFlag(EXPANDEDNAME)) modname = privateWithin.expandedName(modname) initialize.owner.info.decl(modname).suchThat(_.isModule) } /** If this symbol is a type parameter skolem (not an existential skolem!) * its corresponding type parameter, otherwise this */ def deSkolemize: Symbol = this /** If this symbol is an existential skolem the location (a Tree or null) * where it was unpacked. Resulttype is AnyRef because trees are not visible here. */ def unpackLocation: AnyRef = null /** Remove private modifier from symbol `sym's definition. If `sym' is a * term symbol rename it by expanding its name to avoid name clashes */ final def makeNotPrivate(base: Symbol) { if (this hasFlag PRIVATE) { setFlag(notPRIVATE) if (isTerm && !isDeferred) setFlag(lateFINAL) if (!isStaticModule && !isClassConstructor) { expandName(base) if (isModule) moduleClass.makeNotPrivate(base) } } } /** change name by appending $$<fully-qualified-name-of-class `base'> * Do the same for any accessed symbols or setters/getters */ def expandName(base: Symbol) { if (this.isTerm && this != NoSymbol && !hasFlag(EXPANDEDNAME)) { setFlag(EXPANDEDNAME) if (hasFlag(ACCESSOR) && !isDeferred) { accessed.expandName(base) } else if (hasGetter) { getter(owner).expandName(base) setter(owner).expandName(base) } name = base.expandedName(name) if (isType) name = name.toTypeName } } /** The expanded name of `name' relative to this class as base */ def expandedName(name: Name): Name = { newTermName(fullNameString('$') + nme.EXPAND_SEPARATOR_STRING + name) } def sourceFile: AbstractFile = { var ret = (if (isModule) moduleClass else toplevelClass).sourceFile if (ret == null && inIDE && !isModule) this match { case sym : ModuleSymbol if sym.referenced != null => ret = sym.referenced.sourceFile case _ => } ret } def sourceFile_=(f: AbstractFile) { throw new Error("sourceFile_= inapplicable for " + this) } def isFromClassFile: Boolean = (if (isModule) moduleClass else toplevelClass).isFromClassFile /** If this is a sealed class, its known direct subclasses. Otherwise Set.empty */ def children: Set[Symbol] = emptySymbolSet /** Declare given subclass `sym' of this sealed class */ def addChild(sym: Symbol) { throw new Error("addChild inapplicable for " + this) } // ToString ------------------------------------------------------------------- /** A tag which (in the ideal case) uniquely identifies class symbols */ final def tag: Int = fullNameString.hashCode() /** The simple name of this Symbol */ final def simpleName: Name = name /** String representation of symbol's definition key word */ final def keyString: String = if (isTrait && hasFlag(JAVA)) "interface" else if (isTrait) "trait" else if (isClass) "class" else if (isType && !hasFlag(PARAM)) "type" else if (isVariable) "var" else if (isPackage) "package" else if (isModule) "object" else if (isMethod) "def" else if (isTerm && (!hasFlag(PARAM) || hasFlag(PARAMACCESSOR))) "val" else "" /** String representation of symbol's kind */ final def kindString: String = if (isPackageClass) if (settings.debug.value) "package class" else "package" else if (isModuleClass) if (settings.debug.value) "singleton class" else "object" else if (isAnonymousClass) "template" else if (isRefinementClass) "" else if (isTrait) "trait" else if (isClass) "class" else if (isType) "type" else if (isTerm && hasFlag(LAZY)) "lazy value" else if (isVariable) "variable" else if (isPackage) "package" else if (isModule) "object" else if (isClassConstructor) "constructor" else if (isSourceMethod) "method" else if (isTerm) "value" else "" /** String representation of symbol's simple name. * If !settings.debug translates expansions of operators back to operator symbol. * E.g. $eq => =. * If settings.uniquId adds id. */ def nameString: String = { var s = simpleName.decode if (s endsWith nme.LOCAL_SUFFIX) s = s.substring(0, s.length - nme.LOCAL_SUFFIX.length) if (s endsWith ".type") s = s.substring(0, s.length - ".type".length) s + idString } /** String representation of symbol's full name with <code>separator</code> * between class names. * Never translates expansions of operators back to operator symbol. * Never adds id. */ final def fullNameString(separator: Char): String = { assert(owner != NoSymbol, this) var str = if (owner.isRoot || owner.isEmptyPackageClass || owner.isInterpreterWrapper) simpleName.toString else owner.enclClass.fullNameString(separator) + separator + simpleName if (str.charAt(str.length - 1) == ' ') str = str.substring(0, str.length - 1) str } final def fullNameString: String = fullNameString('.') /** If settings.uniqid is set, the symbol's id, else "" */ final def idString: String = if (settings.uniqid.value) "#"+id else "" /** String representation, including symbol's kind * e.g., "class Foo", "method Bar". */ override def toString(): String = if (isValueParameter && owner.isSetter) "parameter of setter "+owner.nameString else compose(List(kindString, if (isClassConstructor) owner.simpleName.decode+idString else nameString)) /** String representation of location. */ final def locationString: String = if (owner.isClass && ((!owner.isAnonymousClass && !owner.isRefinementClass && !owner.isInterpreterWrapper && !owner.isRoot && !owner.isEmptyPackageClass) || settings.debug.value)) " in " + owner else "" /** String representation of symbol's definition following its name */ final def infoString(tp: Type): String = { def typeParamsString: String = tp match { case PolyType(tparams, _) if (tparams.length != 0) => (tparams map (_.defString)).mkString("[", ",", "]") case _ => "" } if (isClass) typeParamsString + " extends " + tp.resultType else if (isAliasType) typeParamsString + " = " + tp.resultType else if (isAbstractType) typeParamsString + { tp.resultType match { case TypeBounds(lo, hi) => (if (lo.typeSymbol == AllClass) "" else " >: " + lo) + (if (hi.typeSymbol == AnyClass) "" else " <: " + hi) case rtp => "<: " + rtp }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?