diff options
Diffstat (limited to 'src/dotty/tools/dotc/core/SymDenotations.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 48 |
1 files changed, 32 insertions, 16 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 2f2703397..00ca99da5 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -1213,8 +1213,17 @@ object SymDenotations { * ClassDenotations compiled from source are first completed, then fully completed. * @see Namer#ClassCompleter */ - private def isFullyCompleted(implicit ctx: Context): Boolean = - isCompleted && classParents.nonEmpty + private def isFullyCompleted(implicit ctx: Context): Boolean = { + def isFullyCompletedRef(tp: TypeRef) = tp.denot match { + case d: ClassDenotation => d.isFullyCompleted + case _ => false + } + def isLocallyFullyCompleted = + if (classParents.isEmpty) is(Package) || symbol.eq(defn.AnyClass) + else classParents.forall(isFullyCompletedRef) + flagsUNSAFE.is(FullyCompleted) || + isCompleted && isLocallyFullyCompleted && { setFlag(FullyCompleted); true } + } // ------ syncing inheritance-related info ----------------------------- @@ -1300,7 +1309,7 @@ object SymDenotations { baseTypeRefValid = ctx.runId } - private def computeBases(implicit ctx: Context): Unit = { + private def computeBases(implicit ctx: Context): (List[ClassSymbol], BitSet) = { if (myBaseClasses eq Nil) throw CyclicReference(this) myBaseClasses = Nil val seen = new mutable.BitSet @@ -1324,8 +1333,14 @@ object SymDenotations { case nil => to } - myBaseClasses = classSymbol :: addParentBaseClasses(classParents, Nil) - mySuperClassBits = seen.toImmutable + val bcs = classSymbol :: addParentBaseClasses(classParents, Nil) + val scbits = seen.toImmutable + if (isFullyCompleted) { + myBaseClasses = bcs + mySuperClassBits = scbits + } + else myBaseClasses = null + (bcs, scbits) } /** A bitset that contains the superId's of all base classes */ @@ -1333,8 +1348,7 @@ object SymDenotations { if (classParents.isEmpty) BitSet() // can happen when called too early in Namers else { checkBasesUpToDate() - if (mySuperClassBits == null) computeBases - mySuperClassBits + if (mySuperClassBits != null) mySuperClassBits else computeBases._2 } /** The base classes of this class in linearization order, @@ -1344,8 +1358,7 @@ object SymDenotations { if (classParents.isEmpty) classSymbol :: Nil // can happen when called too early in Namers else { checkBasesUpToDate() - if (myBaseClasses == null) computeBases - myBaseClasses + if (myBaseClasses != null) myBaseClasses else computeBases._1 } final override def derivesFrom(base: Symbol)(implicit ctx: Context): Boolean = @@ -1378,9 +1391,9 @@ object SymDenotations { while (ps.nonEmpty) { val parent = ps.head.typeSymbol parent.denot match { - case classd: ClassDenotation => - fp.include(classd.memberFingerPrint) - parent.denot.setFlag(Frozen) + case parentDenot: ClassDenotation => + fp.include(parentDenot.memberFingerPrint) + if (parentDenot.isFullyCompleted) parentDenot.setFlag(Frozen) case _ => } ps = ps.tail @@ -1393,10 +1406,13 @@ object SymDenotations { * not be used for package classes because cache never * gets invalidated. */ - def memberFingerPrint(implicit ctx: Context): FingerPrint = { - if (myMemberFingerPrint == FingerPrint.unknown) myMemberFingerPrint = computeMemberFingerPrint - myMemberFingerPrint - } + def memberFingerPrint(implicit ctx: Context): FingerPrint = + if (myMemberFingerPrint != FingerPrint.unknown) myMemberFingerPrint + else { + val fp = computeMemberFingerPrint + if (isFullyCompleted) myMemberFingerPrint = fp + fp + } private[this] var myMemberCache: LRUCache[Name, PreDenotation] = null private[this] var myMemberCachePeriod: Period = Nowhere |