aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-11-26 17:08:58 +0100
committerMartin Odersky <odersky@gmail.com>2013-11-26 17:08:58 +0100
commitf0b4fc58e0c5e5372c23bd817954ed3aa82b2102 (patch)
tree7d933db35e8d3c975b69089312b72397842575c0 /src
parent537e29676b0706de1855fe763b87732b846931f4 (diff)
downloaddotty-f0b4fc58e0c5e5372c23bd817954ed3aa82b2102.tar.gz
dotty-f0b4fc58e0c5e5372c23bd817954ed3aa82b2102.tar.bz2
dotty-f0b4fc58e0c5e5372c23bd817954ed3aa82b2102.zip
More posishings of SymDenots/Denotations.
In particular - closed a loophole where we did not go through parentDenot in ClassDenotation. - fused some of the predenotation ops used in computeMemberNames
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/config/Config.scala1
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala47
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala36
-rw-r--r--src/dotty/tools/dotc/core/Types.scala10
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala2
5 files changed, 47 insertions, 49 deletions
diff --git a/src/dotty/tools/dotc/config/Config.scala b/src/dotty/tools/dotc/config/Config.scala
index af75aea89..4d93fae29 100644
--- a/src/dotty/tools/dotc/config/Config.scala
+++ b/src/dotty/tools/dotc/config/Config.scala
@@ -4,6 +4,7 @@ object Config {
final val cacheMemberNames = true
final val cacheAsSeenFrom = true
+ final val useFingerPrints = true
/** When set, use new signature-based matching.
* Advantantage of doing so: It's supposed to be faster
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 72c999f9b..8aafa5e64 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -540,19 +540,13 @@ object Denotations {
if (p(this)) this else NoDenotation
final def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): SingleDenotation =
if (denots.containsSig(signature)) NoDenotation else this
- def disjointAsSeenFrom(denots: PreDenotation, pre: Type)(implicit ctx: Context): SingleDenotation =
- if (isType) filterDisjoint(denots).asSeenFrom(pre)
- else asSeenFrom(pre).filterDisjoint(denots)
+ def mapInherited(ownDenots: PreDenotation, prevDenots: PreDenotation, pre: Type)(implicit ctx: Context): SingleDenotation =
+ if (hasUniqueSym && prevDenots.containsSym(symbol)) NoDenotation
+ else if (overlaps(Private)) NoDenotation
+ else if (isType) filterDisjoint(ownDenots).asSeenFrom(pre)
+ else asSeenFrom(pre).filterDisjoint(ownDenots)
final def filterExcluded(excluded: FlagSet)(implicit ctx: Context): SingleDenotation =
- if (excluded.isEmpty) this
- else this match {
- case thisd: SymDenotation =>
- if (thisd is excluded) NoDenotation else this
- case _ =>
- if (symbol is excluded) NoDenotation else this
- }
- final def dropUniqueRefsIn(denots: PreDenotation): SingleDenotation =
- if (hasUniqueSym && denots.containsSym(symbol)) NoDenotation else this
+ if (excluded.isEmpty || !(this overlaps excluded)) this else NoDenotation
type AsSeenFromResult = SingleDenotation
protected def computeAsSeenFrom(pre: Type)(implicit ctx: Context): SingleDenotation = {
@@ -563,6 +557,11 @@ object Denotations {
if (!owner.membersNeedAsSeenFrom(pre)) this
else derivedSingleDenotation(symbol, info.asSeenFrom(pre, owner))
}
+
+ private def overlaps(fs: FlagSet)(implicit ctx: Context): Boolean = this match {
+ case sd: SymDenotation => sd is fs
+ case _ => symbol is fs
+ }
}
class UniqueRefDenotation(
@@ -624,18 +623,23 @@ object Denotations {
*/
def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): PreDenotation
- def disjointAsSeenFrom(denots: PreDenotation, pre: Type)(implicit ctx: Context): PreDenotation
+ /** Keep only those inherited members M of this predenotation for which the following is true
+ * - M is not marked Private
+ * - If M has a unique symbol, it does not appear in `prevDenots`.
+ * - M's signature as seen from prefix `pre` does not appear in `ownDenots`
+ * Return the denotation as seen from `pre`.
+ * Called from SymDenotations.computeMember. There, `ownDenots` are the denotations found in
+ * the base class, which shadow any inherited denotations with the same signature.
+ * `prevDenots` are the denotations that are defined in the class or inherited from
+ * a base type which comes earlier in the linearization.
+ */
+ def mapInherited(ownDenots: PreDenotation, prevDenots: PreDenotation, pre: Type)(implicit ctx: Context): PreDenotation
/** Keep only those denotations in this group whose flags do not intersect
* with `excluded`.
*/
def filterExcluded(excluded: FlagSet)(implicit ctx: Context): PreDenotation
- /** Drop all denotations which refer to a unique symbol that is
- * already referred uniquely in `denots`.
- */
- def dropUniqueRefsIn(denots: PreDenotation): PreDenotation
-
private var cachedPrefix: Type = _
private var cachedAsSeenFrom: AsSeenFromResult = _
private var validAsSeenFrom: Period = Nowhere
@@ -674,12 +678,11 @@ object Denotations {
derivedUnion(denots1 filterWithPredicate p, denots2 filterWithPredicate p)
def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): PreDenotation =
derivedUnion(denots1 filterDisjoint denots, denots2 filterDisjoint denots)
- def disjointAsSeenFrom(denots: PreDenotation, pre: Type)(implicit ctx: Context): PreDenotation =
- derivedUnion(denots1.disjointAsSeenFrom(denots, pre), denots2.disjointAsSeenFrom(denots, pre))
+ def mapInherited(ownDenots: PreDenotation, prevDenots: PreDenotation, pre: Type)(implicit ctx: Context): PreDenotation =
+ derivedUnion(denots1.mapInherited(ownDenots, prevDenots, pre), denots2.mapInherited(ownDenots, prevDenots, pre))
def filterExcluded(excluded: FlagSet)(implicit ctx: Context): PreDenotation =
derivedUnion(denots1.filterExcluded(excluded), denots2.filterExcluded(excluded))
- def dropUniqueRefsIn(denots: PreDenotation): PreDenotation =
- derivedUnion(denots1.dropUniqueRefsIn(denots), denots2.dropUniqueRefsIn(denots))
+
type AsSeenFromResult = PreDenotation
protected def computeAsSeenFrom(pre: Type)(implicit ctx: Context): PreDenotation =
derivedUnion(denots1.asSeenFrom(pre), denots2.asSeenFrom(pre))
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 2727095cf..fa7b71450 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -359,6 +359,8 @@ object SymDenotations {
/** Is this a subclass of `base`,
* and is the denoting symbol also different from `Null` or `Nothing`?
+ * @note erroneous classes are assumed to derive from all other classes
+ * and all classes derive from them.
*/
def derivesFrom(base: Symbol)(implicit ctx: Context) = false
@@ -449,7 +451,7 @@ object SymDenotations {
!( this.isTerm
|| this.isStaticOwner
|| ctx.erasedTypes && symbol != defn.ArrayClass
- || (pre eq thisType)
+ || (pre eq NoPrefix) || (pre eq thisType)
)
/** Is this symbol concrete, or that symbol deferred? */
@@ -737,24 +739,22 @@ object SymDenotations {
/** The type parameters of this class */
override final def typeParams(implicit ctx: Context): List[TypeSymbol] = {
+ def computeTypeParams = decls.filter(sym =>
+ (sym is TypeParam) && sym.owner == symbol).asInstanceOf[List[TypeSymbol]]
if (myTypeParams == null) myTypeParams = computeTypeParams
myTypeParams
}
- private def computeTypeParams(implicit ctx: Context): List[TypeSymbol] =
- decls.filter(sym =>
- (sym is TypeParam) && sym.owner == symbol).asInstanceOf[List[TypeSymbol]]
-
/** A key to verify that all caches influenced by parent classes are valid */
private var parentDenots: List[Denotation] = null
/** The denotations of all parents in this class.
- * Note: Always use this method instead of `classInfo.classParents`
+ * Note: Always use this method instead of `classInfo.myClassParents`
* because the latter does not ensure that the `parentDenots` key
* is up-to-date, which might lead to invalid caches later on.
*/
def classParents(implicit ctx: Context) = {
- val ps = classInfo.classParents
+ val ps = classInfo.myClassParents
if (parentDenots == null) parentDenots = ps map (_.denot)
ps
}
@@ -762,7 +762,7 @@ object SymDenotations {
/** Are caches influenced by parent classes still valid? */
private def parentsAreValid(implicit ctx: Context): Boolean =
parentDenots == null ||
- parentDenots.corresponds(classInfo.classParents)(_ eq _.denot)
+ parentDenots.corresponds(classInfo.myClassParents)(_ eq _.denot)
/** If caches influenced by parent classes are still valid, the denotation
* itself, otherwise a freshly initialized copy.
@@ -785,11 +785,11 @@ object SymDenotations {
else
ThisType(classSymbol) */
- private[this] var myTypeConstructor: TypeRef = null
+ private[this] var myTypeRef: TypeRef = null
override def typeRef(implicit ctx: Context): TypeRef = {
- if (myTypeConstructor == null) myTypeConstructor = super.typeRef
- myTypeConstructor
+ if (myTypeRef == null) myTypeRef = super.typeRef
+ myTypeRef
}
private[this] var myBaseClasses: List[ClassSymbol] = null
@@ -941,7 +941,9 @@ object SymDenotations {
} else computeMembersNamed(name)
private def computeMembersNamed(name: Name)(implicit ctx: Context): PreDenotation =
- if (!classSymbol.hasChildren || (memberFingerPrint contains name)) {
+ if (!classSymbol.hasChildren ||
+ !Config.useFingerPrints ||
+ (memberFingerPrint contains name)) {
val ownDenots = decls.denotsNamed(name)
if (debugTrace) // DEBUG
println(s"$this.member($name), ownDenots = $ownDenots")
@@ -950,17 +952,9 @@ object SymDenotations {
val denots1 = collect(denots, ps)
p.symbol.denot match {
case parentd: ClassDenotation =>
- if (debugTrace) { // DEBUG
- val s1 = parentd.membersNamed(name)
- val s2 = s1.filterExcluded(Private)
- val s3 = s2.disjointAsSeenFrom(ownDenots, thisType)
- println(s"$this.member($name) $s1 $s2 $s3")
- }
denots1 union
parentd.membersNamed(name)
- .dropUniqueRefsIn(denots1)
- .filterExcluded(Private)
- .disjointAsSeenFrom(ownDenots, thisType)
+ .mapInherited(ownDenots, denots1, thisType)
case _ =>
denots1
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 437839c4f..9c849bfdf 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1708,7 +1708,7 @@ object Types {
abstract case class ClassInfo(
prefix: Type,
cls: ClassSymbol,
- classParents: List[TypeRef],
+ myClassParents: List[TypeRef], // to be used only in ClassDenotation!
decls: Scope,
selfInfo: DotClass /* should be: Type | Symbol */) extends CachedGroundType with TypeType {
@@ -1738,16 +1738,16 @@ object Types {
override def parents(implicit ctx: Context): List[TypeRef] = {
if (parentsCache == null)
- parentsCache = classParents.mapConserve(rebase(_).asInstanceOf[TypeRef])
+ parentsCache = cls.classParents.mapConserve(rebase(_).asInstanceOf[TypeRef])
parentsCache
}
def derivedClassInfo(prefix: Type)(implicit ctx: Context) =
if (prefix eq this.prefix) this
- else ClassInfo(prefix, cls, classParents, decls, selfInfo)
+ else ClassInfo(prefix, cls, myClassParents, decls, selfInfo)
- def derivedClassInfo(prefix: Type, classParents: List[TypeRef], selfInfo: Type)(implicit ctx: Context) =
- if ((prefix eq this.prefix) && (classParents eq this.classParents) && (selfInfo eq this.selfInfo)) this
+ def derivedClassInfo(prefix: Type = this.prefix, classParents: List[TypeRef] = myClassParents, selfInfo: DotClass = this.selfInfo)(implicit ctx: Context) =
+ if ((prefix eq this.prefix) && (classParents eq this.myClassParents) && (selfInfo eq this.selfInfo)) this
else ClassInfo(prefix, cls, classParents, decls, selfInfo)
override def computeHash = doHash(cls, prefix)
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index f8551d615..66d238614 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -338,7 +338,7 @@ class Namer { typer: Typer =>
case sig: TypeRef =>
sig
case sig: ClassInfo =>
- sig.derivedClassInfo(sig.prefix, sig.classParents, sig.prefix select sourceModule)
+ sig.derivedClassInfo(selfInfo = sig.prefix select sourceModule)
case _ =>
sig
}