summaryrefslogtreecommitdiff
path: root/src/compiler/scala/reflect/internal/Symbols.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/reflect/internal/Symbols.scala')
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala166
1 files changed, 112 insertions, 54 deletions
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index a73ab32960..df6720d497 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -42,6 +42,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
m setModuleClass moduleClass
m
}
+ /** Create a new free variable. Its owner is NoSymbol.
+ */
+ def newFreeVar(name: TermName, tpe: Type, value: Any, flags: Long = 0L): FreeVar =
+ new FreeVar(name, value) initFlags flags setInfo tpe
/** The original owner of a class. Used by the backend to generate
* EnclosingMethod attributes.
@@ -79,7 +83,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private var rawpos = initPos
val id = { ids += 1; ids } // identity displayed when -uniqid
- //assert(id != 3204, initName)
var validTo: Period = NoPeriod
@@ -146,15 +149,18 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
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, flags: Long = 0L): TermSymbol =
new TermSymbol(this, pos, name) initFlags flags
- def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: Long = 0L): TypeSymbol =
- new TypeSymbol(this, pos, name) initFlags flags
+ def newAbstractTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: Long = 0L): AbstractTypeSymbol =
+ new AbstractTypeSymbol(this, pos, name) initFlags flags
+
+ def newAliasTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: Long = 0L): AliasTypeSymbol =
+ new AliasTypeSymbol(this, pos, name) initFlags flags
def newModuleSymbol(name: TermName, pos: Position = NoPosition, flags: Long = 0L): ModuleSymbol =
new ModuleSymbol(this, pos, name) initFlags flags
@@ -167,9 +173,21 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def newModuleClassSymbol(name: TypeName, pos: Position = NoPosition, flags: Long = 0L): ModuleClassSymbol =
new ModuleClassSymbol(this, pos, name) initFlags flags
+
+ /** 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, flags: Long = 0L): TypeSymbol =
+ if ((flags & DEFERRED) == 0L)
+ newAliasTypeSymbol(name, pos, flags)
+ else
+ newAbstractTypeSymbol(name, pos, flags)
def newTypeSkolemSymbol(name: TypeName, origin: AnyRef, pos: Position = NoPosition, flags: Long = 0L): TypeSkolem =
- new TypeSkolem(this, pos, name, origin) initFlags flags
+ if ((flags & DEFERRED) == 0L)
+ new TypeSkolem(this, pos, name, origin) initFlags flags
+ else
+ new TypeSkolem(this, pos, name, origin) with AbstractTypeMixin initFlags flags
/** @param pre type relative to which alternatives are seen.
* for instance:
@@ -211,12 +229,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Symbol of a type definition type T = ...
*/
final def newAliasType(name: TypeName, pos: Position = NoPosition, flags: Long = 0L): Symbol =
- newTypeSymbol(name, pos, flags)
+ newAliasTypeSymbol(name, pos, flags)
/** Symbol of an abstract type type T >: ... <: ...
*/
final def newAbstractType(name: TypeName, pos: Position = NoPosition, flags: Long = 0L): Symbol =
- newTypeSymbol(name, pos, DEFERRED | flags)
+ newAbstractTypeSymbol(name, pos, DEFERRED | flags)
/** Symbol of a type parameter
*/
@@ -231,11 +249,19 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
mmap(argtypess)(tp => newValueParameter(freshName(), focusPos(owner.pos), SYNTHETIC) setInfo tp)
}
+ /** Create a new existential type skolem with this symbol its owner,
+ * based on the given symbol and origin.
+ */
+ def newExistentialSkolem(basis: Symbol, origin: AnyRef): TypeSkolem = {
+ val skolem = newTypeSkolemSymbol(basis.name.toTypeName, origin, basis.pos, (basis.flags | EXISTENTIAL) & ~PARAM)
+ skolem setInfo (basis.info cloneInfo skolem)
+ }
+
final def newExistential(name: TypeName, pos: Position = NoPosition, flags: Long = 0L): Symbol =
newAbstractType(name, pos, EXISTENTIAL | flags)
final def freshExistential(suffix: String): Symbol =
- newExistential(pos, freshExistentialName(suffix))
+ newExistential(freshExistentialName(suffix), pos)
/** Synthetic value parameters when parameter symbols are not available.
* Calling this method multiple times will re-use the same parameter names.
@@ -1180,15 +1206,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* the bound of the type variable that stands for it
* pre: symbol is a term, a class, or an abstract type (no alias type allowed)
*/
- def existentialBound: Type =
- if (this.isClass)
- polyType(this.typeParams, TypeBounds.upper(this.classBound))
- else if (this.isAbstractType)
- this.info
- else if (this.isTerm)
- singletonBounds(this.tpe)
- else
- abort("unexpected alias type: "+this.ownerChain+ " " + hasFlagsToString(-1L))
+ def existentialBound: Type
/** Reset symbol to initial state
*/
@@ -1322,17 +1340,17 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** A clone of this symbol, but with given owner. */
final def cloneSymbol(owner: Symbol): Symbol = {
- val newSym = cloneSymbolImpl(owner)
+ val newSym = cloneSymbolImpl(owner, this.rawflags)
( newSym
- initFlags this.rawflags
setPrivateWithin privateWithin
setInfo (info cloneInfo newSym)
setAnnotations this.annotations
)
}
-
- /** Internal method to clone a symbol's implementation without flags or type. */
- def cloneSymbolImpl(owner: Symbol): Symbol
+
+ /** 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 --------------------------------------------------
@@ -2036,9 +2054,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
privateWithin = NoSymbol
var referenced: Symbol = NoSymbol
+
+ def existentialBound = singletonBounds(this.tpe)
- def cloneSymbolImpl(owner: Symbol): Symbol =
- owner.newTermSymbol(name, pos).copyAttrsFrom(this)
+ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ owner.newTermSymbol(name, pos, newFlags).copyAttrsFrom(this)
def copyAttrsFrom(original: TermSymbol): this.type = {
referenced = original.referenced
@@ -2134,8 +2154,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else rawname.toTermName
)
- override def cloneSymbolImpl(owner: Symbol): Symbol =
- owner.newModuleSymbol(name, pos).copyAttrsFrom(this)
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ owner.newModuleSymbol(name, pos, newFlags).copyAttrsFrom(this)
}
/** A class for method symbols */
@@ -2146,8 +2166,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private var mtpeResult: Type = _
private var mtpeInfo: Type = _
- override def cloneSymbolImpl(owner: Symbol): Symbol =
- owner.newMethodSymbol(name, pos).copyAttrsFrom(this)
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ owner.newMethodSymbol(name, pos, newFlags).copyAttrsFrom(this)
def typeAsMemberOf(pre: Type): Type = {
if (mtpePeriod == currentPeriod) {
@@ -2164,24 +2184,71 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
res
}
}
+
+ class AliasTypeSymbol(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)
+ }
+ final override def isAbstractType = true
+ override def existentialBound = this.info
+ }
/** A class of type symbols. Alias and abstract types are direct instances
* of this class. Classes are instances of a subclass.
*/
- class TypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName)
- extends Symbol(initOwner, initPos, initName) {
+ sealed abstract class TypeSymbol(initOwner: Symbol, initPos: Position, initName: TypeName) extends Symbol(initOwner, initPos, initName) {
privateWithin = NoSymbol
private var tyconCache: Type = null
private var tyconRunId = NoRunId
private var tpeCache: Type = _
private var tpePeriod = NoPeriod
+ /** Overridden in subclasses for which it makes sense.
+ */
+ def existentialBound: Type = abort("unexpected type: "+this.getClass+ " "+this.fullLocationString+ " " + hasFlagsToString(-1L))
+
override def name: TypeName = super.name.asInstanceOf[TypeName]
final override def isType = true
override def isNonClassType = true
- override def isAbstractType = isDeferred
- override def isAliasType = !isDeferred
-
+ override def isAbstractType = {
+ if (settings.debug.value) {
+ if (isDeferred) {
+ println("TypeSymbol claims to be abstract type: " + this.getClass + " " + hasFlagsToString(-1L) + " 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)
@@ -2278,7 +2345,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
}
- def cloneSymbolImpl(owner: Symbol): Symbol = owner.newTypeSymbol(name, pos)
+ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ owner.newTypeSymbol(name, pos, newFlags)
incCounter(typeSymbolCount)
}
@@ -2316,8 +2384,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
//@M! (not deSkolemize.typeParams!!), also can't leave superclass definition: use info, not rawInfo
override def typeParams = info.typeParams
- override def cloneSymbolImpl(owner: Symbol): Symbol =
- owner.newTypeSkolemSymbol(name, origin, pos)
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol =
+ owner.newTypeSkolemSymbol(name, origin, pos, newFlags)
override def nameString: String =
if (settings.debug.value) (super.nameString + "&" + level)
@@ -2335,6 +2403,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final override def isNonClassType = false
final override def isAbstractType = false
final override def isAliasType = false
+
+ override def existentialBound = polyType(this.typeParams, TypeBounds.upper(this.classBound))
override def sourceFile =
if (owner.isPackageClass) source
@@ -2397,8 +2467,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
thissym = newThisSym(pos).setInfo(tp)
}
- override def cloneSymbolImpl(owner: Symbol): Symbol = {
- val clone = owner.newClassSymbol(name, pos)
+ override def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = {
+ val clone = owner.newClassSymbol(name, pos, newFlags)
if (thisSym != this) {
clone.typeOfThis = typeOfThis
clone.thisSym.name = thisSym.name
@@ -2447,18 +2517,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def sourceModule = module
override def sourceModule_=(module: Symbol) { this.module = module }
}
-
- def newFreeVar(name0: TermName, tpe: Type, value: Any, flags: Long = 0L) =
- new FreeVar(name0, tpe, value) initFlags flags
-
- class FreeVar(name0: TermName, tpe: Type, val value: Any) extends TermSymbol(definitions.RootClass, NoPosition, name0) {
- setInfo(tpe)
+ class FreeVar(name0: TermName, val value: Any) extends TermSymbol(NoSymbol, NoPosition, name0) {
override def hashCode = value.hashCode
-
override def equals(other: Any): Boolean = other match {
case that: FreeVar => this.value.asInstanceOf[AnyRef] eq that.value.asInstanceOf[AnyRef]
- case _ => false
+ case _ => false
}
}
@@ -2485,10 +2549,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def alternatives: List[Symbol] = List()
override def reset(completer: Type) {}
override def info: Type = NoType
+ override def existentialBound: Type = NoType
override def rawInfo: Type = NoType
protected def doCookJavaRawInfo() {}
override def accessBoundary(base: Symbol): Symbol = RootClass
- def cloneSymbolImpl(owner: Symbol): Symbol = abort()
+ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol = abort()
override def originalEnclosingMethod = this
}
@@ -2560,13 +2625,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def mapParamss[T](sym: Symbol)(f: Symbol => T): List[List[T]] = mmap(sym.info.paramss)(f)
- /** Create a new existential type skolem with the given owner and origin.
- */
- def newExistentialSkolem(sym: Symbol, owner: Symbol, origin: AnyRef): TypeSkolem = {
- val skolem = owner.newTypeSkolemSymbol(sym.name.toTypeName, origin, sym.pos, (sym.flags | EXISTENTIAL) & ~PARAM)
- skolem setInfo (sym.info cloneInfo skolem)
- }
-
/** An exception for cyclic references of symbol definitions */
case class CyclicReference(sym: Symbol, info: Type)
extends TypeError("illegal cyclic reference involving " + sym) {