aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/SymDenotations.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/core/SymDenotations.scala')
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala86
1 files changed, 57 insertions, 29 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index d9fa15a5f..1bb912059 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -30,8 +30,8 @@ trait SymDenotations { this: Context =>
initPrivateWithin: Symbol = NoSymbol)(implicit ctx: Context): SymDenotation = {
val result =
if (symbol.isClass)
- if (initFlags is Package) new PackageClassDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin)
- else new ClassDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin)
+ if (initFlags is Package) new PackageClassDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin, ctx.runId)
+ else new ClassDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin, ctx.runId)
else new SymDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin)
result.validFor = stablePeriod
result
@@ -39,8 +39,19 @@ trait SymDenotations { this: Context =>
def stillValid(denot: SymDenotation): Boolean =
if (denot is ValidForever) true
- else if (denot.owner is PackageClass) denot.owner.decls.lookup(denot.name) eq denot.symbol
- else stillValid(denot.owner)
+ else try {
+ val owner = denot.owner.denot
+ def isSelfSym = owner.infoOrCompleter match {
+ case ClassInfo(_, _, _, _, selfInfo) => selfInfo == denot.symbol
+ case _ => false
+ }
+ stillValid(owner) && owner.isClass && (
+ (owner.decls.lookupAll(denot.name) contains denot.symbol)
+ || isSelfSym
+ )
+ } catch {
+ case ex: StaleSymbol => false
+ }
}
object SymDenotations {
@@ -732,7 +743,8 @@ object SymDenotations {
name: Name,
initFlags: FlagSet,
initInfo: Type,
- initPrivateWithin: Symbol = NoSymbol)
+ initPrivateWithin: Symbol,
+ initRunId: RunId)
extends SymDenotation(symbol, ownerIfExists, name, initFlags, initInfo, initPrivateWithin) {
import util.LRUCache
@@ -758,8 +770,9 @@ object SymDenotations {
myTypeParams
}
- private def myClassParents(implicit ctx: Context): List[TypeRef] = info match {
- case classInfo: ClassInfo => classInfo.myClassParents
+ /** The denotations of all parents in this class. */
+ def classParents(implicit ctx: Context): List[TypeRef] = info match {
+ case classInfo: ClassInfo => classInfo.classParents
case _ => Nil
}
@@ -768,32 +781,46 @@ object SymDenotations {
* @see Namer#ClassCompleter
*/
private def isFullyCompleted(implicit ctx: Context): Boolean =
- isCompleted && myClassParents.nonEmpty
+ isCompleted && classParents.nonEmpty
- /** A key to verify that all caches influenced by parent classes are valid */
- private var parentDenots: List[Denotation] = null
+ // ------ syncing inheritance-related info -----------------------------
- /** The denotations of all parents in this class.
- * 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): List[TypeRef] = {
- val ps = myClassParents
- if (parentDenots == null && ps.nonEmpty) parentDenots = ps map (_.denot)
- ps
- }
-
- /** Are caches influenced by parent classes still valid? */
- private def parentsAreValid(implicit ctx: Context): Boolean =
- parentDenots == null ||
- parentDenots.corresponds(myClassParents)(_ eq _.denot)
+ private var firstRunId: RunId = initRunId
/** If caches influenced by parent classes are still valid, the denotation
* itself, otherwise a freshly initialized copy.
*/
- override def copyIfParentInvalid(implicit ctx: Context): SingleDenotation =
- if (!parentsAreValid) copySymDenotation() else this
+ override def syncWithParents(implicit ctx: Context): SingleDenotation = {
+ def isYounger(tref: TypeRef) = tref.symbol.denot match {
+ case denot: ClassDenotation =>
+ if (denot.validFor.runId < ctx.runId) denot.current // syncs with its parents in turn
+ val result = denot.firstRunId > this.firstRunId
+ if (result) incremental.println(s"$denot is younger than $this")
+ result
+ case _ => false
+ }
+ val parentIsYounger = (firstRunId < ctx.runId) && {
+ infoOrCompleter match {
+ case cinfo: ClassInfo => cinfo.classParents exists isYounger
+ case _ => false
+ }
+ }
+ if (parentIsYounger) {
+ incremental.println(s"parents of $this are invalid; symbol id = ${symbol.id}, copying ...\n")
+ invalidateInheritedInfo()
+ firstRunId = ctx.runId
+ }
+ this
+ }
+
+ /** Invalidate all caches and fields that depend on base classes and their contents */
+ private def invalidateInheritedInfo(): Unit = {
+ myBaseClasses = null
+ mySuperClassBits = null
+ myMemberFingerPrint = FingerPrint.unknown
+ myMemberCache = null
+ memberNamesCache = SimpleMap.Empty
+ }
// ------ class-specific operations -----------------------------------
@@ -1142,8 +1169,9 @@ object SymDenotations {
name: Name,
initFlags: FlagSet,
initInfo: Type,
- initPrivateWithin: Symbol = NoSymbol)
- extends ClassDenotation(symbol, ownerIfExists, name, initFlags, initInfo, initPrivateWithin) {
+ initPrivateWithin: Symbol,
+ initRunId: RunId)
+ extends ClassDenotation(symbol, ownerIfExists, name, initFlags, initInfo, initPrivateWithin, initRunId) {
private[this] var packageObjCache: SymDenotation = _
private[this] var packageObjRunId: RunId = NoRunId