symbols.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 1,613 行 · 第 1/4 页
SCALA
1,613 行
/* NSC -- new Scala compiler * Copyright 2005-2008 LAMP/EPFL * @author Martin Odersky */// $Id: Symbols.scala 14561 2008-04-09 09:57:10Z odersky $package scala.tools.nsc.symtabimport scala.collection.mutable.ListBufferimport scala.tools.nsc.io.AbstractFileimport scala.tools.nsc.util.{Position, NoPosition, BatchSourceFile}import Flags._//todo: get rid of MONOMORPHIC flagtrait Symbols { self: SymbolTable => import definitions._ private var ids = 0 //for statistics: def symbolCount = ids var typeSymbolCount = 0 var classSymbolCount = 0 val emptySymbolArray = new Array[Symbol](0) val emptySymbolSet = Set.empty[Symbol]/* type Position; def NoPos : Position; def FirstPos : Position; implicit def coercePosToInt(pos : Position) : Int; def coerceIntToPos(pos : Int) : Position; object RequiresIntsAsPositions { implicit def coerceIntToPos0(pos: Int) = coerceIntToPos(pos) } */ /** The class for all symbols */ abstract class Symbol(initOwner: Symbol, initPos: Position, initName: Name) { var rawowner = initOwner var rawname = initName var rawflags: Long = 0 private var rawpos = initPos val id = { ids += 1; ids }// assert(id != 5413, initName+"/"+initOwner) var validTo: Period = NoPeriod def pos = rawpos def setPos(pos: Position): this.type = { this.rawpos = pos; this } def namePos(source: BatchSourceFile) = { val pos: Int = this.pos.offset.getOrElse(-1) val buf = source.content if (pos == -1) -1 else if (isTypeParameter) pos - name.length else if (isVariable || isMethod || isClass || isModule) { var ret = pos if (buf(pos) == ',') ret += 1 else if (isClass) ret += "class".length() else if (isModule) ret += "object".length() else ret += "var".length() while (buf(ret).isWhitespace) ret += 1 ret } else if (isValue) { if (pos < (buf.length + ("val ").length())) { if ((buf(pos + 0) == 'v') && (buf(pos + 1) == 'a') && (buf(pos + 2) == 'l') && (buf(pos + 3) == ' ')) { var pos0 = pos + 4 while (pos0 < buf.length && buf(pos0).isWhitespace) pos0 += 1 pos0 } else pos } else pos } else -1 } var attributes: List[AnnotationInfo] = List() def setAttributes(attrs: List[AnnotationInfo]): this.type = { this.attributes = attrs; this } /** Does this symbol have an attribute of the given class? */ def hasAttribute(cls: Symbol): Boolean = attributes.exists { case AnnotationInfo(tp, _, _) if tp.typeSymbol == cls => true case _ => false } var privateWithin: Symbol = _// Creators ------------------------------------------------------------------- final def newValue(pos: Position, name: Name) = new TermSymbol(this, pos, name) final def newVariable(pos: Position, name: Name) = newValue(pos, name).setFlag(MUTABLE) final def newValueParameter(pos: Position, name: Name) = newValue(pos, name).setFlag(PARAM) final def newLocalDummy(pos: Position) = newValue(pos, nme.LOCAL(this)).setInfo(NoType) final def newMethod(pos: Position, name: Name) = newValue(pos, name).setFlag(METHOD) final def newLabel(pos: Position, name: Name) = newMethod(pos, name).setFlag(LABEL) final def newConstructor(pos: Position) = newMethod(pos, nme.CONSTRUCTOR) final def newModule(pos: Position, name: Name, clazz: ClassSymbol) = new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL) .setModuleClass(clazz) final def newModule(pos: Position, name: Name) = { val m = new ModuleSymbol(this, pos, name).setFlag(MODULE | FINAL) m.setModuleClass(new ModuleClassSymbol(m)) } final def newPackage(pos: Position, name: Name) = { assert(name == nme.ROOT || isPackageClass) val m = newModule(pos, name).setFlag(JAVA | PACKAGE) m.moduleClass.setFlag(JAVA | PACKAGE) m } final def newThisSym(pos: Position) = newValue(pos, nme.this_).setFlag(SYNTHETIC) final def newImport(pos: Position) = newValue(pos, nme.IMPORT) final def newOverloaded(pre: Type, alternatives: List[Symbol]): Symbol = newValue(alternatives.head.pos, alternatives.head.name) .setFlag(OVERLOADED) .setInfo(OverloadedType(pre, alternatives)) final def newOuterAccessor(pos: Position) = { val sym = newMethod(pos, nme.OUTER) sym setFlag (STABLE | SYNTHETIC) if (isTrait) sym setFlag DEFERRED sym.expandName(this) sym.referenced = this sym } final def newErrorValue(name: Name) = newValue(pos, name).setFlag(SYNTHETIC | IS_ERROR).setInfo(ErrorType) final def newAliasType(pos: Position, name: Name) = new TypeSymbol(this, pos, name) final def newAbstractType(pos: Position, name: Name) = new TypeSymbol(this, pos, name).setFlag(DEFERRED) final def newTypeParameter(pos: Position, name: Name) = newAbstractType(pos, name).setFlag(PARAM) final def newTypeSkolem: Symbol = new TypeSkolem(owner, pos, name, this) .setFlag(flags) final def newClass(pos: Position, name: Name) = new ClassSymbol(this, pos, name) final def newModuleClass(pos: Position, name: Name) = new ModuleClassSymbol(this, pos, name) final def newAnonymousClass(pos: Position) = newClass(pos, nme.ANON_CLASS_NAME.toTypeName) final def newAnonymousFunctionClass(pos: Position) = { val anonfun = newClass(pos, nme.ANON_FUN_NAME.toTypeName) anonfun.attributes = AnnotationInfo(definitions.SerializableAttr.tpe, List(), List()) :: anonfun.attributes anonfun } final def newRefinementClass(pos: Position) = newClass(pos, nme.REFINE_CLASS_NAME.toTypeName) final def newErrorClass(name: Name) = { val clazz = newClass(pos, name).setFlag(SYNTHETIC | IS_ERROR) clazz.setInfo(ClassInfoType(List(), new ErrorScope(this), clazz)) clazz } final def newErrorSymbol(name: Name): Symbol = if (name.isTypeName) newErrorClass(name) else newErrorValue(name)// Tests ---------------------------------------------------------------------- def isTerm = false //to be overridden def isType = false //to be overridden def isClass = false //to be overridden def isTypeMember = false //to be overridden def isAliasType = false //to be overridden def isAbstractType = false //to be overridden def isSkolem = false //to be overridden final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA)) final def isVariable = isTerm && hasFlag(MUTABLE) && !isMethod final def isCapturedVariable = isVariable && hasFlag(CAPTURED) final def isGetter = isTerm && hasFlag(ACCESSOR) && !nme.isSetterName(name) final def isSetter = isTerm && hasFlag(ACCESSOR) && nme.isSetterName(name) //todo: make independent of name, as this can be forged. final def hasGetter = isTerm && nme.isLocalName(name) final def isValueParameter = isTerm && hasFlag(PARAM) final def isLocalDummy = isTerm && nme.isLocalDummyName(name) final def isMethod = isTerm && hasFlag(METHOD) final def isSourceMethod = isTerm && (flags & (METHOD | STABLE)) == METHOD final def isLabel = isTerm && hasFlag(LABEL) final def isClassConstructor = isTerm && (name == nme.CONSTRUCTOR) final def isMixinConstructor = isTerm && (name == nme.MIXIN_CONSTRUCTOR) final def isConstructor = isTerm && (name == nme.CONSTRUCTOR) || (name == nme.MIXIN_CONSTRUCTOR) final def isModule = isTerm && hasFlag(MODULE) final def isStaticModule = isModule && isStatic && !isMethod final def isPackage = isModule && hasFlag(PACKAGE) final def isThisSym = isTerm && owner.thisSym == this //final def isMonomorphicType = isType && hasFlag(MONOMORPHIC) final def isError = hasFlag(IS_ERROR) final def isErroneous = isError || isInitialized && tpe.isErroneous final def isTrait = isClass & hasFlag(TRAIT) final def isTypeParameterOrSkolem = isType && hasFlag(PARAM) final def isTypeSkolem = isSkolem && hasFlag(PARAM) final def isTypeParameter = isTypeParameterOrSkolem && !isSkolem final def isExistential = isType && hasFlag(EXISTENTIAL) final def isExistentialSkolem = isSkolem && hasFlag(EXISTENTIAL) final def isExistentialQuantified = isExistential && !isSkolem final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR) final def isAnonymousClass = isClass && (originalName startsWith nme.ANON_CLASS_NAME) // startsWith necessary because name may grow when lifted and also because of anonymous function classes def isAnonymousFunction = hasFlag(SYNTHETIC) && (originalName startsWith nme.ANON_FUN_NAME) final def isRefinementClass = isClass && name == nme.REFINE_CLASS_NAME.toTypeName; // no lifting for refinement classes final def isModuleClass = isClass && hasFlag(MODULE) final def isPackageClass = isClass && hasFlag(PACKAGE) final def isRoot = isPackageClass && name == nme.ROOT.toTypeName final def isRootPackage = isPackage && name == nme.ROOTPKG final def isEmptyPackage = isPackage && name == nme.EMPTY_PACKAGE_NAME final def isEmptyPackageClass = isPackageClass && name == nme.EMPTY_PACKAGE_NAME.toTypeName final def isPredefModule = isModule && name == nme.Predef // not printed as a prefix final def isScalaPackage = isPackage && name == nme.scala_ // not printed as a prefix final def isScalaPackageClass = isPackageClass && name == nme.scala_.toTypeName // not printed as a prefix /** Is symbol a monomophic type? * assumption: if a type starts out as monomorphic, it will not acquire * type parameters in later phases. */ final def isMonomorphicType = isType && { var is = infos (is eq null) || { while (is.prev ne null) { is = is.prev } is.info.isComplete && is.info.typeParams.isEmpty } } def isDeprecated = attributes exists (attr => attr.atp.typeSymbol == DeprecatedAttr) /** Does this symbol denote a wrapper object of the interpreter or its class? */ final def isInterpreterWrapper = (isModule || isModuleClass) && owner.isEmptyPackageClass && name.toString.startsWith(nme.INTERPRETER_LINE_PREFIX) && name.toString.endsWith(nme.INTERPRETER_WRAPPER_SUFFIX) /** Does this symbol denote a stable value? */ final def isStable = isTerm && !hasFlag(MUTABLE) && (!hasFlag(METHOD | BYNAMEPARAM) || hasFlag(STABLE)) def isDeferred = hasFlag(DEFERRED) && !isClass def isVirtualClass = hasFlag(DEFERRED) && isClass def isVirtualSubClass = info.baseClasses exists (_.isVirtualClass) /** Is this symbol a public */ final def isPublic: Boolean = !hasFlag(PRIVATE | PROTECTED) && privateWithin == NoSymbol /** Is this symbol a private local */ final def isPrivateLocal = hasFlag(PRIVATE) && hasFlag(LOCAL) /** Is this symbol a protected local */ final def isProtectedLocal = hasFlag(PROTECTED) && hasFlag(LOCAL) /** Does this symbol denote the primary constructor of its enclosing class? */ final def isPrimaryConstructor = isConstructor && owner.primaryConstructor == this /** Is this symbol a synthetic apply or unapply method in a companion object of a case class? */ final def isCaseApplyOrUnapply = isMethod && hasFlag(CASE) && hasFlag(SYNTHETIC) /** Is this symbol an implementation class for a mixin? */ final def isImplClass: Boolean = isClass && hasFlag(IMPLCLASS) /** Is thhis symbol early initialized */ final def isEarly: Boolean = isTerm && hasFlag(PRESUPER) /** Is this symbol a trait which needs an implementation class? */ final def needsImplClass: Boolean = isTrait && (!hasFlag(INTERFACE) || hasFlag(lateINTERFACE)) && !isImplClass /** Is this a symbol which exists only in the implementation class, not in its trait? */ final def isImplOnly: Boolean = hasFlag(PRIVATE) || (owner.isImplClass || owner.isTrait) && ((hasFlag(notPRIVATE | LIFTED) && !hasFlag(ACCESSOR | SUPERACCESSOR | MODULE) || isConstructor) || (hasFlag(LIFTED) && isModule && isMethod)) /** Is this symbol a module variable ? */ final def isModuleVar: Boolean = isVariable && hasFlag(MODULEVAR) /** Is this symbol static (i.e. with no outer instance)? */ final def isStatic: Boolean = hasFlag(STATIC) || isRoot || owner.isStaticOwner /** Does this symbol denote a class that defines static symbols? */ final def isStaticOwner: Boolean = isPackageClass || isModuleClass && isStatic /** Is this symbol final?*/ final def isFinal: Boolean = ( hasFlag(FINAL) || isTerm && ( hasFlag(PRIVATE) || isLocal || owner.isClass && owner.hasFlag(FINAL | MODULE)) ) /** Is this symbol a sealed class?*/ final def isSealed: Boolean = isClass && (hasFlag(SEALED) || isUnboxedClass(this)) /** Is this symbol locally defined? I.e. not accessed from outside `this' instance */ final def isLocal: Boolean = owner.isTerm /** Is this symbol a constant? */ final def isConstant: Boolean = isStable && (tpe match { case ConstantType(_) => true case PolyType(_, ConstantType(_)) => true case MethodType(_, ConstantType(_)) => true case _ => false }) /** Is this class nested in another class or module (not a package)? */ final def isNestedClass: Boolean = isClass && !isRoot && !owner.isPackageClass /** Is this class locally defined? * A class is local, if * - it is anonymous, or * - its owner is a value * - it is defined within a local class */ final def isLocalClass: Boolean = isClass && (isAnonymousClass || isRefinementClass || isLocal || !owner.isPackageClass && owner.isLocalClass) /** A a member of class `base' is incomplete if * (1) it is declared deferred or * (2) it is abstract override and its super symbol in `base' is * nonexistent or inclomplete. * * @param base ... * @return ... */ final def isIncompleteIn(base: Symbol): Boolean = this.isDeferred || (this hasFlag ABSOVERRIDE) && { val supersym = superSymbol(base) supersym == NoSymbol || supersym.isIncompleteIn(base) } final def exists: Boolean = this != NoSymbol && (!owner.isPackageClass || { rawInfo.load(this); rawInfo != NoType }) final def isInitialized: Boolean = validTo != NoPeriod final def isStableClass: Boolean = { def hasNoAbstractTypeMember(clazz: Symbol): Boolean = (clazz hasFlag STABLE) || { var e = clazz.info.decls.elems while ((e ne null) && !(e.sym.isAbstractType && info.member(e.sym.name) == e.sym)) e = e.next e == null } def checkStable() = (info.baseClasses forall hasNoAbstractTypeMember) && { setFlag(STABLE); true } isClass && (hasFlag(STABLE) || checkStable()) } final def isCovariant: Boolean = isType && hasFlag(COVARIANT) final def isContravariant: Boolean = isType && hasFlag(CONTRAVARIANT) /** The variance of this symbol as an integer */ final def variance: Int = if (isCovariant) 1 else if (isContravariant) -1 else 0// Flags, owner, and name attributes -------------------------------------------------------------- def owner: Symbol = rawowner final def owner_=(owner: Symbol) { rawowner = owner } def ownerChain: List[Symbol] = this :: owner.ownerChain
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?