summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-04-06 15:14:48 -0700
committerPaul Phillips <paulp@improving.org>2012-04-07 17:22:36 -0700
commitb66d390ed4ddc1880db06dd1f1cc1167b6278627 (patch)
treea6cffd382923e8e21c09499603e343b43097b282 /src
parent1a6408c42928211d5d119317cc1aec4eb2481101 (diff)
downloadscala-b66d390ed4ddc1880db06dd1f1cc1167b6278627.tar.gz
scala-b66d390ed4ddc1880db06dd1f1cc1167b6278627.tar.bz2
scala-b66d390ed4ddc1880db06dd1f1cc1167b6278627.zip
More Symbols and Flags.
Another "three yards and a cloud of dust" in my ongoing battle against flag uncertainty.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala2
-rw-r--r--src/compiler/scala/reflect/internal/NameManglers.scala15
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala3
-rw-r--r--src/compiler/scala/reflect/internal/SymbolCreations.scala6
-rw-r--r--src/compiler/scala/reflect/internal/SymbolFlags.scala7
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala257
-rw-r--r--src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala14
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala133
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Flatten.scala3
10 files changed, 257 insertions, 187 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 0fa2762c0f..4fd98ad7b3 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -151,6 +151,8 @@ trait Definitions extends reflect.api.StandardDefinitions {
// type and term symbols respectively.
sealed trait RootSymbol extends WellKnownSymbol {
final override def isRootSymbol = true
+ override def owner = NoSymbol
+ override def typeOfThis = thisSym.tpe
}
// This is the package _root_. The actual root cannot be referenced at
// the source level, but _root_ is essentially a function => <root>.
diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala
index 48f21721da..05578a2042 100644
--- a/src/compiler/scala/reflect/internal/NameManglers.scala
+++ b/src/compiler/scala/reflect/internal/NameManglers.scala
@@ -179,9 +179,6 @@ trait NameManglers {
else name.toTermName
}
- // This isn't needed at the moment since I fixed $class$1 but
- // I expect it will be at some point.
- //
// def anonNumberSuffix(name: Name): Name = {
// ("" + name) lastIndexOf '$' match {
// case -1 => nme.EMPTY
@@ -192,6 +189,18 @@ trait NameManglers {
// }
// }
+ // If the name ends with $nn where nn are
+ // all digits, strip the $ and the digits.
+ // Otherwise return the argument.
+ def stripAnonNumberSuffix(name: Name): Name = {
+ var pos = name.length
+ while (pos > 0 && name(pos - 1).isDigit)
+ pos -= 1
+
+ if (pos <= 0 || pos == name.length || name(pos - 1) != '$') name
+ else name.subName(0, pos - 1)
+ }
+
def stripModuleSuffix(name: Name): Name = (
if (isModuleName(name)) name dropRight MODULE_SUFFIX_STRING.length else name
)
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index e2c253628c..0cd3616ba9 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -529,6 +529,9 @@ trait StdNames extends NameManglers { self: SymbolTable =>
def expandedName(name: TermName, base: Symbol, separator: String = EXPAND_SEPARATOR_STRING): TermName =
newTermNameCached(base.fullName('$') + separator + name)
+ def isModuleVarName(name: Name): Boolean =
+ stripAnonNumberSuffix(name) endsWith MODULE_VAR_SUFFIX
+
def moduleVarName(name: TermName): TermName =
newTermNameCached("" + name + MODULE_VAR_SUFFIX)
diff --git a/src/compiler/scala/reflect/internal/SymbolCreations.scala b/src/compiler/scala/reflect/internal/SymbolCreations.scala
index 77c4ee27c2..a1163b0f57 100644
--- a/src/compiler/scala/reflect/internal/SymbolCreations.scala
+++ b/src/compiler/scala/reflect/internal/SymbolCreations.scala
@@ -45,6 +45,8 @@ trait SymbolCreations {
protected def createModuleClassSymbol(name: TypeName, pos: Position, newFlags: Long): ModuleClassSymbol
protected def createPackageClassSymbol(name: TypeName, pos: Position, newFlags: Long): PackageClassSymbol
protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol
+ protected def createImplClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol
+ protected def createPackageObjectClassSymbol(pos: Position, newFlags: Long): PackageObjectClassSymbol
// Distinguished term categories include methods, modules, packages, package objects,
// value parameters, and values (including vals, vars, and lazy vals.)
@@ -88,8 +90,12 @@ trait SymbolCreations {
createRefinementClassSymbol(pos, newFlags)
else if ((newFlags & PACKAGE) != 0)
createPackageClassSymbol(name, pos, newFlags | PackageFlags)
+ else if (name == tpnme.PACKAGE)
+ createPackageObjectClassSymbol(pos, newFlags)
else if ((newFlags & MODULE) != 0)
createModuleClassSymbol(name, pos, newFlags)
+ else if ((newFlags & IMPLCLASS) != 0)
+ createImplClassSymbol(name, pos, newFlags)
else
createClassSymbol(name, pos, newFlags)
}
diff --git a/src/compiler/scala/reflect/internal/SymbolFlags.scala b/src/compiler/scala/reflect/internal/SymbolFlags.scala
index 0c620f8346..febcec8c7c 100644
--- a/src/compiler/scala/reflect/internal/SymbolFlags.scala
+++ b/src/compiler/scala/reflect/internal/SymbolFlags.scala
@@ -97,6 +97,11 @@ trait SymbolFlags {
}
}
+ /** Flags which should always be present on a particular class of
+ * Symbol, and never be present on any others.
+ */
+ def AllDistinguishingFlags: Long = METHOD | MODULE | IMPLCLASS
+
/** A distinguishing flag is one which the mixing class must always
* have, and which no other symbol class is allowed to have.
*/
@@ -125,7 +130,7 @@ trait SymbolFlags {
protected def calculateFlagString(basis: Long): String
protected def alwaysHasFlags: Long = 0L
- protected def neverHasFlags: Long = METHOD | MODULE
+ protected def neverHasFlags: Long = AllDistinguishingFlags
def rawFlagString(mask: Long): String = calculateFlagString(rawflags & mask)
def rawFlagString: String = rawFlagString(flagMask)
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index a30714f113..ba1513d12b 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -166,7 +166,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// with the proper specific type.
def rawname: NameType
def name: NameType
- def name_=(n: NameType): Unit
+ def name_=(n: Name): Unit
def asNameType(n: Name): NameType
private[this] var _rawowner = initOwner // Syncnote: need not be protected, as only assignment happens in owner_=, which is not exposed to api
@@ -381,15 +381,16 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
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)
-
- final def newAnonymousFunctionClass(pos: Position, newFlags: Long = 0L) =
+ final def newAnonymousFunctionClass(pos: Position = NoPosition, newFlags: Long = 0L) =
newClassSymbol(tpnme.ANON_FUN_NAME, pos, FINAL | SYNTHETIC | newFlags)
final def newAnonymousFunctionValue(pos: Position, newFlags: Long = 0L) =
newTermSymbol(nme.ANON_FUN_NAME, pos, SYNTHETIC | newFlags) setInfo NoType
+ def newImplClass(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): ClassSymbol = {
+ newClassSymbol(name, pos, newFlags | IMPLCLASS)
+ }
+
/** Refinement types P { val x: String; type T <: Number }
* also have symbols, they are refinementClasses
*/
@@ -520,21 +521,23 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isAbstractClass = false
def isAnonOrRefinementClass = false
def isAnonymousClass = false
+ def isCaseClass = false
def isConcreteClass = false
def isImplClass = false // the implementation class of a trait
+ def isJavaInterface = false
def isModuleClass = false
def isNumericValueClass = false
def isPrimitiveValueClass = false
def isRefinementClass = false
- override def isTrait = false
+ override def isTrait = false
/** Qualities of Types, always false for TermSymbols.
*/
def isContravariant = false
def isCovariant = false
+ def isExistentialQuantified = false
def isExistentialSkolem = false
def isExistentiallyBound = false
- def isExistentialQuantified = false
def isGADTSkolem = false
def isTypeParameter = false
def isTypeParameterOrSkolem = false
@@ -542,12 +545,23 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** 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
+ def isAccessor = false
+ def isBridge = false
+ def isCapturedVariable = false
+ def isClassConstructor = false
+ def isConstructor = false
+ def isEarlyInitialized = false
+ def isGetter = false
+ def isLocalDummy = false
+ def isMixinConstructor = false
+ def isModule = false
+ def isOverloaded = false
+ def isSetter = false
+ def isSetterParameter = false
+ def isValue = false
+ def isValueParameter = false
+ def isVariable = false
+ override def hasDefault = false
/** Qualities of MethodSymbols, always false for TypeSymbols
* and other TermSymbols.
@@ -558,13 +572,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isMethod = false
def isSourceMethod = false
def isVarargsMethod = false
+ override def isLabel = 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
@@ -625,26 +639,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def flags_=(fs: Long) = _rawflags = fs
def rawflags_=(x: Long) { _rawflags = x }
- /** 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
-
- // interesting only for lambda lift. Captured variables are accessed from inner lambdas.
- final def isCapturedVariable = isVariable && hasFlag(CAPTURED)
-
- final def isGetter = isTerm && hasAccessorFlag && !nme.isSetterName(name)
- // todo: make independent of name, as this can be forged.
- final def isSetter = isTerm && hasAccessorFlag && nme.isSetterName(name)
- def isSetterParameter = isValueParameter && owner.isSetter
-
final def hasGetter = isTerm && nme.isLocalName(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)
final def isStaticModule = isModule && isStatic && !isMethod
final def isThisSym = isTerm && owner.thisSym == this
final def isError = hasFlag(IS_ERROR)
@@ -663,7 +660,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
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
/** change name by appending $$<fully-qualified-name-of-class `base`>
@@ -681,7 +677,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** If this is a package object or its implementing class, its owner: otherwise this.
*/
- def skipPackageObject: Symbol = if (this.isPackageObjectOrClass) owner else this
+ def skipPackageObject: Symbol = this
/** If this is a constructor, its owner: otherwise this.
*/
@@ -752,16 +748,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
/** Does this symbol denote a stable value? */
- final def isStable =
- isTerm &&
- !isMutable &&
- (!hasFlag(METHOD | BYNAMEPARAM) || hasFlag(STABLE)) &&
- !(tpe.isVolatile && !hasAnnotation(uncheckedStableClass))
-
- // def isVirtualClass = hasFlag(DEFERRED) && isClass
- // def isVirtualTrait = hasFlag(DEFERRED) && isTrait
- // def isLiftedMethod = hasAllFlags(METHOD | LIFTED)
- def isCaseClass = isClass && isCase
+ def isStable = false
/** Does this symbol denote the primary constructor of its enclosing class? */
final def isPrimaryConstructor =
@@ -776,20 +763,20 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
isMethod && isCase && isSynthetic
/** Is this symbol a trait which needs an implementation class? */
- final def needsImplClass: Boolean =
- isTrait && (!isInterface || hasFlag(lateINTERFACE)) && !isImplClass
+ final def needsImplClass = (
+ isTrait
+ && (!isInterface || hasFlag(lateINTERFACE))
+ && !isImplClass
+ )
/** Is this a symbol which exists only in the implementation class, not in its trait? */
- final def isImplOnly: Boolean =
- hasFlag(PRIVATE) ||
- (owner.isImplClass || owner.isTrait) &&
- ((hasFlag(notPRIVATE | LIFTED) && !hasFlag(ACCESSOR | SUPERACCESSOR | MODULE) || isConstructor) ||
- (hasFlag(LIFTED) && isModule && isMethod))
-
- /** Is this symbol a module variable?
- * This used to have to test for MUTABLE to distinguish the overloaded
- * MODULEVAR/SYNTHETICMETH flag, but now SYNTHETICMETH is gone.
- */
+ final def isImplOnly = isPrivate || (
+ (owner.isTrait || owner.isImplClass) && (
+ hasAllFlags(LIFTED | MODULE | METHOD)
+ || isConstructor
+ || hasFlag(notPRIVATE | LIFTED) && !hasFlag(ACCESSOR | SUPERACCESSOR | MODULE)
+ )
+ )
final def isModuleVar = hasFlag(MODULEVAR)
/** Is this symbol static (i.e. with no outer instance)? */
@@ -883,7 +870,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else if (isContravariant) -1
else 0
-
/** The sequence number of this parameter symbol among all type
* and value parameters of symbol's owner. -1 if symbol does not
* appear among the parameters of its owner.
@@ -1031,6 +1017,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol =
new RefinementClassSymbol(this, pos) initFlags newFlags
+ protected def createPackageObjectClassSymbol(pos: Position, newFlags: Long): PackageObjectClassSymbol =
+ new PackageObjectClassSymbol(this, pos) initFlags newFlags
+
+ protected def createImplClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol =
+ new ClassSymbol(this, pos, name) with ImplClassSymbol initFlags newFlags
+
protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol =
new TermSymbol(this, pos, name) initFlags newFlags
@@ -1529,6 +1521,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
)
if (clone.thisSym != clone)
clone.typeOfThis = (clone.typeOfThis cloneInfo clone)
+
if (newName ne null)
clone setName asNameType(newName)
@@ -1604,8 +1597,6 @@ 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
@@ -1830,18 +1821,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* This only works for implementation classes owned by other classes or traits.
* !!! Why?
*/
- final def toInterface: Symbol =
- if (isImplClass) {
- val result =
- if (phase.next.erasedTypes) {
- assert(!tpe.parents.isEmpty, this)
- tpe.parents.last.typeSymbol
- } else {
- owner.info.decl(nme.interfaceName(name))
- }
- assert(result != NoSymbol, this)
- result
- } else this
+ def toInterface: Symbol = this
/** The module class corresponding to this module.
*/
@@ -2222,15 +2202,25 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private[this] var _rawname: TermName = initName
def rawname = _rawname
def name = _rawname
- def name_=(name: TermName) {
+ def name_=(name: Name) {
if (name != rawname) {
+ log("Renaming %s %s %s to %s".format(shortSymbolClass, debugFlagString, rawname, name))
changeNameInOwners(name)
- _rawname = name
+ _rawname = name.toTermName
}
}
final def asNameType(n: Name) = n.toTermName
final override def isTerm = true
+
+ /** Term symbols with the exception of static parts of Java classes and packages.
+ */
+ override def isValue = !(isModule && hasFlag(PACKAGE | JAVA))
+ override def isVariable = isMutable && !isMethod
+
+ // interesting only for lambda lift. Captured variables are accessed from inner lambdas.
+ override def isCapturedVariable = hasAllFlags(MUTABLE | CAPTURED) && !hasFlag(METHOD)
+
override def companionSymbol: Symbol = companionClass
override def moduleClass = if (isModule) referenced else NoSymbol
@@ -2243,7 +2233,22 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def isPackage = this hasFlag PACKAGE
override def isValueParameter = this hasFlag PARAM
+ override def isSetterParameter = isValueParameter && owner.isSetter
+ override def isAccessor = this hasFlag ACCESSOR
+ override def isGetter = isAccessor && !isSetter
+ override def isSetter = isAccessor && nme.isSetterName(name) // todo: make independent of name, as this can be forged.
+ override def isLocalDummy = nme.isLocalDummyName(name)
+ override def isClassConstructor = name == nme.CONSTRUCTOR
+ override def isMixinConstructor = name == nme.MIXIN_CONSTRUCTOR
+ override def isConstructor = nme.isConstructorName(name)
+
override def isPackageObject = isModule && (name == nme.PACKAGE)
+ override def isStable = !isUnstable
+ private def isUnstable = (
+ isMutable
+ || (hasFlag(METHOD | BYNAMEPARAM) && !hasFlag(STABLE))
+ || (tpe.isVolatile && !hasAnnotation(uncheckedStableClass))
+ )
// The name in comments is what it is being disambiguated from.
// TODO - rescue CAPTURED from BYNAMEPARAM so we can see all the names.
@@ -2285,7 +2290,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
override def outerSource: Symbol =
- if (name endsWith nme.OUTER) initialize.referenced
+ if (originalName == nme.OUTER) initialize.referenced
else NoSymbol
def setModuleClass(clazz: Symbol): TermSymbol = {
@@ -2399,9 +2404,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private[this] var mtpeInfo: Type = _
override def isMethod = true
+ override def isLabel = this hasFlag LABEL
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.
@@ -2487,19 +2494,16 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
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 }
-
// 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: TypeName) {
+ def name_=(name: Name) {
if (name != rawname) {
+ log("Renaming %s %s %s to %s".format(shortSymbolClass, debugFlagString, rawname, name))
changeNameInOwners(name)
- _rawname = name
+ _rawname = name.toTypeName
}
}
-
private def newPrefix = if (this hasFlag EXISTENTIAL | PARAM) NoPrefix else owner.thisType
private def newTypeRef(targs: List[Type]) = typeRef(newPrefix, this, targs)
@@ -2618,9 +2622,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final override def isSkolem = true
+ // a type symbol bound by an existential type, for instance the T in
+ // List[T] forSome { type T }
+ override def isExistentialSkolem = this hasFlag EXISTENTIAL
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
@@ -2657,15 +2663,14 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
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
override def resolveOverloadedFlag(flag: Long) = flag match {
- case INCONSTRUCTOR => "<inconstructor>" // CONTRAVARIANT / LABEL
- case EXISTENTIAL => "<existential>" // MIXEDIN
+ case INCONSTRUCTOR => "<inconstructor>" // INCONSTRUCTOR / CONTRAVARIANT / LABEL
+ case EXISTENTIAL => "<existential>" // EXISTENTIAL / MIXEDIN
+ case IMPLCLASS => "<implclass>" // IMPLCLASS / PRESUPER
case _ => super.resolveOverloadedFlag(flag)
}
@@ -2675,24 +2680,32 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final override def isAliasType = false
override def isAbstractClass = this hasFlag ABSTRACT
+ override def isCaseClass = this hasFlag CASE
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 isAnonymousClass = name containsName tpnme.ANON_CLASS_NAME
+ override def isConcreteClass = !(this hasFlag ABSTRACT | TRAIT)
+ override def isJavaInterface = hasAllFlags(JAVA | TRAIT)
override def isNestedClass = !owner.isPackageClass
override def isNumericValueClass = definitions.isNumericValueClass(this)
+ override def isPackageObjectClass = isModuleClass && (name == tpnme.PACKAGE)
override def isPrimitiveValueClass = definitions.isPrimitiveValueClass(this)
+ // The corresponding interface is the last parent by convention.
+ private def lastParent = if (tpe.parents.isEmpty) NoSymbol else tpe.parents.last.typeSymbol
+ override def toInterface: Symbol = (
+ if (isImplClass) {
+ if (phase.next.erasedTypes) lastParent
+ else owner.info.decl(nme.interfaceName(name))
+ }
+ else super.toInterface
+ )
+
/** Is this class locally defined?
* A class is local, if
* - it is anonymous, or
@@ -2734,9 +2747,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def companionSymbol = companionModule0
override def linkedClassOfClass = companionModule.moduleClass
+ override def sourceModule = if (isModuleClass) companionModule else NoSymbol
+
override def existentialBound = GenPolyType(this.typeParams, TypeBounds.upper(this.classBound))
- def primaryConstructorName = if (isTraitOrImplClass) nme.MIXIN_CONSTRUCTOR else nme.CONSTRUCTOR
+ def primaryConstructorName = if (this hasFlag TRAIT | IMPLCLASS) nme.MIXIN_CONSTRUCTOR else nme.CONSTRUCTOR
override def primaryConstructor = {
val c = info decl primaryConstructorName
@@ -2763,21 +2778,6 @@ 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
@@ -2808,9 +2808,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
clone
}
- // Must have this line.
- override def sourceModule = if (isModuleClass) companionModule else NoSymbol
-
override def firstParamAccessor =
info.decls.find(_ hasAllFlags PARAMACCESSOR | METHOD) getOrElse NoSymbol
@@ -2827,9 +2824,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
class ModuleClassSymbol protected[Symbols] (owner: Symbol, pos: Position, name: TypeName)
extends ClassSymbol(owner, pos, name) with DistinguishingFlag {
+ private[this] var module: Symbol = _
+ private[this] var typeOfThisCache: Type = _
+ private[this] var typeOfThisPeriod = NoPeriod
+
def distinguishingFlag = MODULE
- private var module: Symbol = null
private var implicitMembersCacheValue: List[Symbol] = Nil
private var implicitMembersCacheKey1: Type = NoType
private var implicitMembersCacheKey2: ScopeEntry = null
@@ -2837,6 +2837,18 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def isModuleClass = true
override def linkedClassOfClass = companionClass
+ /** the self type of an object foo is foo.type, not class<foo>.this.type
+ */
+ override def typeOfThis = {
+ val period = typeOfThisPeriod
+ if (period != currentPeriod) {
+ typeOfThisPeriod = currentPeriod
+ if (!isValid(period))
+ typeOfThisCache = singleType(owner.thisType, sourceModule)
+ }
+ typeOfThisCache
+ }
+
def implicitMembers: List[Symbol] = {
val tp = info
if ((implicitMembersCacheKey1 ne tp) || (implicitMembersCacheKey2 ne tp.decls.elems)) {
@@ -2850,10 +2862,27 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
implicitMembersCacheValue
}
- override def sourceModule = module
+ // The null check seems to be necessary for the reifier.
+ override def sourceModule = if (module ne null) module else companionModule
override def sourceModule_=(module: Symbol) { this.module = module }
}
+ class PackageObjectClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position)
+ extends ModuleClassSymbol(owner0, pos0, tpnme.PACKAGE) {
+ final override def isPackageObjectClass = true
+ final override def isPackageObjectOrClass = true
+ final override def skipPackageObject = owner
+ final override def setName(name: Name): this.type = {
+ abort("Can't rename a package object to " + name)
+ }
+ }
+
+ trait ImplClassSymbol extends ClassSymbol {
+ override def sourceModule = companionModule
+ // override def isImplClass = true
+ override def typeOfThis = thisSym.tpe // don't use the ModuleClassSymbol typeOfThisCache.
+ }
+
class PackageClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position, name0: TypeName)
extends ModuleClassSymbol(owner0, pos0, name0) with DistinguishingFlag {
override def distinguishingFlag = super.distinguishingFlag | PACKAGE
@@ -2864,7 +2893,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
class RefinementClassSymbol protected[Symbols] (owner0: Symbol, pos0: Position)
extends ClassSymbol(owner0, pos0, tpnme.REFINE_CLASS_NAME) {
- override def name_=(name: TypeName) {
+ override def name_=(name: Name) {
assert(false, "Cannot set name of RefinementClassSymbol to " + name)
super.name_=(name)
}
@@ -2899,7 +2928,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def asNameType(n: Name) = n.toTermName
def rawname = nme.NO_NAME
def name = nme.NO_NAME
- def name_=(n: TermName) = abort("Cannot set name to " + n)
+ def name_=(n: Name) = abort("Cannot set NoSymbol's name to " + n)
synchronized {
setInfo(NoType)
diff --git a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
index 2956bc8a21..5ae4ec15ee 100644
--- a/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/compiler/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -21,10 +21,10 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
trait SynchronizedSymbol extends Symbol {
- override def rawowner = synchronized { super.rawowner }
override def rawflags = synchronized { super.rawflags }
-
override def rawflags_=(x: Long) = synchronized { super.rawflags_=(x) }
+
+ override def rawowner = synchronized { super.rawowner }
override def owner_=(owner: Symbol) = synchronized { super.owner_=(owner) }
override def validTo = synchronized { super.validTo }
@@ -74,6 +74,12 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
override protected def createRefinementClassSymbol(pos: Position, newFlags: Long): RefinementClassSymbol =
new RefinementClassSymbol(this, pos) with SynchronizedClassSymbol initFlags newFlags
+ override protected def createImplClassSymbol(name: TypeName, pos: Position, newFlags: Long): ClassSymbol =
+ new ClassSymbol(this, pos, name) with ImplClassSymbol with SynchronizedClassSymbol initFlags newFlags
+
+ override protected def createPackageObjectClassSymbol(pos: Position, newFlags: Long): PackageObjectClassSymbol =
+ new PackageObjectClassSymbol(this, pos) with SynchronizedClassSymbol initFlags newFlags
+
override protected def createTermSymbol(name: TermName, pos: Position, newFlags: Long): TermSymbol =
new TermSymbol(this, pos, name) with SynchronizedTermSymbol initFlags newFlags
@@ -94,7 +100,7 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
// ------- subclasses ---------------------------------------------------------------------
trait SynchronizedTermSymbol extends TermSymbol with SynchronizedSymbol {
- override def name_=(x: TermName) = synchronized { super.name_=(x) }
+ override def name_=(x: Name) = synchronized { super.name_=(x) }
override def rawname = synchronized { super.rawname }
override def referenced: Symbol = synchronized { super.referenced }
override def referenced_=(x: Symbol) = synchronized { super.referenced_=(x) }
@@ -105,7 +111,7 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
}
trait SynchronizedTypeSymbol extends TypeSymbol with SynchronizedSymbol {
- override def name_=(x: TypeName) = synchronized { super.name_=(x) }
+ override def name_=(x: Name) = synchronized { super.name_=(x) }
override def rawname = synchronized { super.rawname }
override def typeConstructor: Type = synchronized { super.typeConstructor }
override def tpe: Type = synchronized { super.tpe }
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index e981910bdb..97e844f6d8 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -64,61 +64,60 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
def implClassPhase = currentRun.erasurePhase.next
- /** Return the implementation class of a trait; create a new one of one does not yet exist */
- def implClass(iface: Symbol): Symbol = {
- def implClassFlags = iface.flags & ~(INTERFACE | lateINTERFACE) | IMPLCLASS
-
- iface.info
-
- implClassMap.getOrElse(iface, {
- atPhase(implClassPhase) {
- if (iface.implClass ne NoSymbol)
- log("%s.implClass == %s".format(iface, iface.implClass))
-
- val implName = nme.implClassName(iface.name)
- var impl = if (iface.owner.isClass) iface.owner.info.decl(implName) else NoSymbol
-
- // !!! Why does forcing the impl's info here lead to a crash?
- // See test case pos/trait-force-info.scala for a minimization.
- // It crashes like this:
- //
- // [log lazyvals] trait ContextTrees.implClass == class ContextTrees$class
- // error: java.lang.AssertionError: assertion failed: (scala.tools.nsc.typechecker.Contexts$NoContext$,scala.tools.nsc.typechecker.Contexts,NoContext$,trait Contexts in package typechecker) / while parsing (/scala/trunk/build/pack/lib/scala-compiler.jar(scala/tools/nsc/interactive/ContextTrees$class.class),Some(class ContextTrees$class))trait Contexts.NoContext$ linkedModule: <none>List()
-
- val originalImpl = impl
- if (impl != NoSymbol) {
+ private def newImplClass(iface: Symbol): Symbol = {
+ val inClass = iface.owner.isClass
+ val implName = nme.implClassName(iface.name)
+ val implFlags = (iface.flags & ~(INTERFACE | lateINTERFACE)) | IMPLCLASS
+
+ val impl0 = (
+ if (!inClass) NoSymbol
+ else iface.owner.info.decl(implName) match {
+ case NoSymbol => NoSymbol
+ case implSym =>
// Unlink a pre-existing symbol only if the implementation class is
// visible on the compilation classpath. In general this is true under
// -optimise and not otherwise, but the classpath can use arbitrary
// logic so the classpath must be queried.
if (classPath.context.isValidName(implName + ".class")) {
- log("unlinking impl class " + impl)
- iface.owner.info.decls.unlink(impl)
- impl = NoSymbol
+ log("unlinking impl class " + implSym)
+ iface.owner.info.decls unlink implSym
+ NoSymbol
}
- else log("not unlinking existing " + impl + " as the impl class is not visible on the classpath.")
- }
- if (impl == NoSymbol) {
- impl = iface.cloneSymbolImpl(iface.owner, implClassFlags) setName implName
- impl.sourceFile = iface.sourceFile
- if (iface.owner.isClass)
- iface.owner.info.decls enter impl
- }
- if (currentRun.compiles(iface)) currentRun.symSource(impl) = iface.sourceFile
- impl setPos iface.pos
- if (impl.flags != implClassFlags) {
- log("!!! Directly setting impl class flags from %s to %s".format(flagsToString(impl.flags), flagsToString(implClassFlags)))
- impl.flags = implClassFlags
- }
- impl setInfo new LazyImplClassType(iface)
- implClassMap(iface) = impl
- debuglog(
- "generating impl class " + impl.debugLocationString + " in " + iface.owner + (
- if (originalImpl == NoSymbol) "" else " (cloned from " + originalImpl.debugLocationString + ")"
- )
- )
- impl
+ else {
+ log("not unlinking existing " + implSym + " as the impl class is not visible on the classpath.")
+ implSym
+ }
+ }
+ )
+ val impl = impl0 orElse {
+ val impl = iface.owner.newImplClass(implName, iface.pos, implFlags)
+ if (iface.thisSym != iface) {
+ impl.typeOfThis = iface.typeOfThis
+ impl.thisSym setName iface.thisSym.name
}
+ impl.sourceFile = iface.sourceFile
+ if (inClass)
+ iface.owner.info.decls enter impl
+
+ impl
+ }
+ if (currentRun compiles iface)
+ currentRun.symSource(impl) = iface.sourceFile
+
+ implClassMap(iface) = impl
+ impl setInfo new LazyImplClassType(iface)
+ }
+
+ /** Return the implementation class of a trait; create a new one of one does not yet exist */
+ def implClass(iface: Symbol): Symbol = {
+ iface.info
+
+ implClassMap.getOrElse(iface, atPhase(implClassPhase) {
+ log("Creating implClass for " + iface)
+ if (iface.implClass ne NoSymbol)
+ log("%s.implClass already exists: %s".format(iface, iface.implClass))
+
+ newImplClass(iface)
})
}
@@ -138,22 +137,31 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
* given the decls ifaceDecls of its interface.
*/
private def implDecls(implClass: Symbol, ifaceDecls: Scope): Scope = {
+ log("LazyImplClassType calculating decls for " + implClass)
+
val decls = newScope
- if ((ifaceDecls lookup nme.MIXIN_CONSTRUCTOR) == NoSymbol)
+ if ((ifaceDecls lookup nme.MIXIN_CONSTRUCTOR) == NoSymbol) {
+ log("Adding mixin constructor to " + implClass)
+
decls enter (
implClass.newMethod(nme.MIXIN_CONSTRUCTOR, implClass.pos)
setInfo MethodType(Nil, UnitClass.tpe)
)
+ }
- for (sym <- ifaceDecls.iterator) {
+ for (sym <- ifaceDecls) {
if (isInterfaceMember(sym)) {
if (needsImplMethod(sym)) {
- val impl = sym.cloneSymbol(implClass).resetFlag(lateDEFERRED)
- if (currentRun.compiles(implClass)) implMethodMap(sym) = impl
- decls enter impl
+ log("Cloning " + sym + " for implementation method in " + implClass)
+ val clone = sym.cloneSymbol(implClass).resetFlag(lateDEFERRED)
+ if (currentRun.compiles(implClass)) implMethodMap(sym) = clone
+ decls enter clone
sym setFlag lateDEFERRED
}
- } else {
+ else log(sym + " needs no implementation method in " + implClass)
+ }
+ else {
+ log("Destructively modifying owner of %s from %s to %s".format(sym, sym.owner, implClass))
sym.owner = implClass
// note: OK to destructively modify the owner here,
// because symbol will not be accessible from outside the sourcefile.
@@ -161,14 +169,17 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
decls enter sym
}
}
+
decls
}
- override def complete(sym: Symbol) {
+ override def complete(implSym: Symbol) {
+ log("LazyImplClassType completing " + implSym)
+
/** If `tp` refers to a non-interface trait, return a
* reference to its implementation class. Otherwise return `tp`.
*/
- def mixinToImplClass(tp: Type): Type = erasure(sym) {
+ def mixinToImplClass(tp: Type): Type = erasure(implSym) {
tp match { //@MATN: no normalize needed (comes after erasure)
case TypeRef(pre, sym, _) if sym.needsImplClass =>
typeRef(pre, implClass(sym), Nil)
@@ -179,15 +190,13 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
def implType(tp: Type): Type = tp match {
case ClassInfoType(parents, decls, _) =>
assert(phase == implClassPhase, tp)
- ClassInfoType(
- ObjectClass.tpe +: (parents.tail map mixinToImplClass filter (_.typeSymbol != ObjectClass)) :+ iface.tpe,
- implDecls(sym, decls),
- sym
- )
+ // Impl class parents: Object first, matching interface last.
+ val implParents = ObjectClass.tpe +: (parents.tail map mixinToImplClass filter (_.typeSymbol != ObjectClass)) :+ iface.tpe
+ ClassInfoType(implParents, implDecls(implSym, decls), implSym)
case PolyType(_, restpe) =>
implType(restpe)
}
- sym setInfo implType(beforeErasure(iface.info))
+ implSym setInfo implType(beforeErasure(iface.info))
}
override def load(clazz: Symbol) { complete(clazz) }
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 0c867b9e7e..ecfc2b6084 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -1134,10 +1134,10 @@ abstract class Erasure extends AddInterfaces
*/
override def transform(tree: Tree): Tree = {
val tree1 = preTransformer.transform(tree)
- log("tree after pretransform: "+tree1)
+ // log("tree after pretransform: "+tree1)
afterErasure {
val tree2 = mixinTransformer.transform(tree1)
- debuglog("tree after addinterfaces: \n" + tree2)
+ // debuglog("tree after addinterfaces: \n" + tree2)
newTyper(rootContext(unit, tree, true)).typed(tree2)
}
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala
index ac76862094..c8de25b2ea 100644
--- a/src/compiler/scala/tools/nsc/transform/Flatten.scala
+++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala
@@ -27,6 +27,7 @@ abstract class Flatten extends InfoTransform {
scope unlink old
scope enter sym
+ log("lifted " + sym.fullLocationString)
old
}
@@ -36,7 +37,7 @@ abstract class Flatten extends InfoTransform {
debuglog("re-enter " + sym.fullLocationString)
val old = replaceSymbolInCurrentScope(sym)
if (old ne NoSymbol)
- debuglog("lifted " + sym.fullLocationString + ", unlinked " + old)
+ log("unlinked " + old.fullLocationString + " after lifting " + sym)
}
}
private def liftSymbol(sym: Symbol) {