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.scala48
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