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