aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-02-07 13:37:57 +0100
committerMartin Odersky <odersky@gmail.com>2013-02-07 13:37:57 +0100
commit11a3d0d2792689d4992bef6dd0887dd5e8a08cb5 (patch)
tree9f070d0499fca617248c384873ceca065b007355 /src/dotty/tools
parentb9fa2c9f9f4d23ab7c9935a37496f4ac2bdc5fe9 (diff)
downloaddotty-11a3d0d2792689d4992bef6dd0887dd5e8a08cb5.tar.gz
dotty-11a3d0d2792689d4992bef6dd0887dd5e8a08cb5.tar.bz2
dotty-11a3d0d2792689d4992bef6dd0887dd5e8a08cb5.zip
Replacing Symbol forwarders by two implicits from Symbol to SymDenotation/ClassDenotation. Rearrangement of SymDenotation methods
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala12
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala542
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala261
3 files changed, 373 insertions, 442 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index f43fe5121..2c977f4be 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -132,7 +132,7 @@ object Denotations {
def isType: Boolean
/** Is this a reference to a term symbol? */
- final def isTerm: Boolean = !isType
+ def isTerm: Boolean = !isType
/** Is this denotation overloaded? */
def isOverloaded = isInstanceOf[MultiDenotation]
@@ -253,7 +253,7 @@ object Denotations {
}
abstract class SingleDenotation extends Denotation with DenotationSet {
- final override def isType = info.isInstanceOf[TypeType]
+ override def isType = info.isInstanceOf[TypeType]
override def signature: Signature = {
def sig(tp: Type): Signature = tp match {
case tp: PolyType =>
@@ -268,9 +268,9 @@ object Denotations {
}
def derivedSingleDenotation(s: Symbol, i: Type): SingleDenotation =
- if ((s eq symbol) && (i eq info)) this else copy(s, i)
+ if ((s eq symbol) && (i eq info)) this else newLikeThis(s, i)
- protected def copy(s: Symbol, i: Type): SingleDenotation = this
+ protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = this
def orElse(that: => SingleDenotation) = if (this.exists) this else that
@@ -372,14 +372,14 @@ object Denotations {
val info: Type,
initValidFor: Period) extends SingleDenotation {
validFor = initValidFor
- override protected def copy(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor)
+ override protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor)
}
class JointRefDenotation(val symbol: Symbol,
val info: Type,
initValidFor: Period) extends SingleDenotation {
validFor = initValidFor
- override protected def copy(s: Symbol, i: Type): SingleDenotation = new JointRefDenotation(s, i, validFor)
+ override protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new JointRefDenotation(s, i, validFor)
}
class ErrorDenotation(implicit ctx: Context) extends SingleDenotation {
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 9319e1573..df768cf61 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -17,42 +17,90 @@ object SymDenotations {
*/
abstract class SymDenotation(initFlags: FlagSet) extends SingleDenotation {
+// ----- denotation fields and accessors ------------------------------
+
+ /** The denoting symbol */
+ def symbol: Symbol
+
+ /** The owner. Owners form chains that always end in
+ * defn.RootClass
+ */
def owner: Symbol
+ /** The name */
def name: Name
+ /** The privateWithin boundary, NoSymbol if no boundary is given. */
def privateWithin: Symbol
- def symbol: Symbol
-
+ /** The type info.
+ * The info an instance of TypeType iff this is a type denotation
+ */
def info: Type
- // The following 5 members are overridden by instances of isLazy
- def isLoaded = true
- def isCompleted = true
- def exists(implicit ctx: Context) = true
- protected[core] def tryLoad(): Unit = unsupported("tryLoad")
- protected[core] def tryComplete(): Unit = unsupported("tryComplete")
+ /** The name with which the denoting symbol was created */
+ def originalName =
+ if (flags is ExpandedName) initial.asSymDenotation.name else name
- final def ensureLoaded() = if (!isLoaded) tryLoad()
- final def ensureCompleted() = if (!isCompleted) tryComplete()
+ /** The encoded full path name of this denotation, where outer names and inner names
+ * are separated by `separator` characters.
+ * Never translates expansions of operators back to operator symbol.
+ * Drops package objects.
+ */
+ def fullName(separator: Char)(implicit ctx: Context): Name =
+ if (this == NoSymbol || owner == NoSymbol || owner.isEffectiveRoot) name
+ else (effectiveOwner.enclosingClass.fullName(separator) :+ separator) ++ name
+
+ /** `fullName` where `.' is the separator character */
+ def fullName(implicit ctx: Context): Name = fullName('.')
+
+ /** The source or class file from which this denotation was generated, null if not applicable. */
+ def associatedFile(implicit ctx: Context): AbstractFile = topLevelClass.associatedFile
+
+ /** The class file from which this denotation was generated, null if not applicable. */
+ final def binaryFile(implicit ctx: Context): AbstractFile = pickFile(associatedFile, classFile = true)
+
+ /** The source file from which this denotation was generated, null if not applicable. */
+ final def sourceFile(implicit ctx: Context): AbstractFile = pickFile(associatedFile, classFile = false)
+
+ /** Desire to re-use the field in ClassSymbol which stores the source
+ * file to also store the classfile, but without changing the behavior
+ * of sourceFile (which is expected at least in the IDE only to
+ * return actual source code.) So sourceFile has classfiles filtered out.
+ */
+ private def pickFile(file: AbstractFile, classFile: Boolean): AbstractFile =
+ if ((file eq null) || classFile != (file.path endsWith ".class")) null else file
private[this] var _flags: FlagSet = initFlags
+ /** The flag set */
def flags: FlagSet = { ensureLoaded(); _flags }
- def flags_=(flags: FlagSet): Unit = { _flags = flags }
+
+ /** Update the flag set */
+ private[core] def flags_=(flags: FlagSet): Unit = { _flags = flags }
+
+ /** Set given flags(s) of this denotation */
def setFlag(flags: FlagSet): Unit = { _flags |= flags }
+
+ /** UnsSet given flags(s) of this denotation */
def resetFlag(flags: FlagSet): Unit = { _flags &~= flags }
private[this] var _annotations: List[Annotation] = Nil
+
+ /** The annotations of this denotation */
def annotations: List[Annotation] = { ensureCompleted(); _annotations }
- def annotations_=(annots: List[Annotation]): Unit = { _annotations = annots }
+ /** Update the annotations of this denotation */
+ private[core] def annotations_=(annots: List[Annotation]): Unit = { _annotations = annots }
+
+ /** Does this denotation have an annotation matching the given class symbol? */
def hasAnnotation(cls: Symbol) = dropOtherAnnotations(annotations, cls).nonEmpty
+ /** Add given annotation to the annotations of this denotation */
final def addAnnotation(annot: Annotation): Unit = annotations =
annot :: annotations
+ /** Record that the denoting symbol is an alias of given `alias` symbol */
final def setAlias(alias: Symbol)(implicit ctx: Context): Unit =
addAnnotation(Alias(alias))
@@ -62,9 +110,39 @@ object SymDenotations {
case Nil => Nil
}
- /** is this denotation a class? */
+// ----- completion ------------------------------
+
+ // The following 4 members are overridden by instances of isLazy
+
+ /** The denotation is loaded: flags and privateWithin are fully defined. */
+ def isLoaded = true
+
+ /** The denotation is completed: all attributes are fully defined */
+ def isCompleted = true
+
+ /** Try to load denotation. May throw `CyclicReference`. */
+ protected[core] def tryLoad(): Unit = unsupported("tryLoad")
+
+ /** Try to complete denotation. May throw `CyclicReference`. */
+ protected[core] def tryComplete(): Unit = unsupported("tryComplete")
+
+ /** Make sure denotation is loaded */
+ final def ensureLoaded() = if (!isLoaded) tryLoad()
+
+ /** Make sure denotation is completed */
+ final def ensureCompleted() = if (!isCompleted) tryComplete()
+
+// ----- tests -------------------------------------------------
+
+ /** Is this denotation a type? */
+ override def isType: Boolean = name.isTypeName
+
+ /** Is this denotation a class? */
final def isClass: Boolean = symbol.isInstanceOf[ClassSymbol]
+ /** Cast to class denotation */
+ final def asClass: ClassDenotation = asInstanceOf[ClassDenotation]
+
/** Special case tests for flags that are known a-priori and do not need loading
* flags.
*/
@@ -78,118 +156,48 @@ object SymDenotations {
/** is this denotation a method? */
//def isMethod: Boolean = false
- def originalName =
- if (flags is ExpandedName) initial.asSymDenotation.name else name
-
- def isSubClass(cls: Symbol)(implicit ctx: Context) = false
-
- def isNonBottomSubClass(cls: Symbol)(implicit ctx: Context) = false
-
- final def isSubClassOrCompanion(base: Symbol)(implicit ctx: Context): Boolean =
- isNonBottomSubClass(base) ||
- isModuleClass && linkedClass.isNonBottomSubClass(base)
-
- final def enclosingSubClass(implicit ctx: Context) = {
- val thissym = symbol
- ctx.owner.ownersIterator.findSymbol(_.isSubClass(thissym))
- }
-
/** is this symbol the result of an erroneous definition? */
def isError: Boolean = false
- final def ownersIterator(implicit ctx: Context) = new Iterator[Symbol] {
- private[this] var current = symbol
- def hasNext = current.exists
- def next: Symbol = {
- val result = current
- current = current.owner
- result
- }
- }
-
- final def hasTransOwner(sym: Symbol)(implicit ctx: Context): Boolean = {
- var o = symbol
- while ((o ne sym) && (o ne NoSymbol)) o = o.owner
- (o eq sym)
- }
-
-// def withType(tp: Type): SymDenotation = ???
-
- def asClass: ClassDenotation = asInstanceOf[ClassDenotation]
-
- override protected def copy(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor)
-
- /** The class implementing this module */
- def moduleClass(implicit ctx: Context): Symbol =
- if (this.isModuleVal) info.typeSymbol else NoSymbol
-
- /** The module implemented by this module class */
- def sourceModule(implicit ctx: Context): Symbol =
- if (this.isModuleClass) this.asClass.selfType.termSymbol else NoSymbol
-
- /** Desire to re-use the field in ClassSymbol which stores the source
- * file to also store the classfile, but without changing the behavior
- * of sourceFile (which is expected at least in the IDE only to
- * return actual source code.) So sourceFile has classfiles filtered out.
+ /** The denotation refers to an existing definition.
+ * @return `false` if denotation is either `NoDenotation` or it
+ * refers to a toplevel class or object that has no
+ * definition in the source or classfile from which it is loaded.
*/
- private def sourceFileOnly(file: AbstractFile): AbstractFile =
- if ((file eq null) || (file.path endsWith ".class")) null else file
-
- private def binaryFileOnly(file: AbstractFile): AbstractFile =
- if ((file eq null) || !(file.path endsWith ".class")) null else file
-
- final def effectiveOwner(implicit ctx: Context) = owner.skipPackageObject
-
- def enclosingClass(implicit ctx: Context): Symbol =
- if (isClass) symbol else owner.enclosingClass
+ def exists(implicit ctx: Context) = true
- final def topLevelClass(implicit ctx: Context): Symbol =
- if (!(owner.isPackageClass)) owner.topLevelClass
- else if (isClass) symbol
- else moduleClass
+ /** Is this symbol the root class or its companion object? */
+ def isRoot: Boolean = name.toTermName == nme.ROOT
- final def enclosingPackage(implicit ctx: Context): Symbol =
- if (isPackageClass) symbol else owner.enclosingPackage
+ /** Is this symbol the empty package class or its companion object? */
+ def isEmptyPackage(implicit ctx: Context): Boolean = name.toTermName == nme.EMPTY_PACKAGE && owner.isRoot
- def fullName(separator: Char)(implicit ctx: Context): Name =
- if (this == NoSymbol || owner == NoSymbol || owner.isEffectiveRoot) name
- else (effectiveOwner.enclosingClass.fullName(separator) :+ separator) ++ name
+ /** Is this symbol the empty package class or its companion object? */
+ def isEffectiveRoot(implicit ctx: Context) = isRoot || isEmptyPackage
- def associatedFile(implicit ctx: Context): AbstractFile = topLevelClass.associatedFile
- final def binaryFile(implicit ctx: Context): AbstractFile = binaryFileOnly(associatedFile)
- final def sourceFile(implicit ctx: Context): AbstractFile = sourceFileOnly(associatedFile)
+ /** Is this symbol an anonymous class? */
+ def isAnonymousClass(implicit ctx: Context): Boolean = initial.asSymDenotation.name startsWith tpnme.ANON_CLASS
- /** Is this symbol a type or stable term? */
- final def isStable(implicit ctx: Context) = !(
- isTerm &&
- this.is(UnstableValue, butNot = Stable) ||
- info.isVolatile && !hasAnnotation(defn.uncheckedStableClass)
- )
+ /** Is this definition contained in `boundary`?
+ * Same as `ownersIterator contains boundary` but more efficient.
+ */
+ final def isContainedIn(boundary: Symbol)(implicit ctx: Context): Boolean = {
+ def recur(sym: Symbol): Boolean =
+ if (sym eq boundary) true
+ else if (sym eq NoSymbol) false
+ else if (sym.isPackageClass && !boundary.isPackageClass) false
+ else recur(sym.owner)
+ recur(symbol)
+ }
+ /** Is this denotation static (i.e. with no outer instance)? */
def isStatic(implicit ctx: Context) = (this is Static) || owner.isStaticOwner
+ /** Is this a package class or module class that defines static symbols? */
final def isStaticOwner(implicit ctx: Context): Boolean =
isPackageClass || isModuleClass && isStatic
- final def matchingSymbol(inClass: Symbol, site: Type)(implicit ctx: Context): Symbol = {
- var denot = inClass.info.nonPrivateDecl(name)
- if (denot.isTerm) {
- val targetType = site.memberInfo(symbol)
- if (denot.isOverloaded)
- denot = denot.atSignature(targetType.signature)
- if (!(site.memberInfo(denot.symbol) matches targetType))
- denot = NoDenotation
- }
- denot.symbol
- }
-
- final def overriddenSymbol(inClass: ClassSymbol)(implicit ctx: Context): Symbol =
- if (owner isSubClass inClass) matchingSymbol(inClass, owner.thisType)
- else NoSymbol
-
- final def allOverriddenSymbols(implicit ctx: Context): Iterator[Symbol] =
- info.baseClasses.tail.iterator map overriddenSymbol filter (_.exists)
-
+ /** Is this denotation defined in the same scope and compilation unit as that symbol? */
def isCoDefinedWith(that: Symbol)(implicit ctx: Context) =
(this.effectiveOwner == that.effectiveOwner) &&
( !(this.effectiveOwner.isPackageClass)
@@ -199,41 +207,41 @@ object SymDenotations {
|| (this.sourceFile.canonicalPath == that.sourceFile.canonicalPath)
)
- def companionModule(implicit ctx: Context): Symbol = {
- owner.info.decl(name.toTermName)
- .filter(sym => sym.isModule && sym.isCoDefinedWith(symbol))
- .symbol
- }
+ /** Is this a denotation of a stable term? */
+ final def isStable(implicit ctx: Context) = !(
+ isTerm &&
+ this.is(UnstableValue, butNot = Stable) ||
+ info.isVolatile && !hasAnnotation(defn.uncheckedStableClass)
+ )
- def companionClass(implicit ctx: Context): Symbol =
- owner.info.decl(name.toTypeName)
- .filter(sym => sym.isClass && sym.isCoDefinedWith(symbol))
- .symbol
+ /** Is this a subclass of the given class `base`? */
+ def isSubClass(base: Symbol)(implicit ctx: Context) = false
- def linkedClass(implicit ctx: Context): Symbol =
- if (this.isModuleClass) companionClass
- else if (this.isClass) companionModule.moduleClass
- else NoSymbol
+ /** Is this a subclass of `base`,
+ * and is the denoting symbol also different from `Null` or `Nothing`?
+ */
+ def isNonBottomSubClass(base: Symbol)(implicit ctx: Context) = false
- final def accessBoundary(base: Symbol)(implicit ctx: Context): Symbol = {
- val fs = flags
- if (fs is PrivateOrLocal) owner
- else if (fs is StaticProtected) defn.RootClass
- else if (privateWithin.exists && !ctx.phase.erasedTypes) privateWithin
- else if (fs is Protected) base
- else defn.RootClass
- }
+ /** Is this a subclass of `base` or a companion object of such a subclass? */
+ final def isSubClassOrCompanion(base: Symbol)(implicit ctx: Context): Boolean =
+ isNonBottomSubClass(base) ||
+ isModuleClass && linkedClass.isNonBottomSubClass(base)
- final def isContainedIn(boundary: Symbol)(implicit ctx: Context): Boolean =
- if (symbol eq boundary) true
- else if (!this.exists ||
- (this.isPackageClass) && !(boundary.isPackageClass)) false
- else owner.isContainedIn(boundary)
+ /** Is this symbol a class that does not extend `AnyVal`? */
+ def isNonValueClass(implicit ctx: Context): Boolean =
+ isClass && !isSubClass(defn.AnyValClass)
+ /** Is this definition accessible whenever `that` symbol is accessible?
+ * Does not take into account status of protected members.
+ */
def isAsAccessibleAs(that: Symbol)(implicit ctx: Context): Boolean =
- (that.accessBoundary(NoSymbol) isContainedIn this.accessBoundary(NoSymbol)) &&
- (this.isStable || !that.isStable)
+ (that.accessBoundary(NoSymbol) isContainedIn this.accessBoundary(NoSymbol)) &&
+ (this.isStable || !that.isStable)
+ /** Is this definition accessible as a member of tree with type `pre`?
+ * @param pre The type of the tree from which the selection is made
+ * @param superAccess Access is via super
+ */
def isAccessibleFrom(pre: Type, superAccess: Boolean = false)(implicit ctx: Context): Boolean = {
def accessWithinLinked(boundary: Symbol) = {
@@ -243,7 +251,7 @@ object SymDenotations {
/** Are we inside definition of `boundary`? */
def accessWithin(boundary: Symbol) =
- owner.hasTransOwner(boundary) &&
+ owner.isContainedIn(boundary) &&
(!(this is JavaDefined) ||
owner.enclosingPackage == boundary.enclosingPackage)
@@ -297,29 +305,161 @@ object SymDenotations {
}
}
- def isNonValueClass(implicit ctx: Context): Boolean =
- isClass && !isSubClass(defn.AnyValClass)
+ // def isOverridable: Boolean = !!! need to enforce that classes cannot be redefined
+ // def isSkolem: Boolean = ???
+
+// ------ access to related symbols ---------------------------------
- def typeParams(implicit ctx: Context): List[TypeSymbol] = unsupported("typeParams")
+ /** The class implementing this module, NoSymbol if not applicable. */
+ final def moduleClass(implicit ctx: Context): Symbol =
+ if (this.isModuleVal) info.typeSymbol else NoSymbol
+
+ /** The module implemented by this module class, NoSymbol if not applicable. */
+ final def sourceModule(implicit ctx: Context): Symbol =
+ if (this.isModuleClass) this.asClass.selfType.termSymbol else NoSymbol
+ /** The chain of owners of this denotation, starting with the denoting symbol itself */
+ final def ownersIterator(implicit ctx: Context) = new Iterator[Symbol] {
+ private[this] var current = symbol
+ def hasNext = current.exists
+ def next: Symbol = {
+ val result = current
+ current = current.owner
+ result
+ }
+ }
+
+ /** If this is a package object or its implementing class, its owner,
+ * otherwise the denoting symbol.
+ */
+ final def skipPackageObject(implicit ctx: Context): Symbol =
+ if (this is PackageObject) owner else symbol
+
+ /** The owner, skipping package objects. */
+ final def effectiveOwner(implicit ctx: Context) = owner.skipPackageObject
+
+ /** The class containing this denotation.
+ * If this denotation is already a class, return itself
+ */
+ def enclosingClass(implicit ctx: Context): Symbol =
+ if (isClass) symbol else owner.enclosingClass
+
+ /** The top-level class containing this denotation,
+ * except for a toplevel module, where its module class is returned.
+ */
+ final def topLevelClass(implicit ctx: Context): Symbol =
+ if (!(owner.isPackageClass)) owner.topLevelClass
+ else if (isClass) symbol
+ else moduleClass
+
+ /** The package containing this denotation */
+ final def enclosingPackage(implicit ctx: Context): Symbol =
+ if (isPackageClass) symbol else owner.enclosingPackage
+
+ /** The module object with the same (term-) name as this class or module class,
+ * and which is also defined in the same scope and compilation unit.
+ * NoSymbol if this module does not exist.
+ */
+ def companionModule(implicit ctx: Context): Symbol = {
+ owner.info.decl(name.toTermName)
+ .filter(sym => sym.isModule && sym.isCoDefinedWith(symbol))
+ .symbol
+ }
+
+ /** The class with the same (type-) name as this module or module class,
+ * and which is also defined in the same scope and compilation unit.
+ * NoSymbol if this class does not exist.
+ */
+ def companionClass(implicit ctx: Context): Symbol =
+ owner.info.decl(name.toTypeName)
+ .filter(sym => sym.isClass && sym.isCoDefinedWith(symbol))
+ .symbol
+
+ /** If this is a class, the module class of its companion object.
+ * If this is a module class, its companion class.
+ * NoSymbol otherwise.
+ */
+ def linkedClass(implicit ctx: Context): Symbol =
+ if (this.isModuleClass) companionClass
+ else if (this.isClass) companionModule.moduleClass
+ else NoSymbol
+
+ /** The class that encloses the owner of the current context
+ * and that is a subclass of this class. NoSymbol if no such class exists.
+ */
+ final def enclosingSubClass(implicit ctx: Context) = {
+ val thissym = symbol
+ ctx.owner.ownersIterator.findSymbol(_.isSubClass(thissym))
+ }
+
+ /** The non-private symbol whose type matches the type of this symbol
+ * in the given class.
+ * @param inClass The class containing the symbol's definition
+ * @param site The base type from which member types are computed
+ */
+ final def matchingSymbol(inClass: Symbol, site: Type)(implicit ctx: Context): Symbol = {
+ var denot = inClass.info.nonPrivateDecl(name)
+ if (denot.isTerm) {
+ val targetType = site.memberInfo(symbol)
+ if (denot.isOverloaded)
+ denot = denot.atSignature(targetType.signature)
+ if (!(site.memberInfo(denot.symbol) matches targetType))
+ denot = NoDenotation
+ }
+ denot.symbol
+ }
+
+ /** The symbol, in class `inClass`, that is overridden by this denotation. */
+ final def overriddenSymbol(inClass: ClassSymbol)(implicit ctx: Context): Symbol =
+ if (owner isSubClass inClass) matchingSymbol(inClass, owner.thisType)
+ else NoSymbol
+
+ /** All symbols overriden by this denotation. */
+ final def allOverriddenSymbols(implicit ctx: Context): Iterator[Symbol] =
+ info.baseClasses.tail.iterator map overriddenSymbol filter (_.exists)
+
+ /** The class or term symbol up to which this symbol is accessible,
+ * or RootClass if it is public. As java protected statics are
+ * otherwise completely inaccessible in scala, they are treated
+ * as public.
+ * @param base The access boundary to assume if this symbol is protected
+ */
+ final def accessBoundary(base: Symbol)(implicit ctx: Context): Symbol = {
+ val fs = flags
+ if (fs is PrivateOrLocal) owner
+ else if (fs is StaticProtected) defn.RootClass
+ else if (privateWithin.exists && !ctx.phase.erasedTypes) privateWithin
+ else if (fs is Protected) base
+ else defn.RootClass
+ }
+
+ // ----- type-related ------------------------------------------------
+
+ /** The type parameters of a class symbol, Nil for all other symbols */
+ def typeParams(implicit ctx: Context): List[TypeSymbol] = Nil
+
+ /** The type This(cls), where cls is this class, NoPrefix for all other symbols */
def thisType(implicit ctx: Context): Type = NoPrefix
+ /** The type representing the type constructor for this type,
+ * @throws ClassCastException is this is not a type
+ */
def typeConstructor(implicit ctx: Context): TypeRef =
TypeRef(owner.thisType, name.asTypeName)
+ /** The variance of this type parameter as an Int, with
+ * +1 = Covariant, -1 = Contravariant, 0 = Nonvariant, or not a type parameter
+ */
def variance: Int =
if (this is Covariant) 1
else if (this is Contravariant) -1
else 0
- def isRoot: Boolean = name.toTermName == nme.ROOT
+ // ----- copies ------------------------------------------------------
- def isEmptyPackage(implicit ctx: Context): Boolean = name.toTermName == nme.EMPTY_PACKAGE && owner.isRoot
-
- def isEffectiveRoot(implicit ctx: Context) = isRoot || isEmptyPackage
-
- def isAnonymousClass(implicit ctx: Context): Boolean = initial.asSymDenotation.name startsWith tpnme.ANON_CLASS
+ override protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor)
+ /** Copy this denotation, overriding selective fields */
def copy(
sym: Symbol,
owner: Symbol = this.owner,
@@ -330,43 +470,54 @@ object SymDenotations {
new CompleteSymDenotation(sym, owner, name, initFlags, privateWithin, info)
}
- // Note: important to leave initctx non-implicit, and to check that it is not
- // retained after object construction.
+ /** The contents of a class definition during a period
+ * Note: important to leave initctx non-implicit, and to check that it is not
+ * retained after object construction.
+ */
abstract class ClassDenotation(initFlags: FlagSet, assocFile: AbstractFile)(initctx: Context)
extends SymDenotation(initFlags) {
import NameFilter._
import util.LRU8Cache
- val symbol: ClassSymbol
+// ----- denotation fields and accessors ------------------------------
+ override val symbol: ClassSymbol
+
+ /** The parent types of this class.
+ * These are all normalized to be TypeRefs by moving any refinements
+ * to be member definitions of the class itself. */
def parents: List[TypeRef]
+ /** The type of `this` in this class */
def selfType: Type
+ /** The symbols defined directly in this class */
def decls: Scope
- val info = ClassInfo(owner.thisType(initctx), this)(initctx)
+ override val info = {
+ implicit val ctx = initctx
+ ClassInfo(owner.thisType, this)
+ }
override def associatedFile(implicit ctx: Context): AbstractFile = assocFile
private[this] var _typeParams: List[TypeSymbol] = _
+ /** The type parameters of this class. Loads the class but does not complete it. */
override final def typeParams(implicit ctx: Context): List[TypeSymbol] = {
val tparams = _typeParams
if (tparams != null) tparams else computeTypeParams
}
+ /** The symbols defined in this class when the class is loaded but
+ * not yet completed.
+ */
+ protected def preCompleteDecls: Scope
+
private def computeTypeParams(implicit ctx: Context): List[TypeSymbol] =
(preCompleteDecls.toList filter (_ is TypeParam)).asInstanceOf[List[TypeSymbol]]
- protected def preCompleteDecls: Scope
-
- private[this] var memberCacheVar: LRU8Cache[Name, DenotationSet] = null
-
- private def memberCache: LRU8Cache[Name, DenotationSet] = {
- if (memberCacheVar == null) memberCacheVar = new LRU8Cache
- memberCacheVar
- }
+// ------ class-specific operations -----------------------------------
private[this] var _thisType: Type = null
@@ -389,17 +540,8 @@ object SymDenotations {
_typeConstructor
}
- /*
- private[this] var typeTemplateCache: Type = null
-
- def typeTemplate(implicit ctx: Context): Type = {
- if (typeTemplateCache == null)
- AppliedType.make(typeConstructor, typeParams map (_.typeConstructor))
- typeTemplateCache
- }
-*/
- private[this] var baseClassesVar: List[ClassSymbol] = null
- private[this] var superClassBitsVar: BitSet = null
+ private[this] var _baseClasses: List[ClassSymbol] = null
+ private[this] var _superClassBits: BitSet = null
private def computeSuperClassBits(implicit ctx: Context): Unit = {
val seen = new mutable.BitSet
@@ -425,31 +567,34 @@ object SymDenotations {
case _ =>
to
}
- baseClassesVar = symbol :: addParentBaseClasses(parents, Nil)
- superClassBitsVar = ctx.uniqueBits.findEntryOrUpdate(seen.toImmutable)
+ _baseClasses = symbol :: addParentBaseClasses(parents, Nil)
+ _superClassBits = ctx.uniqueBits.findEntryOrUpdate(seen.toImmutable)
}
- def superClassBits(implicit ctx: Context): BitSet = {
- if (superClassBitsVar == null) computeSuperClassBits
- superClassBitsVar
+ private def superClassBits(implicit ctx: Context): BitSet = {
+ if (_superClassBits == null) computeSuperClassBits
+ _superClassBits
}
- def baseClasses(implicit ctx: Context): List[ClassSymbol] = {
- if (baseClassesVar == null) computeSuperClassBits
- baseClassesVar
+ /** The base classes of this class in linearization order,
+ * with the class itself as first element.
+ */
+ def baseClasses(implicit ctx: Context): List[ClassSymbol] = {
+ if (_baseClasses == null) computeSuperClassBits
+ _baseClasses
}
- final override def isNonBottomSubClass(cls: Symbol)(implicit ctx: Context): Boolean =
- (symbol eq cls) ||
- (superClassBits contains cls.superId) ||
+ final override def isNonBottomSubClass(base: Symbol)(implicit ctx: Context): Boolean =
+ (symbol eq base) ||
+ (superClassBits contains base.superId) ||
(this is Erroneous) ||
- (cls is Erroneous) && cls.isClass
+ (base is Erroneous) && base.isClass
- final override def isSubClass(cls: Symbol)(implicit ctx: Context) =
- isNonBottomSubClass(cls) ||
- cls.isClass && ((symbol eq defn.NothingClass) || (symbol eq defn.NullClass))
+ final override def isSubClass(base: Symbol)(implicit ctx: Context) =
+ isNonBottomSubClass(base) ||
+ base.isClass && ((symbol eq defn.NothingClass) || (symbol eq defn.NullClass))
- private[this] var definedFingerPrintCache: FingerPrint = null
+ private[this] var _definedFingerPrint: FingerPrint = null
private def computeDefinedFingerPrint(implicit ctx: Context): FingerPrint = {
var bits = newNameFilter
@@ -469,10 +614,16 @@ object SymDenotations {
}
ps = ps.tail
}
- definedFingerPrintCache = bits
+ _definedFingerPrint = bits
bits
}
+ private[this] var _memberCache: LRU8Cache[Name, DenotationSet] = null
+
+ private def memberCache: LRU8Cache[Name, DenotationSet] = {
+ if (_memberCache == null) _memberCache = new LRU8Cache
+ _memberCache
+ }
/** Enter a symbol in current scope.
* Note: We require that this does not happen after the first time
* someone does a findMember on a subclass.
@@ -480,9 +631,9 @@ object SymDenotations {
def enter(sym: Symbol)(implicit ctx: Context) = {
require(!(this is Frozen))
decls enter sym
- if (definedFingerPrintCache != null)
- includeName(definedFingerPrintCache, sym.name)
- if (memberCacheVar != null)
+ if (_definedFingerPrint != null)
+ includeName(_definedFingerPrint, sym.name)
+ if (_memberCache != null)
memberCache invalidate sym.name
}
@@ -493,14 +644,14 @@ object SymDenotations {
def delete(sym: Symbol)(implicit ctx: Context) = {
require(!(this is Frozen))
decls unlink sym
- if (definedFingerPrintCache != null)
+ if (_definedFingerPrint != null)
computeDefinedFingerPrint
- if (memberCacheVar != null)
+ if (_memberCache != null)
memberCache invalidate sym.name
}
def definedFingerPrint(implicit ctx: Context): FingerPrint = {
- val fp = definedFingerPrintCache
+ val fp = _definedFingerPrint
if (fp != null) fp else computeDefinedFingerPrint
}
@@ -681,11 +832,14 @@ object SymDenotations {
}
object NoDenotation extends SymDenotation(EmptyFlags) {
+ override def isTerm = false
+ override def isType = false
override def symbol: Symbol = NoSymbol
override def owner: Symbol = throw new AssertionError("NoDenotation.owner")
override def name: Name = "<none>".toTermName
override def info: Type = NoType
override def privateWithin = NoSymbol
+ override def exists(implicit ctx: Context) = false
}
// ---- Completion --------------------------------------------------------
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index 86cb70d34..348fc4848 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -114,8 +114,17 @@ object Symbols {
/** This symbol, if it exists, otherwise the result of evaluating `that` */
def orElse(that: => Symbol) = if (exists) this else that
+ /** If this symbol satisfies predicate `p` this symbol, otherwise `NoSymbol` */
def filter(p: Symbol => Boolean): Symbol = if (p(this)) this else NoSymbol
+ private[this] var _id: Int = _
+
+ /** The unique id of this symbol */
+ def id(implicit ctx: Context) = {
+ if (_id == 0) _id = ctx.nextId
+ _id
+ }
+
/** The last denotation of this symbol */
private[this] var lastDenot: SymDenotation = denotf(this)
@@ -126,21 +135,13 @@ object Symbols {
denot
}
- private[this] var _id: Int = _
-
- /** The unique id of this symbol */
- def id(implicit ctx: Context) = {
- if (_id == 0) _id = ctx.nextId
- _id
- }
-
/** Subclass tests and casts */
- final def isTerm: Boolean = isInstanceOf[TermSymbol]
- final def isType: Boolean = isInstanceOf[TypeSymbol]
+ final def isTerm(implicit ctx: Context): Boolean = denot.isTerm
+ final def isType(implicit ctx: Context): Boolean = denot.isType
final def isClass: Boolean = isInstanceOf[ClassSymbol]
- final def asTerm: TermSymbol = asInstanceOf[TermSymbol]
- final def asType: TypeSymbol = asInstanceOf[TypeSymbol]
+ final def asTerm(implicit ctx: Context): TermSymbol = { assert(isTerm, this); asInstanceOf[TermSymbol] }
+ final def asType(implicit ctx: Context): TypeSymbol = { assert(isType, this); asInstanceOf[TypeSymbol] }
final def asClass: ClassSymbol = asInstanceOf[ClassSymbol]
/** A unique, densely packed integer tag for each class symbol, -1
@@ -150,7 +151,7 @@ object Symbols {
def superId: Int = -1
final def entered(implicit ctx: Context): this.type = {
- owner.info.decls.enter(this)
+ this.owner.info.decls.enter(this)
this
}
@@ -160,227 +161,14 @@ object Symbols {
/** Is symbol a phantom class for which no runtime representation exists? */
def isPhantomClass(implicit ctx: Context) = defn.PhantomClasses contains this
- // --------- Forwarders for sym methods --------------------------
-
- /** Special case tests for flags that are known a-priori and do not need loading
- * flags.
- */
- def isModule(implicit ctx: Context) = denot.isModule
- def isModuleObj(implicit ctx: Context) = denot.isModuleVal
- def isModuleClass(implicit ctx: Context) = denot.isModuleClass
- def isPackage(implicit ctx: Context) = denot.isPackage
- def isPackageObj(implicit ctx: Context) = denot.isPackageVal
- def isPackageClass(implicit ctx: Context) = denot.isPackageClass
-
- /** The current owner of this symbol */
- final def owner(implicit ctx: Context): Symbol = denot.owner
-
/** The current name of this symbol */
final def name(implicit ctx: Context): ThisName = denot.name.asInstanceOf[ThisName]
- /** The current type info of this symbol */
- final def info(implicit ctx: Context): Type = denot.info
-
- /** The current flag set of this symbol */
- final def flags(implicit ctx: Context): FlagSet = denot.flags
-
- /** The current privateWithin boundary of this symbol, NoSymbol if no boundary is given. */
- final def privateWithin(implicit ctx: Context): Symbol = denot.privateWithin
-
- /** The current annotations of this symbol */
- final def annotations(implicit ctx: Context): List[Annotation] = denot.annotations
-
- /** The name with which this symbol was created */
- def originalName(implicit ctx: Context) = denot.originalName
-
- /** Set given flags(s) of this symbol */
- def setFlag(flags: FlagSet)(implicit ctx: Context): Unit = denot.setFlag(flags)
-
- /** Unset given flag(s) of this symbol */
- def resetFlag(flags: FlagSet)(implicit ctx: Context): Unit = denot.resetFlag(flags)
-
- /** Does this symbol have an annotation matching the given class symbol? */
- final def hasAnnotation(cls: Symbol)(implicit ctx: Context): Boolean = denot.hasAnnotation(cls)
-
- /** Add given annotation to this symbol */
- final def addAnnotation(annot: Annotation)(implicit ctx: Context): Unit = denot.addAnnotation(annot)
-
- /** Record that this symbol is an alias of given `alias` symbol */
- final def setAlias(alias: Symbol)(implicit ctx: Context): Unit = denot.setAlias(alias)
-
- /** The chain of owners of this symbol, starting with the symbol itself */
- final def ownersIterator(implicit ctx: Context): Iterator[Symbol] = denot.ownersIterator
-
- /** Same as `ownersIterator contains sym` but more efficient. */
- final def hasTransOwner(sym: Symbol)(implicit ctx: Context): Boolean = denot.hasTransOwner(sym)
-
- /** The owner, skipping package objects. */
- def effectiveOwner(implicit ctx: Context) = denot.effectiveOwner
-
- /** If this is a package object or its implementing class, its owner: otherwise this.
- */
- def skipPackageObject(implicit ctx: Context): Symbol = if (this is PackageObject) owner else this
-
- /** The class containing this symbol */
- def enclosingClass(implicit ctx: Context): Symbol = denot.enclosingClass
-
- /** The top-level class containing this symbol, except for a toplevel module
- * its module class
- */
- def topLevelClass(implicit ctx: Context): Symbol = denot.topLevelClass
-
- /** The package containing this symbol */
- def enclosingPackage(implicit ctx: Context): Symbol = denot.enclosingPackage
-
- /** The encoded full path name of this symbol, where outer names and inner names
- * are separated by `separator` characters.
- * Never translates expansions of operators back to operator symbol.
- * Drops package objects.
- */
- final def fullName(separator: Char)(implicit ctx: Context): Name = denot.fullName(separator)
- final def fullName(implicit ctx: Context): Name = fullName('.')
-
- /** The source or class file from which this symbol was generated, null if not applicable. */
- final def associatedFile(implicit ctx: Context): AbstractFile = denot.associatedFile
-
- /** The class file from which this symbol was generated, null if not applicable. */
- final def binaryFile(implicit ctx: Context): AbstractFile = denot.binaryFile
-
- /** The source or class file from which this symbol was generated, null if not applicable. */
- final def sourceFile(implicit ctx: Context): AbstractFile = denot.sourceFile
-
- /** Is this symbol defined in the same compilation unit as that symbol? */
- final def isCoDefinedWith(that: Symbol)(implicit ctx: Context): Boolean = denot.isCoDefinedWith(that)
-
- /** The class with the same (type-) name as this module or module class,
- * which is the defined in the same compilation unit.
- * NoSymbol if this class does not exist.
- */
- final def companionClass(implicit ctx: Context): Symbol = denot.companionClass
-
- /** The module object with the same (term-) name as this class or module class,
- * which is the defined in the same compilation unit.
- * NoSymbol if this class does not exist.
- */
- final def companionModule(implicit ctx: Context): Symbol = denot.companionModule
-
- /** If this is a class, the module class of its companion object.
- * If this is a module class, its companion class.
- * NoSymbol otherwise.
- */
- final def linkedClass(implicit ctx: Context): Symbol = denot.linkedClass
-
- /** Is this symbol a subclass of the given class? */
- final def isSubClass(cls: Symbol)(implicit ctx: Context): Boolean = denot.isSubClass(cls)
-
- /** Is this class symbol a subclass of `cls`,
- * and is this class symbol also different from Null or Nothing?
- */
- final def isNonBottomSubClass(cls: Symbol)(implicit ctx: Context): Boolean = denot.isNonBottomSubClass(cls)
-
- /** Is this symbol a subclass of `base` or a companion object of such a subclass? */
- final def isSubClassOrCompanion(base: Symbol)(implicit ctx: Context): Boolean = denot.isSubClassOrCompanion(base)
-
- /** The class that encloses the owner of the current context
- * and that is a subclass of this class.
- */
- final def enclosingSubClass(implicit ctx: Context) = denot.enclosingSubClass
-
- ///** Is this symbol a proper subclass of the given class? */
- //def isProperSubClass(cls: ClassSymbol)(implicit ctx: Context): Boolean = (this ne cls) && this.isSubClass(cls)
-
- /** The non-private symbol whose type matches the type of this symbol
- * in in given class.
- *
- * @param inClass The class containing the symbol's definition
- * @param site The base type from which member types are computed
- */
- final def matchingSymbol(inClass: Symbol, site: Type)(implicit ctx: Context): Symbol = denot.matchingSymbol(inClass, site)
-
- /** The symbol, in class `inClass`, that is overridden by this symbol. */
- final def overriddenSymbol(inClass: ClassSymbol)(implicit ctx: Context): Symbol = denot.overriddenSymbol(inClass)
-
- /** All symbols overriden by this symbol. */
- final def allOverriddenSymbols(implicit ctx: Context): Iterator[Symbol] = denot.allOverriddenSymbols
-
- /** The class or term symbol up to which this symbol is accessible,
- * or RootClass if it is public. As java protected statics are
- * otherwise completely inaccessible in scala, they are treated
- * as public.
- * @param base
- */
- final def accessBoundary(base: Symbol)(implicit ctx: Context): Symbol = denot.accessBoundary(base)
-
- /** Is this symbol contained in `boundary`? */
- final def isContainedIn(boundary: Symbol)(implicit ctx: Context): Boolean = denot.isContainedIn(boundary)
-
- /** Is this symbol accessible whenever `that` symbol is accessible?
- * Does not take into account status of protected members.
- */
- final def isAsAccessibleAs(that: Symbol)(implicit ctx: Context): Boolean = denot.isAsAccessibleAs(that)
-
- /** Is this symbol a non-value class? */
- final def isNonValueClass(implicit ctx: Context): Boolean = denot.isNonValueClass
-
- /** Is this symbol accessible as a member of tree with type `pre`?
- * @param pre The type of the tree from which the selection is made
- * @param superAccess Access is via super
- */
- final def isAccessibleFrom(pre: Type, superAccess: Boolean = false)(implicit ctx: Context): Boolean = denot.isAccessibleFrom(pre, superAccess)
-
def show(implicit ctx: Context): String = ctx.show(this)
def showLocated(implicit ctx: Context): String = ctx.showLocated(this)
def showDef(implicit ctx: Context): String = ctx.showDef(this)
def showKind(implicit tcx: Context): String = ???
def showName(implicit ctx: Context): String = ???
-
- /** The type parameters of a class symbol, Nil for all other symbols */
- def typeParams(implicit ctx: Context): List[TypeSymbol] = denot.typeParams
-
- /** The type This(cls), where cls is this class symbol */
- def thisType(implicit ctx: Context): Type = denot.thisType
-
- /** Is this symbol the root class or its companion object? */
- def isRoot(implicit ctx: Context): Boolean = denot.isRoot
-
- /** Is this symbol the empty package class or its companion object? */
- def isEmptyPackage(implicit ctx: Context): Boolean = denot.isEmptyPackage
-
- /** Is this symbol an anonymous class? */
- def isAnonymousClass(implicit ctx: Context): Boolean = denot.isAnonymousClass
-
- /** Is this symbol the root class, empty package class, or one of their companion objects? */
- def isEffectiveRoot(implicit ctx: Context): Boolean = denot.isEffectiveRoot
-
- /** If this is a module symbol, the class defining its template, otherwise NoSymbol. */
- def moduleClass(implicit ctx: Context): Symbol = denot.moduleClass
-
- /** Can a term with this symbol be a stable value? */
- def isStable(implicit ctx: Context): Boolean = denot.isStable
-
- /** Is this symbol static (i.e. with no outer instance)? */
- def isStatic(implicit ctx: Context): Boolean = denot.isStatic
-
- /** Does this symbol denote a class that defines static symbols? */
- final def isStaticOwner(implicit ctx: Context): Boolean = denot.isStaticOwner
-
- // def isOverridable: Boolean = !!! need to enforce that classes cannot be redefined
-
- // def isSkolem: Boolean = ???
-
- // def isAbstractType: Boolean = ???
- // def newAbstractType(name: TypeName, info: TypeBounds): TypeSymbol = ???
- // def newAbstractTerm(name: TermName, tpe: Type): TypeSymbol = ???
-
- //def isMethod(implicit ctx: Context): Boolean = denot.isMethod
-
- /** The type representing the type constructor for this type symbol */
- def typeConstructor(implicit ctx: Context): TypeRef = denot.typeConstructor
-
- /** The variance of this type parameter as an Int, with
- * +1 = Covariant, -1 = Contravariant, 0 = Nonvariant
- */
- def variance(implicit ctx: Context): Int = denot.variance
}
type TermSymbol = Symbol { type ThisName = TermName }
@@ -390,25 +178,10 @@ object Symbols {
type ThisName = TypeName
- private var superIdHint: Int = -1
-
final def classDenot(implicit ctx: Context): ClassDenotation =
denot.asInstanceOf[ClassDenotation]
- def selfType(implicit ctx: Context): Type = classDenot.selfType
-
- /** The base classes of this class in linearization order,
- * with the class itself as first element.x
- */
- def baseClasses(implicit ctx: Context): List[ClassSymbol] = classDenot.baseClasses
-
- /** The parent types of this class */
- def parents(implicit ctx: Context): List[TypeRef] = classDenot.parents
-
- /** The symbols defined directly in this class */
- def decls(implicit ctx: Context): Scope = classDenot.decls
-
- // override def typeTemplate(implicit ctx: Context): Type = classDenot.typeTemplate
+ private var superIdHint: Int = -1
def superId(implicit ctx: Context): Int = {
val hint = superIdHint
@@ -471,4 +244,8 @@ object Symbols {
implicit def toFlagSet(sym: Symbol)(implicit ctx: Context): FlagSet = sym.flags
+ implicit def toDenot(sym: Symbol)(implicit ctx: Context): SymDenotation = sym.denot
+
+ implicit def toClassDenot(cls: ClassSymbol)(implicit ctx: Context): ClassDenotation = cls.classDenot
+
}