diff options
author | Paul Phillips <paulp@improving.org> | 2012-04-05 15:50:10 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-04-05 22:51:29 -0700 |
commit | 296b7061ccef8600c011140fa6fd64afec244ed0 (patch) | |
tree | 852bfad96dc8b980b18a7869640f4c400566baa5 /src/compiler/scala/reflect/internal/Symbols.scala | |
parent | 2b89c3459d1d9a9aa9dd5aba75847274d6f74129 (diff) | |
download | scala-296b7061ccef8600c011140fa6fd64afec244ed0.tar.gz scala-296b7061ccef8600c011140fa6fd64afec244ed0.tar.bz2 scala-296b7061ccef8600c011140fa6fd64afec244ed0.zip |
A boatload of work on Symbols and Flags.
Finally my dream of orderliness is within sight.
It's all pretty self-explanatory. More polymorphism, more immutable
identity, more invariants.
Diffstat (limited to 'src/compiler/scala/reflect/internal/Symbols.scala')
-rw-r--r-- | src/compiler/scala/reflect/internal/Symbols.scala | 852 |
1 files changed, 465 insertions, 387 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 5c43047046..cfab069588 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -55,11 +55,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ val originalOwner = perRunCaches.newMap[Symbol, Symbol]() - abstract class AbsSymbolImpl extends AbsSymbol { this: Symbol => - def newNestedSymbol(name: Name, pos: Position, newFlags: Long) = name match { + abstract class AbsSymbolImpl extends AbsSymbol { + this: Symbol => + + def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match { case n: TermName => newTermSymbol(n, pos, newFlags) - case n: TypeName => newTypeSymbol(n, pos, newFlags) + case n: TypeName => if (isClass) newClassSymbol(n, pos, newFlags) else newNonClassSymbol(n, pos, newFlags) } + def enclosingClass: Symbol = enclClass def enclosingMethod: Symbol = enclMethod def thisPrefix: Type = thisType @@ -79,6 +82,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => abstract class Symbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: Name) extends AbsSymbolImpl with HasFlags + with SymbolFlagLogic + with SymbolCreator + // with FlagVerifier with Annotatable[Symbol] { type FlagsType = Long @@ -87,13 +93,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => private[this] var _rawowner = initOwner // Syncnote: need not be protected, as only assignment happens in owner_=, which is not exposed to api private[this] var _rawname = initName - private[this] var _rawflags = 0L def rawowner = _rawowner def rawname = _rawname - def rawflags = _rawflags - - protected def rawflags_=(x: FlagsType) { _rawflags = x } private var rawpos = initPos @@ -135,7 +137,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def newLocalDummy(pos: Position) = newTermSymbol(nme.localDummyName(this), pos) setInfo NoType final def newMethod(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol = - newMethodSymbol(name, pos, METHOD | newFlags) + createMethodSymbol(name, pos, METHOD | newFlags) final def newLabel(name: TermName, pos: Position = NoPosition): MethodSymbol = newMethod(name, pos, LABEL) @@ -146,73 +148,39 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Static constructor with info set. */ def newStaticConstructor(pos: Position) = newConstructor(pos, STATIC) setInfo UnitClass.tpe + /** Instance constructor with info set. */ def newClassConstructor(pos: Position) = newConstructor(pos) setInfo MethodType(Nil, this.tpe) - // Top-level objects can be automatically marked final, but others - // must be explicitly marked final if overridable objects are enabled. - private def ModuleFlags = ( - if (isPackage || !settings.overrideObjects.value) MODULE | FINAL - else MODULE - ) def newLinkedModule(clazz: Symbol, newFlags: Long = 0L): ModuleSymbol = { - val m = newModuleSymbol(clazz.name.toTermName, clazz.pos, ModuleFlags | newFlags) + val m = newModuleSymbol(clazz.name.toTermName, clazz.pos, MODULE | newFlags) connectModuleToClass(m, clazz.asInstanceOf[ClassSymbol]) } final def newModule(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = { - val m = newModuleSymbol(name, pos, newFlags | ModuleFlags) - val clazz = newModuleClassSymbol(name.toTypeName, pos, (m getFlag ModuleToClassFlags) | MODULE) + val m = newModuleSymbol(name, pos, newFlags | MODULE) + val clazz = newModuleClass(name.toTypeName, pos, m getFlag ModuleToClassFlags) connectModuleToClass(m, clazz) } final def newPackage(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = { assert(name == nme.ROOT || isPackageClass, this) - newModule(name, pos, JAVA | PACKAGE | newFlags) + newModule(name, pos, PackageFlags | newFlags) } + final def newThisSym(pos: Position) = newTermSymbol(nme.this_, pos, SYNTHETIC) final def newImport(pos: Position) = newTermSymbol(nme.IMPORT, pos) - /** Direct symbol factories. - * For internal use; these are unlikely to be what you want. - */ - def newTermSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): TermSymbol = - new TermSymbol(this, pos, name) initFlags newFlags + final def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = + newTermSymbol(name, pos, newFlags).asInstanceOf[ModuleSymbol] - def newAbstractTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AbstractTypeSymbol = - new AbstractTypeSymbol(this, pos, name) initFlags newFlags + final def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol = + newClassSymbol(name, pos, newFlags).asInstanceOf[ModuleClassSymbol] - def newAliasTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): AliasTypeSymbol = - new AliasTypeSymbol(this, pos, name) initFlags newFlags - - def newModuleSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleSymbol = - new ModuleSymbol(this, pos, name) initFlags newFlags - - def newMethodSymbol(name: TermName, pos: Position = NoPosition, newFlags: Long = 0L): MethodSymbol = - new MethodSymbol(this, pos, name) initFlags newFlags - - def newClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = - new ClassSymbol(this, pos, name) initFlags newFlags - - def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ModuleClassSymbol = - new ModuleClassSymbol(this, pos, name) initFlags newFlags - - /** Derive whether it is an abstract type from the flags; after creation - * the DEFERRED flag will be ignored. - */ - def newTypeSymbol(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol = - if ((newFlags & DEFERRED) == 0L) - newAliasTypeSymbol(name, pos, newFlags) - else - newAbstractTypeSymbol(name, pos, newFlags) - - def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, newFlags: Long = 0L): TypeSkolem = - if ((newFlags & DEFERRED) == 0L) - new TypeSkolem(this, pos, name, origin) initFlags newFlags - else - new TypeSkolem(this, pos, name, origin) with AbstractTypeMixin initFlags newFlags + final def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, newFlags: Long = 0L): TypeSkolem = + createTypeSkolemSymbol(name, origin, pos, newFlags) /** @param pre type relative to which alternatives are seen. * for instance: @@ -243,18 +211,23 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Symbol of a type definition type T = ... */ final def newAliasType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = - newAliasTypeSymbol(name, pos, newFlags) + createAliasTypeSymbol(name, pos, newFlags) /** Symbol of an abstract type type T >: ... <: ... */ final def newAbstractType(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = - newAbstractTypeSymbol(name, pos, DEFERRED | newFlags) + createAbstractTypeSymbol(name, pos, DEFERRED | newFlags) /** Symbol of a type parameter */ final def newTypeParameter(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L) = newAbstractType(name, pos, PARAM | newFlags) + /** Symbol of an existential type T forSome { ... } + */ + final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = + newAbstractType(name, pos, EXISTENTIAL | newFlags) + /** Synthetic value parameters when parameter symbols are not available */ final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[Symbol]] = { @@ -280,10 +253,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => def newGADTSkolem(name: TypeName, origin: Symbol, info: Type): TypeSkolem = newTypeSkolemSymbol(name, origin, origin.pos, origin.flags & ~(EXISTENTIAL | PARAM) | CASEACCESSOR | SYNTHETIC) setInfo info - - final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): Symbol = - newAbstractType(name, pos, EXISTENTIAL | newFlags) - final def freshExistential(suffix: String): Symbol = newExistential(freshExistentialName(suffix), pos) @@ -318,8 +287,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def newErrorClass(name: TypeName) = newClassWithInfo(name, Nil, new ErrorScope(this), pos, SYNTHETIC | IS_ERROR) - final def newModuleClass(name: TypeName, pos: Position = NoPosition) = - newModuleClassSymbol(name, pos) + final def newModuleClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L) = + newModuleClassSymbol(name, pos, newFlags | MODULE) final def newAnonymousClass(pos: Position) = newClassSymbol(tpnme.ANON_CLASS_NAME, pos) @@ -333,8 +302,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Refinement types P { val x: String; type T <: Number } * also have symbols, they are refinementClasses */ - final def newRefinementClass(pos: Position) = - newClass(tpnme.REFINE_CLASS_NAME, pos) + final def newRefinementClass(pos: Position) = createRefinementClassSymbol(pos, 0L) /** Create a new getter for current symbol (which must be a field) */ @@ -410,7 +378,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => if ((rawflags & LOCKED) != 0L) { // activeLocks -= 1 // lockedSyms -= this - _rawflags = rawflags & ~LOCKED + rawflags &= ~LOCKED if (settings.Yrecursion.value != 0) recursionTable -= this } @@ -418,42 +386,84 @@ trait Symbols extends api.Symbols { self: SymbolTable => // ----- tests ---------------------------------------------------------------------- - def isTerm = false // to be overridden - def isType = false // to be overridden - def isClass = false // to be overridden - def isBottomClass = false // to be overridden - def isAliasType = false // to be overridden - def isAbstractType = false // to be overridden - private[scala] def isSkolem = false // to be overridden - - /** Is this symbol a type but not a class? */ - def isNonClassType = false // to be overridden - - override final def isTrait = isClass && hasFlag(TRAIT) - final def isAbstractClass = isClass && hasFlag(ABSTRACT) - final def isBridge = hasFlag(BRIDGE) - final def isContravariant = isType && hasFlag(CONTRAVARIANT) - final def isConcreteClass = isClass && !hasFlag(ABSTRACT | TRAIT) - final def isCovariant = isType && hasFlag(COVARIANT) - final def isEarlyInitialized = isTerm && hasFlag(PRESUPER) - final def isExistentiallyBound = isType && hasFlag(EXISTENTIAL) - final def isImplClass = isClass && hasFlag(IMPLCLASS) - final def isLazyAccessor = isLazy && lazyAccessor != NoSymbol - final def isMethod = isTerm && hasFlag(METHOD) - final def isModule = isTerm && hasFlag(MODULE) - final def isModuleClass = isClass && hasFlag(MODULE) - final def isNumericValueClass = definitions.isNumericValueClass(this) - final def isOverloaded = hasFlag(OVERLOADED) - final def isOverridableMember = !(isClass || isEffectivelyFinal) && owner.isClass - final def isRefinementClass = isClass && name == tpnme.REFINE_CLASS_NAME - final def isSourceMethod = isMethod && !hasFlag(STABLE) // exclude all accessors!!! - final def isTypeParameter = isType && isParameter && !isSkolem - final def isPrimitiveValueClass = definitions.isPrimitiveValueClass(this) - final def isVarargsMethod = isMethod && hasFlag(VARARGS) - - /** Package tests */ - final def isPackage = isModule && hasFlag(PACKAGE) - final def isPackageClass = isClass && hasFlag(PACKAGE) + /** All symbols are one of three categories: TermSymbol, TypeSymbol, or NoSymbol. + * There is only one NoSymbol. + */ + def isTerm = false + def isType = false + + /** TypeSymbols fall into four named direct subclasses: + * - ClassSymbol + * - AliasTypeSymbol + * - AbstractTypeSymbol + * - TypeSkolem + */ + def isClass = false + def isAliasType = false + def isAbstractType = false + def isSkolem = false + + /** A Type, but not a Class. */ + def isNonClassType = false + + /** The bottom classes are Nothing and Null, found in Definitions. */ + def isBottomClass = false + + /** These are all tests for varieties of ClassSymbol, which has these subclasses: + * - ModuleClassSymbol + * - RefinementClassSymbol + * - PackageClassSymbol (extends ModuleClassSymbol) + */ + def isAbstractClass = false + def isAnonOrRefinementClass = false + def isAnonymousClass = false + def isConcreteClass = false + def isImplClass = false // the implementation class of a trait + def isModuleClass = false + def isNumericValueClass = false + def isPrimitiveValueClass = false + def isRefinementClass = false + override def isTrait = false + + /** Qualities of Types, always false for TermSymbols. + */ + def isContravariant = false + def isCovariant = false + def isExistentialSkolem = false + def isExistentiallyBound = false + def isExistentialQuantified = false + def isGADTSkolem = false + def isTypeParameter = false + def isTypeParameterOrSkolem = false + def isTypeSkolem = false + + /** Qualities of Terms, always false for TypeSymbols. + */ + override def hasDefault = false + def isBridge = false + def isEarlyInitialized = false + def isModule = false + def isOverloaded = false + def isValueParameter = false + + /** Qualities of MethodSymbols, always false for TypeSymbols + * and other TermSymbols. + */ + def isCaseAccessorMethod = false + def isLiftedMethod = false + def isMacro = false + def isMethod = false + def isSourceMethod = false + def isVarargsMethod = false + + /** Package/package object tests */ + def isPackage = false + def isPackageClass = false + def isPackageObject = false + def isPackageObjectClass = false + + def isPackageObjectOrClass = isPackageObject || isPackageObjectClass + def isModuleOrModuleClass = isModule || isModuleClass /** Overridden in custom objects in Definitions */ def isRoot = false @@ -466,22 +476,30 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def isEffectiveRoot = false - /** For RootClass, EmptyPackageClass. For all other symbols, itself. + /** For RootClass, this is EmptyPackageClass. For all other symbols, + * the symbol itself. */ def ownerOfNewSymbols = this + final def isLazyAccessor = isLazy && lazyAccessor != NoSymbol + final def isOverridableMember = !(isClass || isEffectivelyFinal) && owner.isClass + /** Does this symbol denote a wrapper created by the repl? */ final def isInterpreterWrapper = ( - (isModule || isModuleClass) + (this hasFlag MODULE) && owner.isPackageClass && nme.isReplWrapperName(name) ) + @inline final override def getFlag(mask: Long): Long = flags & mask + /** Does symbol have ANY flag in `mask` set? */ + @inline final override def hasFlag(mask: Long): Boolean = (flags & mask) != 0 + /** Does symbol have ALL the flags in `mask` set? */ + @inline final override def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask /** Term symbols with the exception of static parts of Java classes and packages. */ - final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA)) - - final def isVariable = isTerm && isMutable && !isMethod + final def isValue = isTerm && !(isModule && hasFlag(PACKAGE | JAVA)) + final def isVariable = isTerm && isMutable && !isMethod // interesting only for lambda lift. Captured variables are accessed from inner lambdas. final def isCapturedVariable = isVariable && hasFlag(CAPTURED) @@ -493,9 +511,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def hasGetter = isTerm && nme.isLocalName(name) - final def isValueParameter = isTerm && hasFlag(PARAM) - final def isLocalDummy = isTerm && nme.isLocalDummyName(name) final def isInitializedToDefault = !isType && hasAllFlags(DEFAULTINIT | ACCESSOR) + final def isLocalDummy = isTerm && nme.isLocalDummyName(name) final def isClassConstructor = isTerm && (name == nme.CONSTRUCTOR) final def isMixinConstructor = isTerm && (name == nme.MIXIN_CONSTRUCTOR) final def isConstructor = isTerm && nme.isConstructorName(name) @@ -503,17 +520,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isThisSym = isTerm && owner.thisSym == this final def isError = hasFlag(IS_ERROR) final def isErroneous = isError || isInitialized && tpe.isErroneous - final def isTypeParameterOrSkolem = isType && hasFlag(PARAM) - final def isHigherOrderTypeParameter = (this ne NoSymbol) && owner.isTypeParameterOrSkolem - final def isTypeSkolem = isSkolem && hasFlag(PARAM) - // a type symbol bound by an existential type, for instance the T in - // List[T] forSome { type T } - final def isExistentialSkolem = isExistentiallyBound && isSkolem - final def isExistentialQuantified = isExistentiallyBound && !isSkolem - final def isGADTSkolem = isSkolem && hasFlag(CASEACCESSOR | SYNTHETIC) + + def isHigherOrderTypeParameter = owner.isTypeParameterOrSkolem // class C extends D( { class E { ... } ... } ). Here, E is a class local to a constructor - final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR) + def isClassLocalToConstructor = false final def isDerivedValueClass = isClass && info.firstParent.typeSymbol == AnyValClass && !isPrimitiveValueClass @@ -521,29 +532,27 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isMethodWithExtension = isMethod && owner.isDerivedValueClass && !isParamAccessor && !isConstructor && !hasFlag(SUPERACCESSOR) - final def isAnonymousClass = isClass && (name containsName tpnme.ANON_CLASS_NAME) - final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME) - final def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass - - // A package object or its module class - final def isPackageObjectOrClass = (this ne NoSymbol) && owner.isPackageClass && (name == nme.PACKAGE || name == tpnme.PACKAGE) - final def isPackageObject = (this ne NoSymbol) && owner.isPackageClass && name == nme.PACKAGE - final def isPackageObjectClass = (this ne NoSymbol) && owner.isPackageClass && name == tpnme.PACKAGE - + final def isAnonymousFunction = isSynthetic && (name containsName tpnme.ANON_FUN_NAME) final def isDefinedInPackage = effectiveOwner.isPackageClass - final def isJavaInterface = isJavaDefined && isTrait - final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass + final def isJavaInterface = isJavaDefined && isTrait + final def needsFlatClasses = phase.flatClasses && rawowner != NoSymbol && !rawowner.isPackageClass + + /** change name by appending $$<fully-qualified-name-of-class `base`> + * Do the same for any accessed symbols or setters/getters. + * Implementation in TermSymbol. + */ + def expandName(base: Symbol) { } // In java.lang, Predef, or scala package/package object def isInDefaultNamespace = UnqualifiedOwners(effectiveOwner) /** The owner, skipping package objects. */ - def effectiveOwner = if (owner.isPackageObjectClass) owner.skipPackageObject else owner + def effectiveOwner = owner.skipPackageObject /** If this is a package object or its implementing class, its owner: otherwise this. */ - final def skipPackageObject: Symbol = if (isPackageObjectOrClass) owner else this + def skipPackageObject: Symbol = if (this.isPackageObjectOrClass) owner else this /** If this is a constructor, its owner: otherwise this. */ @@ -622,15 +631,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => // def isVirtualClass = hasFlag(DEFERRED) && isClass // def isVirtualTrait = hasFlag(DEFERRED) && isTrait - def isLiftedMethod = isMethod && hasFlag(LIFTED) + // def isLiftedMethod = hasAllFlags(METHOD | LIFTED) def isCaseClass = isClass && isCase - // unfortunately having the CASEACCESSOR flag does not actually mean you - // are a case accessor (you can also be a field.) - def isCaseAccessorMethod = isMethod && isCaseAccessor - - def isMacro = isMethod && hasFlag(MACRO) - /** Does this symbol denote the primary constructor of its enclosing class? */ final def isPrimaryConstructor = isConstructor && owner.primaryConstructor == this @@ -675,10 +678,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isStaticOwner: Boolean = isPackageClass || isModuleClass && isStatic + def isTopLevelModule = hasFlag(MODULE) && owner.isPackageClass + /** Is this symbol effectively final? I.e, it cannot be overridden */ final def isEffectivelyFinal: Boolean = ( - isFinal - || hasModuleFlag && !settings.overrideObjects.value + (this hasFlag FINAL | PACKAGE) + || isModuleOrModuleClass && (owner.isPackageClass || !settings.overrideObjects.value) || isTerm && ( isPrivate || isLocal @@ -693,7 +698,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isConstant: Boolean = isStable && isConstantType(tpe.resultType) /** Is this class nested in another class or module (not a package)? */ - def isNestedClass = isClass && !owner.isPackageClass + def isNestedClass = false /** Is this class locally defined? * A class is local, if @@ -701,9 +706,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => * - its owner is a value * - it is defined within a local class */ - final def isLocalClass: Boolean = - isClass && (isAnonOrRefinementClass || isLocal || - !owner.isPackageClass && owner.isLocalClass) + def isLocalClass = false + + def isStableClass = false /* code for fixing nested objects override final def isModuleClass: Boolean = @@ -738,26 +743,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => // Does not always work if the rawInfo is a SourcefileLoader, see comment // in "def coreClassesFirst" in Global. - final def exists: Boolean = - this != NoSymbol && (!owner.isPackageClass || { rawInfo.load(this); rawInfo != NoType }) + def exists = !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()) - } - - /** The variance of this symbol as an integer */ final def variance: Int = if (isCovariant) 1 @@ -788,6 +778,10 @@ trait Symbols extends api.Symbols { self: SymbolTable => // ------ owner attribute -------------------------------------------------------------- def owner: Symbol = rawowner + // TODO - don't allow the owner to be changed without checking invariants, at least + // when under some flag. Define per-phase invariants for owner/owned relationships, + // e.g. after flatten all classes are owned by package classes, there are lots and + // lots of these to be declared (or more realistically, discovered.) def owner_=(owner: Symbol) { // don't keep the original owner in presentation compiler runs // (the map will grow indefinitely, and the only use case is the @@ -805,11 +799,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => def ownerChain: List[Symbol] = this :: owner.ownerChain def originalOwnerChain: List[Symbol] = this :: originalOwner.getOrElse(this, rawowner).originalOwnerChain - def enclClassChain: List[Symbol] = { - if ((this eq NoSymbol) || isPackageClass) Nil - else if (isClass) this :: owner.enclClassChain - else owner.enclClassChain - } + // Non-classes skip self and return rest of owner chain; overridden in ClassSymbol. + def enclClassChain: List[Symbol] = owner.enclClassChain def ownersIterator: Iterator[Symbol] = new Iterator[Symbol] { private var current = Symbol.this @@ -817,21 +808,21 @@ trait Symbols extends api.Symbols { self: SymbolTable => def next = { val r = current; current = current.owner; r } } - /** same as ownerChain contains sym, but more efficient, and - * with a twist for refinement classes. A refinement class - * has a transowner X if an of its parents has transowner X. + /** Same as `ownerChain contains sym` but more efficient, and + * with a twist for refinement classes (see RefinementClassSymbol.) */ def hasTransOwner(sym: Symbol): Boolean = { var o = this while ((o ne sym) && (o ne NoSymbol)) o = o.owner - (o eq sym) || - isRefinementClass && (info.parents exists (_.typeSymbol.hasTransOwner(sym))) + (o eq sym) } // ------ name attribute -------------------------------------------------------------- def name: Name = rawname + // TODO - don't allow names to be renamed in this unstructured a fashion. + // Rename as little as possible. Enforce invariants on all renames. def name_=(name: Name) { if (name != rawname) { if (owner.isClass) { @@ -903,43 +894,50 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ final def fullName: String = fullName('.') -// ------ flags attribute -------------------------------------------------------------- + /** + * Symbol creation implementations. + */ + protected def createTypeSymbol(name: TypeName, pos: Position, newFlags: Long): TypeSymbol = + new TypeSymbol(this, pos, name) { } initFlags newFlags - final def flags: Long = { - val fs = rawflags & phase.flagMask - (fs | ((fs & LateFlags) >>> LateShift)) & ~(fs >>> AntiShift) - } - def flags_=(fs: Long) = _rawflags = fs + protected def createAbstractTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AbstractTypeSymbol = + new AbstractTypeSymbol(this, pos, name) initFlags newFlags - /** Set the symbol's flags to the given value, asserting - * that the previous value was 0. - */ - def initFlags(mask: Long): this.type = { - assert(rawflags == 0L, this) - _rawflags = mask - this - } - def setFlag(mask: Long): this.type = { _rawflags = rawflags | mask ; this } - def resetFlag(mask: Long): this.type = { _rawflags = rawflags & ~mask ; this } - final def getFlag(mask: Long): Long = flags & mask - final def resetFlags() { _rawflags = rawflags & TopLevelCreationFlags } + protected def createAliasTypeSymbol(name: TypeName, pos: Position, newFlags: Long): AliasTypeSymbol = + new AliasTypeSymbol(this, pos, name) initFlags newFlags - /** Does symbol have ANY flag in `mask` set? */ - final def hasFlag(mask: Long): Boolean = (flags & mask) != 0L + protected def createTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position, newFlags: Long): TypeSkolem = + new TypeSkolem(this, pos, name, origin) initFlags newFlags - /** Does symbol have ALL the flags in `mask` set? */ - final def hasAllFlags(mask: Long): Boolean = (flags & mask) == mask + protected def createClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol = + new ClassSymbol(this, pos, name) initFlags newFlags - /** If the given flag is set on this symbol, also set the corresponding - * notFLAG. For instance if flag is PRIVATE, the notPRIVATE flag will - * be set if PRIVATE is currently set. - */ - final def setNotFlag(flag: Int) = if (hasFlag(flag)) setFlag((flag: @annotation.switch) match { - case PRIVATE => notPRIVATE - case PROTECTED => notPROTECTED - case OVERRIDE => notOVERRIDE - case _ => abort("setNotFlag on invalid flag: " + flag) - }) + protected def createModuleClassSymbol(name: TypeName, pos: Position, newFlags: Long): ModuleClassSymbol = + new ModuleClassSymbol(this, pos, name) initFlags newFlags + + protected def createPackageClassSymbol(name: TypeName, pos: Position, newFlags: Long): PackageClassSymbol = + new PackageClassSymbol(this, pos, name) initFlags newFlags + + protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol = + new RefinementClassSymbol(this, pos) initFlags newFlags + + protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol = + new TermSymbol(this, pos, name) initFlags newFlags + + protected def createMethodSymbol(name: TermName, pos: Position, newFlags: Long): MethodSymbol = + new MethodSymbol(this, pos, name) initFlags newFlags + + protected def createModuleSymbol(name: TermName, pos: Position, newFlags: Long): ModuleSymbol = + new ModuleSymbol(this, pos, name) initFlags newFlags + + protected def createPackageSymbol(name: TermName, pos: Position, newFlags: Long): PackageSymbol = + new PackageSymbol(this, pos, name) initFlags newFlags + + protected def createValueParameterSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol = + new TermSymbol(this, pos, name) initFlags newFlags + + protected def createValueMemberSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol = + new TermSymbol(this, pos, name) initFlags newFlags /** The class or term up to which this symbol is accessible, * or RootClass if it is public. As java protected statics are @@ -1008,7 +1006,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => throw CyclicReference(this, tp) } } else { - _rawflags |= LOCKED + rawflags |= LOCKED // activeLocks += 1 // lockedSyms += this } @@ -1200,9 +1198,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => var ph = phase while (ph.prev.keepsTypeParams) ph = ph.prev - // - // if (ph ne phase) - // debuglog("checking unsafeTypeParams(" + this + ") at: " + phase + " reading at: " + ph) ph } @@ -1234,7 +1229,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** The value parameter sections of this symbol. */ def paramss: List[List[Symbol]] = info.paramss - def hasParamWhich(cond: Symbol => Boolean) = paramss exists (_ exists cond) + def hasParamWhich(cond: Symbol => Boolean) = mexists(paramss)(cond) /** The least proper supertype of a class; includes all parent types * and refinement where needed. You need to compute that in a situation like this: @@ -1432,7 +1427,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** Internal method to clone a symbol's implementation with the given flags and no info. */ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol - def cloneSymbolImpl(owner: Symbol): Symbol = cloneSymbolImpl(owner, 0L) // ------ access to related symbols -------------------------------------------------- @@ -1443,14 +1437,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def enclMethod: Symbol = if (isSourceMethod) this else owner.enclMethod /** The primary constructor of a class. */ - def primaryConstructor: Symbol = { - var c = info.decl( - if (isTrait || isImplClass) nme.MIXIN_CONSTRUCTOR - else nme.CONSTRUCTOR) - c = if (c hasFlag OVERLOADED) c.alternatives.head else c - //assert(c != NoSymbol) - c - } + def primaryConstructor: Symbol = NoSymbol /** The self symbol (a TermSymbol) of a class with explicit self type, or else the * symbol itself (a TypeSymbol). @@ -1507,6 +1494,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => * is not updated when a module is cloned), or NoSymbol if this is not a ModuleClass. */ def sourceModule: Symbol = NoSymbol + // if (isModuleClass) companionModule else NoSymbol + // NoSymbol /** The implementation class of a trait. If available it will be the * symbol with the same owner, and the name of this symbol with $class @@ -1560,13 +1549,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** The package class containing this symbol, or NoSymbol if there * is not one. */ - def enclosingPackageClass: Symbol = - if (this == NoSymbol) this else { - var packSym = this.owner - while (packSym != NoSymbol && !packSym.isPackageClass) - packSym = packSym.owner - packSym - } + def enclosingPackageClass: Symbol = { + var packSym = this.owner + while (packSym != NoSymbol && !packSym.isPackageClass) + packSym = packSym.owner + packSym + } /** The package containing this symbol, or NoSymbol if there * is not one. */ @@ -1677,21 +1665,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => * Note: does not work for classes owned by methods, see Namers.companionClassOf * * object Foo . companionClass --> class Foo + * + * !!! linkedClassOfClass depends on companionClass on the module class getting + * to the class. As presently implemented this potentially returns class for + * any symbol except NoSymbol. */ - final def companionClass: Symbol = { - if (this != NoSymbol) - flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) - else NoSymbol - } - - /** A helper method that factors the common code used the discover a - * companion module of a class. If a companion module exists, its symbol is - * returned, otherwise, `NoSymbol` is returned. The method assumes that - * `this` symbol has already been checked to be a class (using `isClass`). - */ - private final def companionModule0: Symbol = - flatOwnerInfo.decl(name.toTermName).suchThat( - sym => sym.hasFlag(MODULE) && (sym isCoDefinedWith this) && !sym.isMethod) + def companionClass: Symbol = flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) /** For a class: the module or case class factory with the same name in the same package. * For all others: NoSymbol @@ -1699,9 +1678,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * * class Foo . companionModule --> object Foo */ - final def companionModule: Symbol = - if (isClass && !isRefinementClass) companionModule0 - else NoSymbol + def companionModule: Symbol = NoSymbol /** For a module: its linked class * For a plain class: its linked module or case factory. @@ -1709,18 +1686,14 @@ trait Symbols extends api.Symbols { self: SymbolTable => * * class Foo <-- companionSymbol --> object Foo */ - final def companionSymbol: Symbol = - if (isTerm) companionClass - else if (isClass) companionModule0 - else NoSymbol + def companionSymbol: Symbol = NoSymbol /** For a module class: its linked class * For a plain class: the module class of its linked module. * * class Foo <-- linkedClassOfClass --> class Foo$ */ - final def linkedClassOfClass: Symbol = - if (isModuleClass) companionClass else companionModule.moduleClass + def linkedClassOfClass: Symbol = NoSymbol /** * Returns the rawInfo of the owner. If the current phase has flat classes, @@ -1733,7 +1706,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => * symbol B in the decls of p. So to find a linked symbol ("object B" or "class B") * we need to apply flatten to B first. Fixes #2470. */ - private final def flatOwnerInfo: Type = { + protected final def flatOwnerInfo: Type = { if (needsFlatClasses) info owner.rawInfo @@ -1912,23 +1885,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => case p :: _ => p case _ => NoSymbol } - - /** 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 (hasAccessorFlag && !isDeferred) { - accessed.expandName(base) - } else if (hasGetter) { - getter(owner).expandName(base) - setter(owner).expandName(base) - } - name = nme.expandedName(name.toTermName, base) - if (isType) name = name - } - } /* code for fixing nested objects def expandModuleClassName() { name = newTypeName(name.toString + "$") @@ -1953,7 +1909,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def sealedDescendants: Set[Symbol] = children.flatMap(_.sealedDescendants) + this - def orElse[T](alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt + @inline final def orElse[T](alt: => Symbol): Symbol = if (this ne NoSymbol) this else alt // ------ toString ------------------------------------------------------------------- @@ -2115,31 +2071,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def infosString = infos.toString def debugLocationString = fullLocationString + " " + debugFlagString - def debugFlagString = hasFlagsToString(-1L) - def hasFlagsToString(mask: Long): String = flagsToString( - flags & mask, - if (hasAccessBoundary) privateWithin.toString else "" - ) - - /** String representation of symbol's variance */ - def varianceString: String = - if (variance == 1) "+" - else if (variance == -1) "-" - else "" - - def defaultFlagMask = - if (isAbstractType) ExplicitFlags - else if (settings.debug.value) -1L - else if (owner.isRefinementClass) ExplicitFlags & ~OVERRIDE - else ExplicitFlags - - // make the error message more googlable - def flagsExplanationString = - if (isGADTSkolem) " (this is a GADT skolem)" - else "" - def accessString = hasFlagsToString(PRIVATE | PROTECTED | LOCAL) - def defaultFlagString = hasFlagsToString(defaultFlagMask) private def defStringCompose(infoString: String) = compose( defaultFlagString, keyString, @@ -2171,12 +2103,24 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class for term symbols */ class TermSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) extends Symbol(initOwner, initPos, initName) { - final override def isTerm = true + private[this] var _referenced: Symbol = NoSymbol + privateWithin = NoSymbol + final override def isTerm = true override def name: TermName = rawname.toTermName - privateWithin = NoSymbol + override def companionSymbol: Symbol = companionClass + override def moduleClass = if (isModule) referenced else NoSymbol - private[this] var _referenced: Symbol = NoSymbol + override def hasDefault = this hasFlag DEFAULTPARAM // overloaded with TRAIT + override def isBridge = this hasFlag BRIDGE + override def isEarlyInitialized = this hasFlag PRESUPER + override def isMethod = this hasFlag METHOD + override def isModule = this hasFlag MODULE + override def isOverloaded = this hasFlag OVERLOADED + override def isPackage = this hasFlag PACKAGE + override def isValueParameter = this hasFlag PARAM + + override def isPackageObject = isModule && (name == nme.PACKAGE) def referenced: Symbol = _referenced def referenced_=(x: Symbol) { _referenced = x } @@ -2210,11 +2154,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => if (name endsWith nme.OUTER) initialize.referenced else NoSymbol - override def moduleClass: Symbol = - if (hasFlag(MODULE)) referenced else NoSymbol - def setModuleClass(clazz: Symbol): TermSymbol = { - assert(hasFlag(MODULE), this) + assert(isModule, this) referenced = clazz this } @@ -2230,6 +2171,23 @@ trait Symbols extends api.Symbols { self: SymbolTable => referenced } + /** change name by appending $$<fully-qualified-name-of-class `base`> + * Do the same for any accessed symbols or setters/getters + */ + override def expandName(base: Symbol) { + if (!hasFlag(EXPANDEDNAME)) { + setFlag(EXPANDEDNAME) + if (hasAccessorFlag && !isDeferred) { + accessed.expandName(base) + } + else if (hasGetter) { + getter(owner).expandName(base) + setter(owner).expandName(base) + } + name = nme.expandedName(name.toTermName, base) + } + } + protected def doCookJavaRawInfo() { def cook(sym: Symbol) { require(sym.isJavaDefined, sym) @@ -2263,9 +2221,16 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class for module symbols */ class ModuleSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) - extends TermSymbol(initOwner, initPos, initName) { + extends TermSymbol(initOwner, initPos, initName) with DistinguishingFlag { + def distinguishingFlag = MODULE + private var flatname: TermName = null + override def isModule = true + override def moduleClass = referenced + override def companionClass = + flatOwnerInfo.decl(name.toTypeName).suchThat(_ isCoDefinedWith this) + override def owner = ( if (!isMethod && needsFlatClasses) rawowner.owner else rawowner @@ -2279,21 +2244,38 @@ trait Symbols extends api.Symbols { self: SymbolTable => } else rawname.toTermName ) + } - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = - owner.newModuleSymbol(name, pos, newFlags).copyAttrsFrom(this) + class PackageSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TermName) + extends ModuleSymbol(owner0, pos0, name0) with DistinguishingFlag { + override def distinguishingFlag = super.distinguishingFlag | PACKAGE + override def isPackage = true } /** A class for method symbols */ class MethodSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TermName) - extends TermSymbol(initOwner, initPos, initName) { - private var mtpePeriod = NoPeriod - private var mtpePre: Type = _ - private var mtpeResult: Type = _ - private var mtpeInfo: Type = _ - - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = - owner.newMethodSymbol(name, pos, newFlags).copyAttrsFrom(this) + extends TermSymbol(initOwner, initPos, initName) with DistinguishingFlag { + def distinguishingFlag = METHOD + // MethodSymbols pick up MODULE when trait-owned object accessors are cloned + // during mixin composition. + override protected def neverHasFlags = super.neverHasFlags & ~MODULE + + private[this] var mtpePeriod = NoPeriod + private[this] var mtpePre: Type = _ + private[this] var mtpeResult: Type = _ + private[this] var mtpeInfo: Type = _ + + override def isMethod = true + override def isMacro = this hasFlag MACRO + override def isVarargsMethod = this hasFlag VARARGS + override def isLiftedMethod = this hasFlag LIFTED + // TODO - this seems a strange definition for "isSourceMethod", given that + // it does not make any specific effort to exclude synthetics. Figure out what + // this method is really for and what logic makes sense. + override def isSourceMethod = !(this hasFlag STABLE) // exclude all accessors + // unfortunately having the CASEACCESSOR flag does not actually mean you + // are a case accessor (you can also be a field.) + override def isCaseAccessorMethod = isCaseAccessor def typeAsMemberOf(pre: Type): Type = { if (mtpePeriod == currentPeriod) { @@ -2313,38 +2295,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => class AliasTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) extends TypeSymbol(initOwner, initPos, initName) { - // Temporary programmatic help tracking down who might do such a thing - override def setFlag(mask: Long): this.type = { - if (isSetting(DEFERRED, mask)) { - println("Setting DEFERRED on alias at") - (new Throwable).printStackTrace - } - super.setFlag(mask) - } final override def isAliasType = true - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): AliasTypeSymbol = - owner.newAliasTypeSymbol(name, pos, newFlags) - } - - class AbstractTypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName) - extends TypeSymbol(initOwner, initPos, initName) with AbstractTypeMixin { - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): AbstractTypeSymbol = - owner.newAbstractTypeSymbol(name, pos, newFlags) } - /** Might be mixed into TypeSymbol or TypeSkolem. - */ - trait AbstractTypeMixin extends TypeSymbol { - override def resetFlag(mask: Long): this.type = { - // Temporary programmatic help tracking down who might do such a thing - if (settings.debug.value) { - if (isClearing(DEFERRED, mask)) { - println("Clearing DEFERRED on abstract type at") - (new Throwable).printStackTrace - } - } - super.resetFlag(mask) - } + class AbstractTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) + extends TypeSymbol(initOwner, initPos, initName) { final override def isAbstractType = true override def existentialBound = this.info } @@ -2352,33 +2307,36 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class of type symbols. Alias and abstract types are direct instances * of this class. Classes are instances of a subclass. */ - abstract class TypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) extends Symbol(initOwner, initPos, initName) { + abstract class TypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) + extends Symbol(initOwner, initPos, initName) { privateWithin = NoSymbol + + final override def isType = true + override def isNonClassType = true + private var tyconCache: Type = null private var tyconRunId = NoRunId private var tpeCache: Type = _ private var tpePeriod = NoPeriod + override def isAbstractType = this hasFlag DEFERRED + override def isContravariant = this hasFlag CONTRAVARIANT + override def isCovariant = this hasFlag COVARIANT + override def isExistentialQuantified = isExistentiallyBound && !isSkolem + override def isExistentiallyBound = this hasFlag EXISTENTIAL + override def isTypeParameter = isTypeParameterOrSkolem && !isSkolem + override def isTypeParameterOrSkolem = this hasFlag PARAM + /** Overridden in subclasses for which it makes sense. */ def existentialBound: Type = abort("unexpected type: "+this.getClass+ " "+debugLocationString) + // a type symbol bound by an existential type, for instance the T in + // List[T] forSome { type T } + override def name: TypeName = super.name.toTypeName - final override def isType = true - override def isNonClassType = true - override def isAbstractType = { - if (settings.debug.value) { - if (isDeferred) { - println("TypeSymbol claims to be abstract type: " + this.getClass + " " + debugFlagString + " at ") - (new Throwable).printStackTrace - } - } - isDeferred - } - private def newTypeRef(targs: List[Type]) = { - val pre = if (hasFlag(PARAM | EXISTENTIAL)) NoPrefix else owner.thisType - typeRef(pre, this, targs) - } + private def newPrefix = if (this hasFlag EXISTENTIAL | PARAM) NoPrefix else owner.thisType + private def newTypeRef(targs: List[Type]) = typeRef(newPrefix, this, targs) /** Let's say you have a type definition * @@ -2471,8 +2429,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => } } + /** Default implementation. */ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = - owner.newTypeSymbol(name, pos, newFlags) + owner.newNonClassSymbol(name, pos, newFlags) incCounter(typeSymbolCount) } @@ -2492,12 +2451,19 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ class TypeSkolem protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName, origin: AnyRef) extends TypeSymbol(initOwner, initPos, initName) { - /** The skolemization level in place when the skolem was constructed */ val level = skolemizationLevel final override def isSkolem = true + override def isGADTSkolem = this hasFlag CASEACCESSOR | SYNTHETIC + override def isTypeSkolem = this hasFlag PARAM + override def isExistentialSkolem = this hasFlag EXISTENTIAL + override def isAbstractType = this hasFlag DEFERRED + + override def isExistentialQuantified = false + override def existentialBound = if (isAbstractType) this.info else super.existentialBound + /** If typeskolem comes from a type parameter, that parameter, otherwise skolem itself */ override def deSkolemize = origin match { case s: Symbol => s @@ -2521,17 +2487,92 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class for class symbols */ class ClassSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName) extends TypeSymbol(initOwner, initPos, initName) { - private[this] var flatname: TypeName = null - private[this] var source: AbstractFileType = null - private[this] var thissym: Symbol = this + private[this] var flatname: TypeName = _ + private[this] var source: AbstractFileType = _ + private[this] var thissym: Symbol = this + + private[this] var thisTypeCache: Type = _ + private[this] var thisTypePeriod = NoPeriod + private[this] var typeOfThisCache: Type = _ + private[this] var typeOfThisPeriod = NoPeriod + + override protected def alwaysHasFlags: Long = 0L + override protected def neverHasFlags: Long = 0L final override def isClass = true final override def isNonClassType = false final override def isAbstractType = false final override def isAliasType = false + override def isAbstractClass = this hasFlag ABSTRACT + override def isClassLocalToConstructor = this hasFlag INCONSTRUCTOR + override def isImplClass = this hasFlag IMPLCLASS + override def isModuleClass = this hasFlag MODULE + override def isPackageClass = this hasFlag PACKAGE + override def isTrait = this hasFlag TRAIT + + override def isConcreteClass = !(this hasFlag ABSTRACT | TRAIT) + override def isPackageObjectClass = isModuleClass && (name == tpnme.PACKAGE) + + def isTraitOrImplClass = this hasFlag TRAIT | IMPLCLASS + def isNonImplModuleClass = isModuleClass && !isImplClass + + override def isAnonymousClass = name containsName tpnme.ANON_CLASS_NAME + override def isAnonOrRefinementClass = isAnonymousClass || isRefinementClass + override def isNestedClass = !owner.isPackageClass + override def isNumericValueClass = definitions.isNumericValueClass(this) + override def isPrimitiveValueClass = definitions.isPrimitiveValueClass(this) + + /** 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 + */ + override def isLocalClass = ( + isAnonOrRefinementClass + || isLocal + || !owner.isPackageClass && owner.isLocalClass + ) + override def isStableClass = (this hasFlag STABLE) || checkStable() + + private def checkStable() = { + 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 + } + (info.baseClasses forall hasNoAbstractTypeMember) && { + setFlag(STABLE) + true + } + } + + override def enclClassChain = this :: owner.enclClassChain + + /** A helper method that factors the common code used the discover a + * companion module of a class. If a companion module exists, its symbol is + * returned, otherwise, `NoSymbol` is returned. + */ + protected final def companionModule0: Symbol = + flatOwnerInfo.decl(name.toTermName).suchThat( + sym => sym.hasFlag(MODULE) && (sym isCoDefinedWith this) && !sym.isMethod) + + override def companionModule = companionModule0 + override def companionSymbol = companionModule0 + override def linkedClassOfClass = companionModule.moduleClass + override def existentialBound = GenPolyType(this.typeParams, TypeBounds.upper(this.classBound)) + def primaryConstructorName = if (isTraitOrImplClass) nme.MIXIN_CONSTRUCTOR else nme.CONSTRUCTOR + + override def primaryConstructor = { + val c = info decl primaryConstructorName + if (c.isOverloaded) c.alternatives.head else c + } + override def sourceFile = if (owner.isPackageClass) source else super.sourceFile @@ -2542,12 +2583,6 @@ trait Symbols extends api.Symbols { self: SymbolTable => thissym = this } - private var thisTypeCache: Type = _ - private var thisTypePeriod = NoPeriod - - private var typeOfThisCache: Type = _ - private var typeOfThisPeriod = NoPeriod - /** the type this.type in this class */ override def thisType: Type = { val period = thisTypePeriod @@ -2558,8 +2593,24 @@ trait Symbols extends api.Symbols { self: SymbolTable => thisTypeCache } + /** the self type of an object foo is foo.type, not class<foo>.this.type + */ + override def typeOfThis: Type = { + if (isNonImplModuleClass && owner != NoSymbol) { + val period = typeOfThisPeriod + if (period != currentPeriod) { + typeOfThisPeriod = currentPeriod + if (!isValid(period)) + typeOfThisCache = singleType(owner.thisType, sourceModule) + } + typeOfThisCache + } + else thisSym.tpe + } + override def owner: Symbol = if (needsFlatClasses) rawowner.owner else rawowner + override def name: TypeName = ( if (needsFlatClasses) { if (flatname eq null) @@ -2573,27 +2624,12 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A symbol carrying the self type of the class as its type */ override def thisSym: Symbol = thissym - /** the self type of an object foo is foo.type, not class<foo>.this.type - */ - override def typeOfThis: Type = { - if (getFlag(MODULE | IMPLCLASS) == MODULE.toLong && owner != NoSymbol) { - val period = typeOfThisPeriod - if (period != currentPeriod) { - typeOfThisPeriod = currentPeriod - if (!isValid(period)) - typeOfThisCache = singleType(owner.thisType, sourceModule) - } - typeOfThisCache - } - else thisSym.tpe - } - /** Sets the self type of the class */ override def typeOfThis_=(tp: Type) { thissym = newThisSym(pos).setInfo(tp) } - override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = { + override def cloneSymbolImpl(owner: Symbol, newFlags: Long): ClassSymbol = { val clone = owner.newClassSymbol(name, pos, newFlags) if (thisSym != this) { clone.typeOfThis = typeOfThis @@ -2602,12 +2638,11 @@ trait Symbols extends api.Symbols { self: SymbolTable => clone } - override def sourceModule = - if (isModuleClass) companionModule else NoSymbol + // Must have this line. + override def sourceModule = if (isModuleClass) companionModule else NoSymbol override def firstParamAccessor = - info.decls.find(m => (m hasFlag PARAMACCESSOR) && m.isMethod) getOrElse NoSymbol - + info.decls.find(_ hasAllFlags PARAMACCESSOR | METHOD) getOrElse NoSymbol private[this] var childSet: Set[Symbol] = Set() override def children = childSet @@ -2621,12 +2656,17 @@ trait Symbols extends api.Symbols { self: SymbolTable => * plain class symbols! */ class ModuleClassSymbol protected[Symbols] (owner: Symbol, pos: Position, name: TypeName) - extends ClassSymbol(owner, pos, name) { + extends ClassSymbol(owner, pos, name) with DistinguishingFlag { + def distinguishingFlag = MODULE + private var module: Symbol = null - private var implicitMembersCacheValue: List[Symbol] = List() + private var implicitMembersCacheValue: List[Symbol] = Nil private var implicitMembersCacheKey1: Type = NoType private var implicitMembersCacheKey2: ScopeEntry = null + override def isModuleClass = true + override def linkedClassOfClass = companionClass + def implicitMembers: List[Symbol] = { val tp = info if ((implicitMembersCacheKey1 ne tp) || (implicitMembersCacheKey2 ne tp.decls.elems)) { @@ -2644,6 +2684,35 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def sourceModule_=(module: Symbol) { this.module = module } } + class PackageClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TypeName) + extends ModuleClassSymbol(owner0, pos0, name0) with DistinguishingFlag { + override def distinguishingFlag = super.distinguishingFlag | PACKAGE + override def sourceModule = companionModule + override def enclClassChain = Nil + override def isPackageClass = true + } + + class RefinementClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position) + extends ClassSymbol(owner0, pos0, tpnme.REFINE_CLASS_NAME) { + override def name_=(name: Name) { + assert(false, "Cannot set name of RefinementClassSymbol to " + name) + super.name_=(name) + } + override def isRefinementClass = true + override def isAnonOrRefinementClass = true + override def isLocalClass = true + override def hasMeaninglessName = true + override def companionModule: Symbol = NoSymbol + + /** The mentioned twist. A refinement class has transowner X + * if any of its parents has transowner X. + */ + override def hasTransOwner(sym: Symbol) = ( + super.hasTransOwner(sym) + || info.parents.exists(_.typeSymbol hasTransOwner sym) + ) + } + class FreeVar(name0: TermName, val value: Any) extends TermSymbol(NoSymbol, NoPosition, name0) { override def hashCode = if (value == null) 0 else value.hashCode override def equals(other: Any): Boolean = other match { @@ -2663,12 +2732,20 @@ trait Symbols extends api.Symbols { self: SymbolTable => unlock() validTo = currentPeriod } + override def defaultFlagMask = AllFlags + override def exists = false + override def isHigherOrderTypeParameter = false + override def companionClass = NoSymbol + override def companionModule = NoSymbol + override def companionSymbol = NoSymbol override def isSubClass(that: Symbol) = false override def filter(cond: Symbol => Boolean) = this override def defString: String = toString override def locationString: String = "" + override def enclClassChain = Nil override def enclClass: Symbol = this override def enclosingTopLevelClass: Symbol = this + override def enclosingPackageClass: Symbol = this override def enclMethod: Symbol = this override def sourceFile: AbstractFileType = null override def ownerChain: List[Symbol] = List() @@ -2689,9 +2766,9 @@ trait Symbols extends api.Symbols { self: SymbolTable => abort("no-symbol does not have a type constructor (this may indicate scalac cannot find fundamental classes)") } - protected def makeNoSymbol = new NoSymbol + protected def makeNoSymbol: NoSymbol = new NoSymbol - lazy val NoSymbol = makeNoSymbol + lazy val NoSymbol: NoSymbol = makeNoSymbol /** Derives a new list of symbols from the given list by mapping the given * list across the given function. Then fixes the info of all the new symbols @@ -2779,7 +2856,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** A class for type histories */ private sealed case class TypeHistory(var validFrom: Period, info: Type, prev: TypeHistory) { assert((prev eq null) || phaseId(validFrom) > phaseId(prev.validFrom), this) - assert(validFrom != NoPeriod) + assert(validFrom != NoPeriod, this) + override def toString() = "TypeHistory(" + phaseOf(validFrom)+":"+runId(validFrom) + "," + info + "," + prev + ")" |