summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/internal/Symbols.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-04-05 15:50:10 -0700
committerPaul Phillips <paulp@improving.org>2012-04-05 22:51:29 -0700
commit296b7061ccef8600c011140fa6fd64afec244ed0 (patch)
tree852bfad96dc8b980b18a7869640f4c400566baa5 /src/compiler/scala/reflect/internal/Symbols.scala
parent2b89c3459d1d9a9aa9dd5aba75847274d6f74129 (diff)
downloadscala-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.scala852
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 + ")"