diff options
author | Martin Odersky <odersky@gmail.com> | 2013-01-21 12:43:11 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-01-21 12:43:11 +0100 |
commit | e59b8822f53fa6fad057ac9642d31e4026800bf5 (patch) | |
tree | 644848889cf7479d43b95e11a224e4a9373ff5e3 /src/dotty | |
parent | a14284769027bc81e48ccfa3379c6448d1399dfc (diff) | |
download | dotty-e59b8822f53fa6fad057ac9642d31e4026800bf5.tar.gz dotty-e59b8822f53fa6fad057ac9642d31e4026800bf5.tar.bz2 dotty-e59b8822f53fa6fad057ac9642d31e4026800bf5.zip |
Big renaming to drop Reference(d) as a terminology and use Denotation instead. previous Denotations (which already were a subclass) are renamed to SymDenotations.
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 689 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Referenceds.scala | 381 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Scopes.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 440 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 165 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Transformers.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 68 |
8 files changed, 885 insertions, 885 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index 8b8ee015d..131f72c65 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -66,7 +66,7 @@ object Contexts { /** Allocate and return next free superclass id */ private[core] def nextSuperId: Int = { lastSuperId += 1; lastSuperId } - // Denotations state + // SymDenotations state private[core] val uniqueBits = new util.HashSet[BitSet]("superbits", 1024) // Types state @@ -89,4 +89,4 @@ object Contexts { * logging starts. */ private[core] final val LogVolatileThreshold = 50 -}
\ No newline at end of file +} diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 859323ed2..f9c4fde8f 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -1,440 +1,373 @@ package dotty.tools.dotc package core -import Periods._, Contexts._, Symbols._, Referenceds._, Names._, Annotations._ -import Types._, Flags._, Decorators._, Transformers._ -import Scopes.Scope -import collection.mutable -import collection.immutable.BitSet +import SymDenotations.{SymDenotation, NoDenotation} +import Contexts.Context +import Names.Name +import Names.TypeName +import Symbols.NoSymbol +import Symbols.Symbol +import Types._, Periods._, Flags._, Transformers._ + +/** Classes that represent the meaning of symbols and named types, and sets over them. + */ object Denotations { - /** A denotation represents the contents of a definition - * during a period. + /** The signature of a denotation. + * Overloaded denotations with the same name are distinguished by + * their signatures. A signature is a list of the fully qualified names + * of the type symbols of the erasure of the parameters of the + * denotation. For instance a definition + * + * def f(x: Int)(y: List[String]): String + * + * would have signature + * + * List("scala.Int".toTypeName, "scala.collection.immutable.List".toTypeName) */ - abstract class Denotation(initFlags: FlagSet) extends SymRefd { - - def owner: Symbol + type Signature = List[TypeName] - def name: Name + /** The signature of a val or parameterless def, as opposed + * to List(), which is the signature of a zero-parameter def. + */ + val NullSignature = List(Names.EmptyTypeName) + + /** A denotation is the result of resolving + * a name (either simple identifier or select) during a given period. + * + * Denotation has two subclasses: MultiDenotation and SingleDenotation. + * + * A SingleDenotation refers to a `symbol` and a type (`info`) that the symbol has + * when seen from the reference. + * + * Denotations can be combined with `&` and `|`. + * & is conjunction, | is disjunction. + * + * `&` will create an overloaded denotation from two + * non-overloaded denotations if their signatures differ. + * Analogously `|` of two denotations with different signatures will give + * an empty denotation `NoDenotation`. + * + * A denotation might refer to `NoSymbol`. This is the case if the denotation + * was produced from a disjunction of two denotations with different symbols + * and there was no common symbol in a superclass that could substitute for + * both symbols. Here is an example: + * + * Say, we have: + * + * class A { def f: A } + * class B { def f: B } + * val x: A | B = if (???) new A else new B + * val y = x.f + * + * Then the denotation of `y` is `SingleDenotation(NoSymbol, A | B)`. + */ + abstract class Denotation extends DotClass { + /** The referencing symbol, exists only for non-overloaded denotations */ def symbol: Symbol + /** The type info of the denotation, exists only for non-overloaded denotations */ def info: Type - private[this] var _flags: FlagSet = initFlags - - def flags: FlagSet = _flags - - def flags_=(flags: FlagSet): Unit = - _flags |= flags - - def setFlags(flags: FlagSet): Unit = - _flags |= flags - - def resetFlags(flags: FlagSet): Unit = - _flags &~= flags - - private[this] var _privateWithin: Symbol = NoSymbol - - def privateWithin: Symbol = _privateWithin - - def privateWithin_=(sym: Symbol): Unit = - _privateWithin = sym - - final def isLoaded = _privateWithin != null + /** The period during which this denotation is valid. */ + def validFor: Period - private[this] var _annotations: List[Annotation] = Nil + /** Is this a reference to a type symbol? */ + def isType: Boolean = false - def annotations: List[Annotation] = _annotations + /** Is this a reference to a term symbol? */ + def isTerm: Boolean = !isType - def annotations_=(annots: List[Annotation]): Unit = - _annotations = annots + /** Is this denotation overloaded? */ + def isOverloaded = isInstanceOf[MultiDenotation] - final def isCompleted = _annotations != null + /** The signature of the denotation */ + def signature: Signature - /** is this symbol a class? */ - def isClass: Boolean = false + /** Resolve overloaded denotation to pick the one with the given signature */ + def atSignature(sig: Signature): SingleDenotation - /** is this symbol a method? */ - def isMethod: Boolean = false + /** The variant of this denotation that's current in the given context. */ + def current(implicit ctx: Context): Denotation - /** is this symbol the result of an erroneous definition? */ - def isError: Boolean = false + def exists: Boolean = true - def withType(tp: Type): Denotation = ??? - - override protected def copy(s: Symbol, i: Type): SymRefd = new UniqueSymRefd(s, i, validFor) - } + /** Form a denotation by conjoining with denotation `that` */ + def & (that: Denotation)(implicit ctx: Context): Denotation = + if (this eq that) this + else if (!this.exists) that + else if (!that.exists) this + else that match { + case that: SingleDenotation => + val r = mergeDenot(this, that) + if (r ne NoDenotation) r else MultiDenotation(this, that) + case that @ MultiDenotation(denot1, denot2) => + this & denot1 & denot2 + } - class CompleteDenotation( - val symbol: Symbol, - val owner: Symbol, - val name: Name, - initFlags: FlagSet, - val info: Type - ) extends Denotation(initFlags) - - trait LazyCompletion extends Denotation { - privateWithin = null - annotations = null - - override final def flags = { - if (!isLoaded) tryLoad() - super.flags + /** Try to merge denot1 and denot2 without adding a new signature. + * If unsuccessful, return NoDenotation. + */ + private def mergeDenot(denot1: Denotation, denot2: SingleDenotation)(implicit ctx: Context): Denotation = denot1 match { + case denot1 @ MultiDenotation(denot11, denot12) => + val d1 = mergeDenot(denot11, denot2) + if (d1 ne NoDenotation) d1 else mergeDenot(denot12, denot2) + case denot1: SingleDenotation => + if (denot1 eq denot2) denot1 + else if (denot1.signature == denot2.signature) { + def isEligible(sym1: Symbol, sym2: Symbol) = + if (sym1.isType) !sym1.isClass + else sym1.isConcrete || sym2.isDeferred || !sym2.exists + def normalize(info: Type) = + if (isType) info.bounds else info + val sym1 = denot1.symbol + val info1 = denot1.info + val sym2 = denot2.symbol + val info2 = denot2.info + val sym1Eligible = isEligible(sym1, sym2) + val sym2Eligible = isEligible(sym2, sym1) + val bounds1 = normalize(info1) + val bounds2 = normalize(info2) + if (sym2Eligible && bounds2 <:< bounds1) denot2 + else if (sym1Eligible && bounds1 <:< bounds2) denot1 + else new JointRefDenotation( + if (sym2Eligible) sym2 else sym1, + bounds1 & bounds2, + denot1.validFor & denot2.validFor) + } else NoDenotation } - override final def privateWithin = { - if (!isLoaded) tryLoad() - super.privateWithin - } + def | (that: Denotation)(pre: Type)(implicit ctx: Context): Denotation = { - override final def annotations: List[Annotation] = { - val annots = super.annotations - if (annots != null) annots else { tryComplete(); annotations } - } + def lubSym(sym1: Symbol, sym2: Symbol): Symbol = { + def qualifies(sym: Symbol) = + (sym isAccessibleFrom pre) && (sym2.owner isSubClass sym.owner) + sym1.allOverriddenSymbols find qualifies getOrElse NoSymbol + } - protected def tryLoad(): Unit = try { - if (flags is Locked) throw new CyclicReference(symbol) - setFlags(Locked) - load() - } catch { - case ex: CyclicReference => handleCycle() - } finally { - flags &~= Locked - } + def throwError = throw new MatchError(s"$this | $that") - protected def tryComplete() = try { - if (flags is Locked) throw new CyclicReference(symbol) - complete() - } catch { - case ex: CyclicReference => handleCycle() - } finally { - flags &~= Locked + if (this eq that) this + else if (!this.exists) this + else if (!that.exists) that + else this match { + case denot1 @ MultiDenotation(denot11, denot12) => + denot1.derivedMultiDenotation((denot11 | that)(pre), (denot12 | that)(pre)) + case _ => + that match { + case denot2 @ MultiDenotation(denot21, denot22) => + denot2.derivedMultiDenotation((this | denot21)(pre), (this | denot22)(pre)) + case denot2: SingleDenotation => + this match { + case denot1: SingleDenotation => + if (denot1.signature != denot2.signature) NoDenotation + else new JointRefDenotation( + lubSym(denot1.symbol, denot2.symbol), + denot1.info | denot2.info, + denot1.validFor & denot2.validFor) + case _ => + throwError + } + case _ => + throwError + } + } } - - protected def handleCycle(): Unit - protected def load(): Unit - protected def complete(): Unit } - abstract class LazyDenotation( - val symbol: Symbol, - val owner: Symbol, - val name: Name, - initFlags: FlagSet - ) extends Denotation(initFlags) with LazyCompletion { - - private var currentInfo: Type = null - - override def info = { - if (currentInfo == null) complete() - currentInfo - } + /** The class of overloaded denotations + * @param variants The overloaded variants indexed by thheir signatures. + */ + case class MultiDenotation(denot1: Denotation, denot2: Denotation) extends Denotation { + def derivedMultiDenotation(d1: Denotation, d2: Denotation) = + if ((d1 eq denot1) && (d2 eq denot2)) this else MultiDenotation(d1, d2) + def symbol = unsupported("symbol") + def info = unsupported("info") + def signature = unsupported("signature") + def atSignature(sig: Signature): SingleDenotation = + denot1.atSignature(sig) orElse denot2.atSignature(sig) + def validFor = denot1.validFor & denot2.validFor + def current(implicit ctx: Context): Denotation = + derivedMultiDenotation(denot1.current, denot2.current) } - abstract class ClassDenotation(initFlags: FlagSet)(implicit ctx: Context) - extends Denotation(initFlags) { - import NameFilter._ - import util.LRU8Cache - - val symbol: ClassSymbol + abstract class SingleDenotation extends Denotation with DenotationSet { - def typeParams: List[TypeSymbol] - - def parents: List[Type] - - def decls: Scope - - val info = ClassInfo(owner.thisType, this) - - private var memberCacheVar: LRU8Cache[Name, ReferencedSet] = null - - private def memberCache: LRU8Cache[Name, ReferencedSet] = { - if (memberCacheVar == null) memberCacheVar = new LRU8Cache - memberCacheVar - } - - private var thisTypeCache: ThisType = null - - def thisType(implicit ctx: Context): Type = { - if (thisTypeCache == null) - thisTypeCache = ThisType(symbol) - thisTypeCache - } - - private var typeConstructorCache: Type = null - - def typeConstructor(implicit ctx: Context): Type = { - if (typeConstructorCache == null) - typeConstructorCache = NamedType(thisType, symbol.name) - typeConstructorCache - } - - private var typeTemplateCache: Type = null - - def typeTemplate(implicit ctx: Context): Type = { - if (typeTemplateCache == null) - AppliedType.make(typeConstructor, typeParams map (_.typeConstructor)) - typeTemplateCache - } - - private var baseClassesVar: List[ClassSymbol] = null - private var superClassBitsVar: BitSet = null - - private def computeSuperClassBits(implicit ctx: Context): Unit = { - val seen = new mutable.BitSet - val locked = new mutable.BitSet - def addBaseClasses(bcs: List[ClassSymbol], to: List[ClassSymbol]) - : List[ClassSymbol] = bcs match { - case bc :: bcs1 => - val id = bc.superId - if (seen contains id) to - else if (locked contains id) throw new CyclicReference(symbol) - else { - locked += id - val bcs1added = addBaseClasses(bcs1, to) - seen += id - if (bcs1added eq bcs1) bcs else bc :: bcs1added + override def isType = symbol.isType + override def signature: Signature = { + def sig(tp: Type): Signature = tp match { + case tp: PolyType => + tp.resultType match { + case mt: MethodType => mt.signature + case _ => List() } - case _ => - to - } - def addParentBaseClasses(ps: List[Type], to: List[ClassSymbol]): List[ClassSymbol] = ps match { - case p :: ps1 => - addBaseClasses(p.baseClasses, addParentBaseClasses(ps1, to)) - case _ => - to + case mt: MethodType => mt.signature + case _ => NullSignature } - baseClassesVar = symbol :: addParentBaseClasses(parents, Nil) - superClassBitsVar = ctx.root.uniqueBits.findEntryOrUpdate(seen.toImmutable) + if (isType) NullSignature else sig(info) } - def superClassBits(implicit ctx: Context): BitSet = { - if (superClassBitsVar == null) computeSuperClassBits - superClassBitsVar - } + def derivedSingleDenotation(s: Symbol, i: Type): SingleDenotation = + if ((s eq symbol) && (i eq info)) this else copy(s, i) - def baseClasses(implicit ctx: Context): List[ClassSymbol] = { - if (baseClassesVar == null) computeSuperClassBits - baseClassesVar - } + protected def copy(s: Symbol, i: Type): SingleDenotation = this - /** Is this class a subclass of `clazz`? */ - final def isSubClass(clazz: ClassSymbol)(implicit ctx: Context): Boolean = { - superClassBits contains clazz.superId - } + def orElse(that: => SingleDenotation) = if (this.exists) this else that - private var definedFingerPrintCache: FingerPrint = null + def atSignature(sig: Signature): SingleDenotation = + if (sig == signature) this else NoDenotation - private def computeDefinedFingerPrint(implicit ctx: Context): FingerPrint = { - var bits = newNameFilter - var e = decls.lastEntry - while (e != null) { - includeName(bits, name) - e = e.prev - } - var ps = parents - while (ps.nonEmpty) { - val parent = ps.head.typeSymbol - parent.deref match { - case classd: ClassDenotation => - includeFingerPrint(bits, classd.definedFingerPrint) - parent.deref.setFlags(Frozen) - case _ => - } - ps = ps.tail - } - definedFingerPrintCache = bits - bits - } + // ------ Transformations ----------------------------------------- - /** 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. - */ - def enter(sym: Symbol)(implicit ctx: Context) = { - require(!(this is Frozen)) - decls enter sym - if (definedFingerPrintCache != null) - includeName(definedFingerPrintCache, sym.name) - if (memberCacheVar != null) - memberCache invalidate sym.name - } + private[this] var _validFor: Period = Nowhere - /** Delete symbol from current scope. - * Note: We require that this does not happen after the first time - * someone does a findMember on a subclass. + def validFor = _validFor + def validFor_=(p: Period) = + _validFor = p + + /** The next SingleDenotation in this run, with wrap-around from last to first. + * + * There may be several `SingleDenotation`s with different validity + * representing the same underlying definition at different phases. + * These are called a "flock". Flock members are generated by + * @See current. Flock members are connected in a ring + * with their `nextInRun` fields. + * + * There are the following invariants converning flock members + * + * 1) validity periods must be non-overlapping + * 2) the union of all validity periods must be a contiguous + * interval starting in FirstPhaseId. */ - def delete(sym: Symbol)(implicit ctx: Context) = { - require(!(this is Frozen)) - decls unlink sym - if (definedFingerPrintCache != null) - computeDefinedFingerPrint - if (memberCacheVar != null) - memberCache invalidate sym.name - } + var nextInRun: SingleDenotation = this - def definedFingerPrint(implicit ctx: Context): FingerPrint = { - val fp = definedFingerPrintCache - if (fp != null) fp else computeDefinedFingerPrint + /** The version of this SingleDenotation that was valid in the first phase + * of this run. + */ + def initial: SingleDenotation = { + var current = nextInRun + while (current.validFor.code > this._validFor.code) current = current.nextInRun + current } - final def memberRefsNamed(name: Name)(implicit ctx: Context): ReferencedSet = { - var refs: ReferencedSet = memberCache lookup name - if (refs == null) { - if (containsName(definedFingerPrint, name)) { - val ownRefs = decls.refsNamed(name) - refs = ownRefs - var ps = parents - while (ps.nonEmpty) { - val parentSym = ps.head.typeSymbol - parentSym.deref match { - case parentd: ClassDenotation => - refs = refs union - parentd.memberRefsNamed(name) - .filterExcluded(Flags.Private) - .asSeenFrom(thisType, parentSym) - .filterDisjoint(ownRefs) - case _ => - } - } - } else { - refs = NoRefd + def current(implicit ctx: Context): SingleDenotation = { + val currentPeriod = ctx.period + val valid = _validFor + var current = this + if (currentPeriod.code > valid.code) { + // search for containing period as long as nextInRun increases. + var next = nextInRun + while (next.validFor.code > valid.code && + !(next.validFor contains currentPeriod)) { + current = next + next = next.nextInRun } - memberCache enter (name, refs) - } - refs - } - - private var baseTypeCache: java.util.HashMap[CachedType, Type] = null - private var baseTypeValid: RunId = NoRunId - - final def baseTypeOf(tp: Type)(implicit ctx: Context): Type = { - - def computeBaseTypeOf(tp: Type): Type = tp match { - case AppliedType(tycon, args) => - baseTypeOf(tycon).subst(tycon.typeParams, args) - case tp: TypeProxy => - baseTypeOf(tp.underlying) - case AndType(tp1, tp2) => - baseTypeOf(tp1) & baseTypeOf(tp2) - case OrType(tp1, tp2) => - baseTypeOf(tp1) | baseTypeOf(tp2) - case tp @ ClassInfo(pre, classd) => - def reduce(bt: Type, ps: List[Type]): Type = ps match { - case p :: ps1 => reduce(bt & baseTypeOf(p), ps1) - case _ => bt - } - if (classd.symbol == symbol) tp.typeTemplate - else reduce(NoType, classd.parents).substThis(classd.symbol, tp.prefix) - } - - if (symbol.isStaticMono) symbol.typeConstructor - else tp match { - case tp: CachedType => - if (baseTypeValid != ctx.runId) { - baseTypeCache = new java.util.HashMap[CachedType, Type] - baseTypeValid = ctx.runId - } - var basetp = baseTypeCache get tp - if (basetp == null) { - baseTypeCache.put(tp, NoType) - basetp = computeBaseTypeOf(tp) - baseTypeCache.put(tp, basetp) - } else if (basetp == NoType) { - throw new CyclicReference(symbol) + if (next.validFor.code > valid.code) { + // in this case, containsPeriod(next._validFor, currentPeriod) + current = next + } else { + // not found, current points to highest existing variant + var startPid = current.validFor.lastPhaseId + 1 + val trans = ctx.root.transformersFor(current) + val endPid = trans.nextTransformer(startPid + 1).phaseId - 1 + next = trans.nextTransformer(startPid) transform current + if (next eq current) + startPid = current.validFor.firstPhaseId + else { + current.nextInRun = next + current = next } - basetp - case _ => - computeBaseTypeOf(tp) + current.validFor = Period(currentPeriod.runId, startPid, endPid) + } + } else { + // currentPeriod < valid; in this case a version must exist + do { + current = current.nextInRun + } while (!(current.validFor contains currentPeriod)) } + current } - private var memberNamesCache: Map[NameFilter, Set[Name]] = Map() - - def memberNames(keepOnly: NameFilter)(implicit ctx: Context): Set[Name] = - memberNamesCache get keepOnly match { - case Some(names) => - names - case _ => - val inheritedNames = (parents flatMap (_.memberNames(thisType, keepOnly))).toSet - val ownNames = decls.iterator map (_.name) - val candidates = inheritedNames ++ ownNames - val names = candidates filter (keepOnly(thisType, _)) - memberNamesCache += (keepOnly -> names) - names - } + def asSymDenotation = asInstanceOf[SymDenotation] + + // ------ DenotationSet ops ---------------------------------------------- + + def toDenot(implicit ctx: Context) = this + def containsSig(sig: Signature)(implicit ctx: Context) = + signature == sig + def filter(p: Symbol => Boolean)(implicit ctx: Context): DenotationSet = + if (p(symbol)) this else NoDenotation + def filterDisjoint(denots: DenotationSet)(implicit ctx: Context): DenotationSet = + if (denots.containsSig(signature)) NoDenotation else this + def filterExcluded(flags: FlagSet)(implicit ctx: Context): DenotationSet = + if (symbol.hasFlag(flags)) NoDenotation else this + def filterAccessibleFrom(pre: Type)(implicit ctx: Context): DenotationSet = + if (symbol.isAccessibleFrom(pre)) this else NoDenotation + def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): DenotationSet = + derivedSingleDenotation(symbol, info.asSeenFrom(pre, owner)) } - class CompleteClassDenotation( - val symbol: ClassSymbol, - val owner: Symbol, - val name: Name, - initFlags: FlagSet, - val typeParams: List[TypeSymbol], - val parents: List[Type], - val decls: Scope - )(implicit ctx: Context) extends ClassDenotation(initFlags) - - abstract class LazyClassDenotation( - val symbol: ClassSymbol, - val owner: Symbol, - val name: Name, - initFlags: FlagSet - )(implicit ctx: Context) extends ClassDenotation(initFlags) with LazyCompletion { - - protected var _typeParams: List[TypeSymbol] = null - protected var _parents: List[Type] = null - protected var _decls: Scope = null - - final def typeParams: List[TypeSymbol] = { - val tparams = _typeParams - if (tparams != null) tparams else { tryLoad(); typeParams } - } - - final def parents: List[Type] = { - val ps = _parents - if (ps != null) ps else { tryComplete(); parents } - } - - final def decls: Scope = { - val ds = _decls - if (ds != null) ds else { tryComplete(); decls } - } + class UniqueRefDenotation(val symbol: Symbol, + val info: Type, + initValidFor: Period) extends SingleDenotation { + validFor = initValidFor + override protected def copy(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor) } - object NoDenotation extends Denotation(Flags.Empty) { - override def symbol: Symbol = NoSymbol - override def owner: Symbol = throw new AssertionError("NoDenotation.owner") - override def name: Name = BootNameTable.newTermName("<none>") - override def info: Type = NoType + 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) } - object NameFilter { - final val WordSizeLog = 6 - final val DefinedNamesWords = 16 - final val DefinedNamesSize = DefinedNamesWords << WordSizeLog - final val DefinedNamesMask = DefinedNamesSize - 1 - - type FingerPrint = Array[Long] - - def includeName(bits: FingerPrint, name: Name): Unit = { - val hash = name.start & DefinedNamesMask - bits(hash >> 6) |= (1 << hash) - } - - def includeFingerPrint(bits1: FingerPrint, bits2: FingerPrint): Unit = - for (i <- 0 until DefinedNamesWords) bits1(i) |= bits2(i) - - def containsName(bits: FingerPrint, name: Name): Boolean = { - val hash = name.start & DefinedNamesMask - (bits(hash >> 6) & (1 << hash)) != 0 - } + class ErrorDenotation(implicit ctx: Context) extends SingleDenotation { + val symbol = NoSymbol + val info = NoType + validFor = Period.allInRun(ctx.runId) + } - def newNameFilter: FingerPrint = new Array[Long](DefinedNamesWords) +// --------------- DenotationSets ------------------------------------------------- + + /** A DenotationSet represents a set of denotation */ + trait DenotationSet { + def exists: Boolean + def toDenot(implicit ctx: Context): Denotation + def containsSig(sig: Signature)(implicit ctx: Context): Boolean + def filter(p: Symbol => Boolean)(implicit ctx: Context): DenotationSet + def filterDisjoint(denots: DenotationSet)(implicit ctx: Context): DenotationSet + def filterExcluded(flags: FlagSet)(implicit ctx: Context): DenotationSet + def filterAccessibleFrom(pre: Type)(implicit ctx: Context): DenotationSet + def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): DenotationSet + def union(that: DenotationSet) = + if (!this.exists) that + else if (that.exists) this + else DenotUnion(this, that) } - implicit def toFlagSet(denot: Denotation): FlagSet = denot.flags + case class DenotUnion(denots1: DenotationSet, denots2: DenotationSet) extends DenotationSet { + assert(denots1.exists && !denots2.exists) + private def derivedUnion(s1: DenotationSet, s2: DenotationSet) = + if (!s1.exists) s2 + else if (!s2.exists) s1 + else if ((s1 eq denots2) && (s2 eq denots2)) this + else new DenotUnion(s1, s2) + def exists = true + def toDenot(implicit ctx: Context) = denots1.toDenot & denots2.toDenot + def containsSig(sig: Signature)(implicit ctx: Context) = + (denots1 containsSig sig) || (denots2 containsSig sig) + def filter(p: Symbol => Boolean)(implicit ctx: Context) = + derivedUnion(denots1 filter p, denots2 filter p) + def filterDisjoint(denots: DenotationSet)(implicit ctx: Context): DenotationSet = + derivedUnion(denots1 filterDisjoint denots, denots2 filterDisjoint denots) + def filterExcluded(flags: FlagSet)(implicit ctx: Context): DenotationSet = + derivedUnion(denots1 filterExcluded flags, denots2 filterExcluded flags) + def filterAccessibleFrom(pre: Type)(implicit ctx: Context): DenotationSet = + derivedUnion(denots1 filterAccessibleFrom pre, denots2 filterAccessibleFrom pre) + def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): DenotationSet = + derivedUnion(denots1.asSeenFrom(pre, owner), denots2.asSeenFrom(pre, owner)) + } +} -}
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/Referenceds.scala b/src/dotty/tools/dotc/core/Referenceds.scala deleted file mode 100644 index 7ec862be2..000000000 --- a/src/dotty/tools/dotc/core/Referenceds.scala +++ /dev/null @@ -1,381 +0,0 @@ -package dotty.tools.dotc -package core - -import Denotations.Denotation -import Contexts.Context -import Names.Name -import Names.TypeName -import Symbols.NoSymbol -import Symbols.Symbol -import Types._, Periods._, Flags._, Transformers._ - - -/** Classes that implement referenced items and sets of them - */ -object Referenceds { - - /** The signature of a referenced. - * Overloaded referenceds with the same name are distinguished by - * their signatures. A signature is a list of the fully qualified names - * of the type symbols of the erasure of the parameters of the - * referenced. For instance a referenced definition - * - * def f(x: Int)(y: List[String]): String - * - * would have signature - * - * List("scala.Int".toTypeName, "scala.collection.immutable.List".toTypeName) - */ - type Signature = List[TypeName] - - /** The signature of a val or parameterless def, as opposed - * to List(), which is the signature of a zero-parameter def. - */ - val NullSignature = List(Names.EmptyTypeName) - - /** A referenced is the result of resolving - * a name (either simple identifier or select) during a given period. - * - * Referenced has two subclasses: OverloadedRefd and SymRefd. - * - * A SymRefd refers to a `symbol` and a type (`info`) that the symbol has - * when seen from the reference. - * - * Referenceds can be combined with `&` and `|`. - * & is conjunction, | is disjunction. - * - * `&` will create an overloaded reference from two - * non-overloaded references if their signatures differ. - * Analogously `|` of two references with different signatures will give - * an empty reference `NoRefd`. - * - * A referenced might refer to `NoSymbol`. This is the case if the referenced - * was produced from a disjunction of two referenceds with different symbols - * and there was no common symbol in a superclass that could substitute for - * both symbols. Here is an example: - * - * Say, we have: - * - * class A { def f: A } - * class B { def f: B } - * val x: A | B = if (???) new A else new B - * val y = x.f - * - * Then the referenced of `y` is `SymRefd(NoSymbol, A | B)`. - */ - abstract class Referenced extends DotClass { - - /** The referenced symbol, exists only for non-overloaded references */ - def symbol: Symbol - - /** The type info of the reference, exists only for non-overloaded references */ - def info: Type - - /** The period during which this reference is valid. */ - def validFor: Period - - /** Is this a reference to a type symbol? */ - def isType: Boolean = false - - /** Is this a reference to a term symbol? */ - def isTerm: Boolean = !isType - - /** Is this reference overloaded? */ - def isOverloaded = isInstanceOf[OverloadedRef] - - /** The signature of the reference */ - def signature: Signature - - /** Resolve overloaded reference to pick the one with the given signature */ - def atSignature(sig: Signature): Referenced - - /** The variant of this reference that's current in the given context. */ - def current(implicit ctx: Context): Referenced - - def exists: Boolean = true - - def orElse(that: => Referenced) = if (this.exists) this else that - - /** Form a reference by conjoining with reference `that` */ - def & (that: Referenced)(implicit ctx: Context): Referenced = - if (this eq that) this - else if (!this.exists) that - else if (!that.exists) this - else that match { - case that: SymRefd => - val r = mergeRef(this, that) - if (r ne NoRefd) r else OverloadedRef(this, that) - case that @ OverloadedRef(ref1, ref2) => - this & ref1 & ref2 - } - - /** Try to merge ref1 and ref2 without adding a new signature. - * If unsuccessful, return NoRefd. - */ - private def mergeRef(ref1: Referenced, ref2: SymRefd)(implicit ctx: Context): Referenced = ref1 match { - case ref1 @ OverloadedRef(ref11, ref12) => - val r1 = mergeRef(ref11, ref2) - if (r1 ne NoRefd) r1 else mergeRef(ref12, ref2) - case ref1: SymRefd => - if (ref1 eq ref2) ref1 - else if (ref1.signature == ref2.signature) { - def isEligible(sym1: Symbol, sym2: Symbol) = - if (sym1.isType) !sym1.isClass - else sym1.isConcrete || sym2.isDeferred || !sym2.exists - def normalize(info: Type) = - if (isType) info.bounds else info - val sym1 = ref1.symbol - val info1 = ref1.info - val sym2 = ref2.symbol - val info2 = ref2.info - val sym1Eligible = isEligible(sym1, sym2) - val sym2Eligible = isEligible(sym2, sym1) - val bounds1 = normalize(info1) - val bounds2 = normalize(info2) - if (sym2Eligible && bounds2 <:< bounds1) ref2 - else if (sym1Eligible && bounds1 <:< bounds2) ref1 - else new JointSymRefd( - if (sym2Eligible) sym2 else sym1, - bounds1 & bounds2, - ref1.validFor & ref2.validFor) - } else NoRefd - } - - def | (that: Referenced)(pre: Type)(implicit ctx: Context): Referenced = { - - def lubSym(sym1: Symbol, sym2: Symbol): Symbol = { - def qualifies(sym: Symbol) = - (sym isAccessibleFrom pre) && (sym2.owner isSubClass sym.owner) - sym1.allOverriddenSymbols find qualifies getOrElse NoSymbol - } - - def throwError = throw new MatchError(s"orRef($this, $that)") - - if (this eq that) this - else if (!this.exists) this - else if (!that.exists) that - else this match { - case ref1 @ OverloadedRef(ref11, ref12) => - ref1.derivedOverloadedRef((ref11 | that)(pre), (ref12 | that)(pre)) - case _ => - that match { - case ref2 @ OverloadedRef(ref21, ref22) => - ref2.derivedOverloadedRef((this | ref21)(pre), (this | ref22)(pre)) - case ref2: SymRefd => - this match { - case ref1: SymRefd => - if (ref1.signature != ref2.signature) NoRefd - else new JointSymRefd( - lubSym(ref1.symbol, ref2.symbol), - ref1.info | ref2.info, - ref1.validFor & ref2.validFor) - case _ => - throwError - } - case _ => - throwError - } - } - } - } - - /** The class of overloaded references - * @param variants The overloaded variants indexed by thheir signatures. - */ - case class OverloadedRef(ref1: Referenced, ref2: Referenced) extends Referenced { - def derivedOverloadedRef(r1: Referenced, r2: Referenced) = - if ((r1 eq ref1) && (r2 eq ref2)) this else OverloadedRef(r1, r2) - def symbol = unsupported("symbol") - def info = unsupported("info") - def signature = unsupported("signature") - def atSignature(sig: Signature): Referenced = - ref1.atSignature(sig) orElse ref2.atSignature(sig) - def validFor = ref1.validFor & ref2.validFor - def current(implicit ctx: Context): Referenced = - derivedOverloadedRef(ref1.current, ref2.current) - } - - abstract class SymRefd extends Referenced with ReferencedSet { - - override def isType = symbol.isType - override def signature: Signature = { - def sig(tp: Type): Signature = tp match { - case tp: PolyType => - tp.resultType match { - case mt: MethodType => mt.signature - case _ => List() - } - case mt: MethodType => mt.signature - case _ => NullSignature - } - if (isType) NullSignature else sig(info) - } - - def derivedSymRefd(s: Symbol, i: Type): SymRefd = - if ((s eq symbol) && (i eq info)) this else copy(s, i) - - protected def copy(s: Symbol, i: Type): SymRefd = this - - def atSignature(sig: Signature): Referenced = - if (sig == signature) this else NoRefd - - // ------ Transformations ----------------------------------------- - - private[this] var _validFor: Period = Nowhere - - def validFor = _validFor - def validFor_=(p: Period) = - _validFor = p - - /** The next SymRefd in this run, with wrap-around from last to first. - * - * There may be several `SymRefd`s with different validity - * representing the same underlying definition at different phases. - * These are called a "flock". Flock members are generated by - * @see SymRef.current. Flock members are connected in a ring - * with their `nextInRun` fields. - * - * There are the following invariants converning flock members - * - * 1) validity periods must be non-overlapping - * 2) the union of all validity periods must be a contiguous - * interval starting in FirstPhaseId. - */ - var nextInRun: SymRefd = this - - /** The version of this SymRefd that was valid in the first phase - * of this run. - */ - def initial: SymRefd = { - var current = nextInRun - while (current.validFor.code > this._validFor.code) current = current.nextInRun - current - } - - def current(implicit ctx: Context): SymRefd = { - val currentPeriod = ctx.period - val valid = _validFor - var current = this - if (currentPeriod.code > valid.code) { - // search for containing period as long as nextInRun increases. - var next = nextInRun - while (next.validFor.code > valid.code && - !(next.validFor contains currentPeriod)) { - current = next - next = next.nextInRun - } - if (next.validFor.code > valid.code) { - // in this case, containsPeriod(next._validFor, currentPeriod) - current = next - } else { - // not found, current points to highest existing variant - var startPid = current.validFor.lastPhaseId + 1 - val trans = ctx.root.transformersFor(current) - val endPid = trans.nextTransformer(startPid + 1).phaseId - 1 - next = trans.nextTransformer(startPid) transform current - if (next eq current) - startPid = current.validFor.firstPhaseId - else { - current.nextInRun = next - current = next - } - current.validFor = Period(currentPeriod.runId, startPid, endPid) - } - } else { - // currentPeriod < valid; in this case a version must exist - do { - current = current.nextInRun - } while (!(current.validFor contains currentPeriod)) - } - current - } - - def asDenotation = asInstanceOf[Denotation] - - // ------ ReferencedSet ops ---------------------------------------------- - - def toRef(implicit ctx: Context) = this - def containsSig(sig: Signature)(implicit ctx: Context) = - signature == sig - def filter(p: Symbol => Boolean)(implicit ctx: Context): ReferencedSet = - if (p(symbol)) this else NoRefd - def filterDisjoint(refs: ReferencedSet)(implicit ctx: Context): ReferencedSet = - if (refs.containsSig(signature)) NoRefd else this - def filterExcluded(flags: FlagSet)(implicit ctx: Context): ReferencedSet = - if (symbol.hasFlag(flags)) NoRefd else this - def filterAccessibleFrom(pre: Type)(implicit ctx: Context): ReferencedSet = - if (symbol.isAccessibleFrom(pre)) this else NoRefd - def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): ReferencedSet = - derivedSymRefd(symbol, info.asSeenFrom(pre, owner)) - } - - class UniqueSymRefd(val symbol: Symbol, - val info: Type, - initValidFor: Period) extends SymRefd { - validFor = initValidFor - override protected def copy(s: Symbol, i: Type): SymRefd = new UniqueSymRefd(s, i, validFor) - } - - class JointSymRefd(val symbol: Symbol, - val info: Type, - initValidFor: Period) extends SymRefd { - validFor = initValidFor - override protected def copy(s: Symbol, i: Type): SymRefd = new JointSymRefd(s, i, validFor) - } - - class ErrorRefd(implicit ctx: Context) extends SymRefd { - val symbol = NoSymbol - val info = NoType - validFor = Period.allInRun(ctx.runId) - } - - object NoRefd extends SymRefd { - val symbol = NoSymbol - val info = NoType - validFor = Nowhere - override def exists = false - override def isTerm = false - } - -// --------------- ReferencedSets ------------------------------------------------- - - /** A ReferencedSet represents a set of referenced */ - trait ReferencedSet { - def exists: Boolean - def toRef(implicit ctx: Context): Referenced - def containsSig(sig: Signature)(implicit ctx: Context): Boolean - def filter(p: Symbol => Boolean)(implicit ctx: Context): ReferencedSet - def filterDisjoint(refs: ReferencedSet)(implicit ctx: Context): ReferencedSet - def filterExcluded(flags: FlagSet)(implicit ctx: Context): ReferencedSet - def filterAccessibleFrom(pre: Type)(implicit ctx: Context): ReferencedSet - def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): ReferencedSet - def union(that: ReferencedSet) = - if (!this.exists) that - else if (that.exists) this - else RefUnion(this, that) - } - - case class RefUnion(refs1: ReferencedSet, refs2: ReferencedSet) extends ReferencedSet { - assert(refs1.exists && !refs2.exists) - private def derivedUnion(s1: ReferencedSet, s2: ReferencedSet) = - if (!s1.exists) s2 - else if (!s2.exists) s1 - else if ((s1 eq refs2) && (s2 eq refs2)) this - else new RefUnion(s1, s2) - def exists = true - def toRef(implicit ctx: Context) = refs1.toRef & refs2.toRef - def containsSig(sig: Signature)(implicit ctx: Context) = - (refs1 containsSig sig) || (refs2 containsSig sig) - def filter(p: Symbol => Boolean)(implicit ctx: Context) = - derivedUnion(refs1 filter p, refs2 filter p) - def filterDisjoint(refs: ReferencedSet)(implicit ctx: Context): ReferencedSet = - derivedUnion(refs1 filterDisjoint refs, refs2 filterDisjoint refs) - def filterExcluded(flags: FlagSet)(implicit ctx: Context): ReferencedSet = - derivedUnion(refs1 filterExcluded flags, refs2 filterExcluded flags) - def filterAccessibleFrom(pre: Type)(implicit ctx: Context): ReferencedSet = - derivedUnion(refs1 filterAccessibleFrom pre, refs2 filterAccessibleFrom pre) - def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): ReferencedSet = - derivedUnion(refs1.asSeenFrom(pre, owner), refs2.asSeenFrom(pre, owner)) - } -} - diff --git a/src/dotty/tools/dotc/core/Scopes.scala b/src/dotty/tools/dotc/core/Scopes.scala index f9fa69c1c..98f0b6390 100644 --- a/src/dotty/tools/dotc/core/Scopes.scala +++ b/src/dotty/tools/dotc/core/Scopes.scala @@ -11,7 +11,8 @@ import Names._ import Periods._ import Decorators._ import Contexts._ -import Referenceds._ +import Denotations._ +import SymDenotations.NoDenotation object Scopes { @@ -194,12 +195,12 @@ object Scopes { def next(): Symbol = { val r = e.sym; e = lookupNextEntry(e); r } } - /** The reference set of all the symbols with given name in this scope */ - def refsNamed(name: Name)(implicit ctx: Context): ReferencedSet = { - var syms: ReferencedSet = NoRefd + /** The denotation set of all the symbols with given name in this scope */ + def denotsNamed(name: Name)(implicit ctx: Context): DenotationSet = { + var syms: DenotationSet = NoDenotation var e = lookupEntry(name) while (e != null) { - syms = syms union e.sym.deref + syms = syms union e.sym.denot e = lookupNextEntry(e) } syms diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala new file mode 100644 index 000000000..d92d6eb27 --- /dev/null +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -0,0 +1,440 @@ +package dotty.tools.dotc +package core + +import Periods._, Contexts._, Symbols._, Denotations._, Names._, Annotations._ +import Types._, Flags._, Decorators._, Transformers._ +import Scopes.Scope +import collection.mutable +import collection.immutable.BitSet + +object SymDenotations { + + /** A denotation represents the contents of a definition + * during a period. + */ + abstract class SymDenotation(initFlags: FlagSet) extends SingleDenotation { + + def owner: Symbol + + def name: Name + + def symbol: Symbol + + def info: Type + + private[this] var _flags: FlagSet = initFlags + + def flags: FlagSet = _flags + + def flags_=(flags: FlagSet): Unit = + _flags |= flags + + def setFlags(flags: FlagSet): Unit = + _flags |= flags + + def resetFlags(flags: FlagSet): Unit = + _flags &~= flags + + private[this] var _privateWithin: Symbol = NoSymbol + + def privateWithin: Symbol = _privateWithin + + def privateWithin_=(sym: Symbol): Unit = + _privateWithin = sym + + final def isLoaded = _privateWithin != null + + private[this] var _annotations: List[Annotation] = Nil + + def annotations: List[Annotation] = _annotations + + def annotations_=(annots: List[Annotation]): Unit = + _annotations = annots + + final def isCompleted = _annotations != null + + /** is this symbol a class? */ + def isClass: Boolean = false + + /** is this symbol a method? */ + def isMethod: Boolean = false + + /** is this symbol the result of an erroneous definition? */ + def isError: Boolean = false + + def withType(tp: Type): SymDenotation = ??? + + override protected def copy(s: Symbol, i: Type): SingleDenotation = new UniqueRefDenotation(s, i, validFor) + } + + class CompleteSymDenotation( + val symbol: Symbol, + val owner: Symbol, + val name: Name, + initFlags: FlagSet, + val info: Type + ) extends SymDenotation(initFlags) + + trait LazyCompletion extends SymDenotation { + privateWithin = null + annotations = null + + override final def flags = { + if (!isLoaded) tryLoad() + super.flags + } + + override final def privateWithin = { + if (!isLoaded) tryLoad() + super.privateWithin + } + + override final def annotations: List[Annotation] = { + val annots = super.annotations + if (annots != null) annots else { tryComplete(); annotations } + } + + protected def tryLoad(): Unit = try { + if (flags is Locked) throw new CyclicReference(symbol) + setFlags(Locked) + load() + } catch { + case ex: CyclicReference => handleCycle() + } finally { + flags &~= Locked + } + + protected def tryComplete() = try { + if (flags is Locked) throw new CyclicReference(symbol) + complete() + } catch { + case ex: CyclicReference => handleCycle() + } finally { + flags &~= Locked + } + + protected def handleCycle(): Unit + protected def load(): Unit + protected def complete(): Unit + } + + abstract class LazySymDenotation( + val symbol: Symbol, + val owner: Symbol, + val name: Name, + initFlags: FlagSet + ) extends SymDenotation(initFlags) with LazyCompletion { + + private var currentInfo: Type = null + + override def info = { + if (currentInfo == null) complete() + currentInfo + } + } + + abstract class ClassDenotation(initFlags: FlagSet)(implicit ctx: Context) + extends SymDenotation(initFlags) { + import NameFilter._ + import util.LRU8Cache + + val symbol: ClassSymbol + + def typeParams: List[TypeSymbol] + + def parents: List[Type] + + def decls: Scope + + val info = ClassInfo(owner.thisType, this) + + private var memberCacheVar: LRU8Cache[Name, DenotationSet] = null + + private def memberCache: LRU8Cache[Name, DenotationSet] = { + if (memberCacheVar == null) memberCacheVar = new LRU8Cache + memberCacheVar + } + + private var thisTypeCache: ThisType = null + + def thisType(implicit ctx: Context): Type = { + if (thisTypeCache == null) + thisTypeCache = ThisType(symbol) + thisTypeCache + } + + private var typeConstructorCache: Type = null + + def typeConstructor(implicit ctx: Context): Type = { + if (typeConstructorCache == null) + typeConstructorCache = NamedType(thisType, symbol.name) + typeConstructorCache + } + + private var typeTemplateCache: Type = null + + def typeTemplate(implicit ctx: Context): Type = { + if (typeTemplateCache == null) + AppliedType.make(typeConstructor, typeParams map (_.typeConstructor)) + typeTemplateCache + } + + private var baseClassesVar: List[ClassSymbol] = null + private var superClassBitsVar: BitSet = null + + private def computeSuperClassBits(implicit ctx: Context): Unit = { + val seen = new mutable.BitSet + val locked = new mutable.BitSet + def addBaseClasses(bcs: List[ClassSymbol], to: List[ClassSymbol]) + : List[ClassSymbol] = bcs match { + case bc :: bcs1 => + val id = bc.superId + if (seen contains id) to + else if (locked contains id) throw new CyclicReference(symbol) + else { + locked += id + val bcs1added = addBaseClasses(bcs1, to) + seen += id + if (bcs1added eq bcs1) bcs else bc :: bcs1added + } + case _ => + to + } + def addParentBaseClasses(ps: List[Type], to: List[ClassSymbol]): List[ClassSymbol] = ps match { + case p :: ps1 => + addBaseClasses(p.baseClasses, addParentBaseClasses(ps1, to)) + case _ => + to + } + baseClassesVar = symbol :: addParentBaseClasses(parents, Nil) + superClassBitsVar = ctx.root.uniqueBits.findEntryOrUpdate(seen.toImmutable) + } + + def superClassBits(implicit ctx: Context): BitSet = { + if (superClassBitsVar == null) computeSuperClassBits + superClassBitsVar + } + + def baseClasses(implicit ctx: Context): List[ClassSymbol] = { + if (baseClassesVar == null) computeSuperClassBits + baseClassesVar + } + + /** Is this class a subclass of `clazz`? */ + final def isSubClass(clazz: ClassSymbol)(implicit ctx: Context): Boolean = { + superClassBits contains clazz.superId + } + + private var definedFingerPrintCache: FingerPrint = null + + private def computeDefinedFingerPrint(implicit ctx: Context): FingerPrint = { + var bits = newNameFilter + var e = decls.lastEntry + while (e != null) { + includeName(bits, name) + e = e.prev + } + var ps = parents + while (ps.nonEmpty) { + val parent = ps.head.typeSymbol + parent.denot match { + case classd: ClassDenotation => + includeFingerPrint(bits, classd.definedFingerPrint) + parent.denot.setFlags(Frozen) + case _ => + } + ps = ps.tail + } + definedFingerPrintCache = bits + bits + } + + /** 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. + */ + def enter(sym: Symbol)(implicit ctx: Context) = { + require(!(this is Frozen)) + decls enter sym + if (definedFingerPrintCache != null) + includeName(definedFingerPrintCache, sym.name) + if (memberCacheVar != null) + memberCache invalidate sym.name + } + + /** Delete symbol from current scope. + * Note: We require that this does not happen after the first time + * someone does a findMember on a subclass. + */ + def delete(sym: Symbol)(implicit ctx: Context) = { + require(!(this is Frozen)) + decls unlink sym + if (definedFingerPrintCache != null) + computeDefinedFingerPrint + if (memberCacheVar != null) + memberCache invalidate sym.name + } + + def definedFingerPrint(implicit ctx: Context): FingerPrint = { + val fp = definedFingerPrintCache + if (fp != null) fp else computeDefinedFingerPrint + } + + final def membersNamed(name: Name)(implicit ctx: Context): DenotationSet = { + var refs: DenotationSet = memberCache lookup name + if (refs == null) { + if (containsName(definedFingerPrint, name)) { + val ownDenots = decls.denotsNamed(name) + refs = ownDenots + var ps = parents + while (ps.nonEmpty) { + val parentSym = ps.head.typeSymbol + parentSym.denot match { + case parentd: ClassDenotation => + refs = refs union + parentd.membersNamed(name) + .filterExcluded(Flags.Private) + .asSeenFrom(thisType, parentSym) + .filterDisjoint(ownDenots) + case _ => + } + } + } else { + refs = NoDenotation + } + memberCache enter (name, refs) + } + refs + } + + private var baseTypeCache: java.util.HashMap[CachedType, Type] = null + private var baseTypeValid: RunId = NoRunId + + final def baseTypeOf(tp: Type)(implicit ctx: Context): Type = { + + def computeBaseTypeOf(tp: Type): Type = tp match { + case AppliedType(tycon, args) => + baseTypeOf(tycon).subst(tycon.typeParams, args) + case tp: TypeProxy => + baseTypeOf(tp.underlying) + case AndType(tp1, tp2) => + baseTypeOf(tp1) & baseTypeOf(tp2) + case OrType(tp1, tp2) => + baseTypeOf(tp1) | baseTypeOf(tp2) + case tp @ ClassInfo(pre, classd) => + def reduce(bt: Type, ps: List[Type]): Type = ps match { + case p :: ps1 => reduce(bt & baseTypeOf(p), ps1) + case _ => bt + } + if (classd.symbol == symbol) tp.typeTemplate + else reduce(NoType, classd.parents).substThis(classd.symbol, tp.prefix) + } + + if (symbol.isStaticMono) symbol.typeConstructor + else tp match { + case tp: CachedType => + if (baseTypeValid != ctx.runId) { + baseTypeCache = new java.util.HashMap[CachedType, Type] + baseTypeValid = ctx.runId + } + var basetp = baseTypeCache get tp + if (basetp == null) { + baseTypeCache.put(tp, NoType) + basetp = computeBaseTypeOf(tp) + baseTypeCache.put(tp, basetp) + } else if (basetp == NoType) { + throw new CyclicReference(symbol) + } + basetp + case _ => + computeBaseTypeOf(tp) + } + } + + private var memberNamesCache: Map[NameFilter, Set[Name]] = Map() + + def memberNames(keepOnly: NameFilter)(implicit ctx: Context): Set[Name] = + memberNamesCache get keepOnly match { + case Some(names) => + names + case _ => + val inheritedNames = (parents flatMap (_.memberNames(thisType, keepOnly))).toSet + val ownNames = decls.iterator map (_.name) + val candidates = inheritedNames ++ ownNames + val names = candidates filter (keepOnly(thisType, _)) + memberNamesCache += (keepOnly -> names) + names + } + } + + class CompleteClassDenotation( + val symbol: ClassSymbol, + val owner: Symbol, + val name: Name, + initFlags: FlagSet, + val typeParams: List[TypeSymbol], + val parents: List[Type], + val decls: Scope + )(implicit ctx: Context) extends ClassDenotation(initFlags) + + abstract class LazyClassDenotation( + val symbol: ClassSymbol, + val owner: Symbol, + val name: Name, + initFlags: FlagSet + )(implicit ctx: Context) extends ClassDenotation(initFlags) with LazyCompletion { + + protected var _typeParams: List[TypeSymbol] = null + protected var _parents: List[Type] = null + protected var _decls: Scope = null + + final def typeParams: List[TypeSymbol] = { + val tparams = _typeParams + if (tparams != null) tparams else { tryLoad(); typeParams } + } + + final def parents: List[Type] = { + val ps = _parents + if (ps != null) ps else { tryComplete(); parents } + } + + final def decls: Scope = { + val ds = _decls + if (ds != null) ds else { tryComplete(); decls } + } + } + + object NoDenotation extends SymDenotation(Flags.Empty) { + override def symbol: Symbol = NoSymbol + override def owner: Symbol = throw new AssertionError("NoDenotation.owner") + override def name: Name = BootNameTable.newTermName("<none>") + override def info: Type = NoType + } + + object NameFilter { + final val WordSizeLog = 6 + final val DefinedNamesWords = 16 + final val DefinedNamesSize = DefinedNamesWords << WordSizeLog + final val DefinedNamesMask = DefinedNamesSize - 1 + + type FingerPrint = Array[Long] + + def includeName(bits: FingerPrint, name: Name): Unit = { + val hash = name.start & DefinedNamesMask + bits(hash >> 6) |= (1 << hash) + } + + def includeFingerPrint(bits1: FingerPrint, bits2: FingerPrint): Unit = + for (i <- 0 until DefinedNamesWords) bits1(i) |= bits2(i) + + def containsName(bits: FingerPrint, name: Name): Boolean = { + val hash = name.start & DefinedNamesMask + (bits(hash >> 6) & (1 << hash)) != 0 + } + + def newNameFilter: FingerPrint = new Array[Long](DefinedNamesWords) + } + + implicit def toFlagSet(denot: SymDenotation): FlagSet = denot.flags + +} diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index bd3ab18f9..9c8738527 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -9,9 +9,9 @@ import java.lang.AssertionError import Decorators._ import Symbols._ import Contexts._ -import Denotations._ +import SymDenotations._ import Types._, Annotations._ -import Referenceds.{Referenced, SymRefd, OverloadedRef} +import Denotations.{Denotation, SingleDenotation, MultiDenotation} import collection.mutable object Symbols { @@ -21,69 +21,26 @@ object Symbols { */ abstract class Symbol { - /** The non-private symbol whose type matches the type of this symbol - * in in given class. - * - * @param ofClass 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 ref = inClass.info.nonPrivateDecl(name) - if (ref.isTerm) { - val targetType = site.memberInfo(this) - if (ref.isOverloaded) ref = ref.atSignature(targetType.signature) - val candidate = ref.symbol - if (site.memberInfo(candidate) matches targetType) candidate - else NoSymbol - } else ref.symbol - } - - def overriddenSymbol(inClass: ClassSymbol)(implicit ctx: Context): Symbol = - if (owner isSubClass inClass) matchingSymbol(inClass, owner.thisType) - else NoSymbol - - def isProtected: Boolean = ??? - def isStable(implicit ctx: Context): Boolean = false - def accessBoundary: ClassSymbol = ??? - def isContainedIn(boundary: ClassSymbol) = ??? - def baseClasses: List[ClassSymbol] = ??? + /** Is symbol different from NoSymbol? */ def exists = true - def hasAnnotation(ann: Annotation): Boolean = ??? - def hasAnnotation(ann: ClassSymbol): Boolean = ??? + /** This symbol, if it exists, otherwise the result of evaluating `that` */ def orElse(that: => Symbol) = if (exists) this else that - /** A isAbove B iff A can always be used instead of B - */ - def isAbove(that: Symbol)(implicit ctx: Context): Boolean = - (that.owner isSubClass this.owner) && - (this isAsAccessible that) - - /** A isBelow B iff the reference A & B can always be simplified to A - */ - def isBelow(that: Symbol)(implicit ctx: Context): Boolean = - (this.owner isSubClass that.owner) || - (this isAsAccessible that) - - def isAsAccessible(that: Symbol)(implicit ctx: Context): Boolean = - !(this is Protected) && !(that is Protected) && // protected members are incomparable - (that.accessBoundary isContainedIn this.accessBoundary) && - this.isStable || !that.isStable - /** Set the denotation of this symbol. */ - def setDenotation(denot: Denotation) = + def setDenotation(denot: SymDenotation) = lastDenot = denot /** The last denotation of this symbol */ - protected[this] var lastDenot: Denotation = null + protected[this] var lastDenot: SymDenotation = null /** Load denotation of this symbol */ - protected def loadDenot(implicit ctx: Context): Denotation + protected def loadDenot(implicit ctx: Context): SymDenotation /** The denotation of this symbol */ - def deref(implicit ctx: Context): Denotation = { + def denot(implicit ctx: Context): SymDenotation = { val denot = lastDenot if (denot == null) loadDenot else { @@ -91,7 +48,7 @@ object Symbols { val valid = denot.validFor if (valid contains currentPeriod) denot else if (valid.runId != currentPeriod.runId) reloadDenot - else denot.current.asDenotation + else denot.current.asSymDenotation } } @@ -99,31 +56,33 @@ object Symbols { * Get loaded denotation if lastDenot points to a denotation from * a different run. !!! needed? */ - private def reloadDenot(implicit ctx: Context): Denotation = { - val initDenot = lastDenot.initial.asDenotation + private def reloadDenot(implicit ctx: Context): SymDenotation = { + val initDenot = lastDenot.initial.asSymDenotation val newSym: Symbol = ctx.atPhase(FirstPhaseId) { implicit ctx => initDenot.owner.info.decl(initDenot.name) - .atSignature(deref.signature).symbol + .atSignature(denot.signature).symbol } if (newSym eq this) { // no change, change validity var d = initDenot do { d.validFor = Period(ctx.runId, d.validFor.firstPhaseId, d.validFor.lastPhaseId) - d = d.nextInRun.asDenotation + d = d.nextInRun.asSymDenotation } while (d ne initDenot) } - newSym.deref + newSym.denot } def isType: Boolean def isTerm = !isType + + // forwarders for sym methods - def owner(implicit ctx: Context): Symbol = deref.owner - def name(implicit ctx: Context): Name = deref.name - def flags(implicit ctx: Context): FlagSet = deref.flags - def info(implicit ctx: Context): Type = deref.info + def owner(implicit ctx: Context): Symbol = denot.owner + def name(implicit ctx: Context): Name = denot.name + def flags(implicit ctx: Context): FlagSet = denot.flags + def info(implicit ctx: Context): Type = denot.info def prefix(implicit ctx: Context) = owner.thisType def allOverriddenSymbols: Iterator[Symbol] = ??? @@ -140,6 +99,9 @@ object Symbols { def isRoot: Boolean = ??? def moduleClass: Symbol = ??? def cloneSymbol: Symbol = ??? + def hasAnnotation(ann: Annotation): Boolean = ??? + def hasAnnotation(ann: ClassSymbol): Boolean = ??? + def asTerm: TermSymbol = ??? def asType: TypeSymbol = ??? @@ -159,18 +121,71 @@ object Symbols { def isProperSubClass(that: Symbol): Boolean = (this ne that) && (this isSubClass that) + def privateWithin(implicit ctx: Context): Symbol = denot.privateWithin def isAbstractType: Boolean = ??? def newAbstractType(name: TypeName, info: TypeBounds): TypeSymbol = ??? def newAbstractTerm(name: TermName, tpe: Type): TypeSymbol = ??? def isClass: Boolean = false - def isMethod(implicit ctx: Context): Boolean = deref.isMethod + def isMethod(implicit ctx: Context): Boolean = denot.isMethod def hasFlag(required: FlagSet)(implicit ctx: Context): Boolean = (flags & required) != Flags.Empty def hasAllFlags(required: FlagSet)(implicit ctx: Context): Boolean = (flags & required) == flags + /** The non-private symbol whose type matches the type of this symbol + * in in given class. + * + * @param ofClass 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 ref = inClass.info.nonPrivateDecl(name) + if (ref.isTerm) { + val targetType = site.memberInfo(this) + if (ref.isOverloaded) ref = ref.atSignature(targetType.signature) + val candidate = ref.symbol + if (site.memberInfo(candidate) matches targetType) candidate + else NoSymbol + } else ref.symbol + } + + def overriddenSymbol(inClass: ClassSymbol)(implicit ctx: Context): Symbol = + if (owner isSubClass inClass) matchingSymbol(inClass, owner.thisType) + else NoSymbol + + def isStable(implicit ctx: Context): Boolean = false + + /** 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 + */ + def accessBoundary(base: Symbol)(implicit ctx: Context): Symbol = { + val denot = this.denot + val fs = denot.flags + if (fs is PrivateOrLocal) owner + else if (fs is StaticProtected) defn.RootClass + else if (denot.privateWithin.exists && !ctx.phase.erasedTypes) denot.privateWithin + else if (fs is Protected) base + else defn.RootClass + } + + /** Is this symbol contained in `boundary`? */ + def isContainedIn(boundary: Symbol)(implicit ctx: Context): Boolean = + if (this eq boundary) true + else if (!this.exists || + (this is PackageClass) && !(boundary is PackageClass)) false + else owner.isContainedIn(boundary) + + /** Is this symbol accessible whenever `that` symbol is accessible? + * Does not take into account status of protected members. + */ + def isAsAccessible(that: Symbol)(implicit ctx: Context): Boolean = + (that.accessBoundary(NoSymbol) isContainedIn this.accessBoundary(NoSymbol)) && + this.isStable || !that.isStable + def containsNull(implicit ctx: Context): Boolean = isClass && !(isSubClass(defn.AnyValClass)) - } abstract class TermSymbol extends Symbol { @@ -183,16 +198,6 @@ object Symbols { ) } - final val MutableMethodByNameParam = Mutable | Method | ByNameParam - - trait RefinementSymbol extends Symbol { - override def deref(implicit ctx: Context) = lastDenot - } - - abstract class RefinementTermSymbol extends TermSymbol with RefinementSymbol - - abstract class RefinementTypeSymbol extends TypeSymbol with RefinementSymbol - abstract class TypeSymbol extends Symbol { def name: TypeName def isType = false @@ -207,13 +212,15 @@ object Symbols { override def isClass = true private var superIdHint: Int = -1 - override def deref(implicit ctx: Context): ClassDenotation = - super.deref.asInstanceOf[ClassDenotation] + override def denot(implicit ctx: Context): ClassDenotation = + super.denot.asInstanceOf[ClassDenotation] def typeOfThis(implicit ctx: Context): Type = ??? - override def typeConstructor(implicit ctx: Context): Type = deref.typeConstructor - override def typeTemplate(implicit ctx: Context): Type = deref.typeTemplate + def baseClasses(implicit ctx: Context): List[ClassSymbol] = denot.baseClasses + + override def typeConstructor(implicit ctx: Context): Type = denot.typeConstructor + override def typeTemplate(implicit ctx: Context): Type = denot.typeTemplate /** The unique, densely packed identifier of this class symbol. Should be called * only if class is a super class of some other class. @@ -239,7 +246,7 @@ object Symbols { } object NoSymbol extends Symbol { - def loadDenot(implicit ctx: Context): Denotation = NoDenotation + def loadDenot(implicit ctx: Context): SymDenotation = NoDenotation override def exists = false def isType = false override def isTerm = false @@ -249,4 +256,4 @@ object Symbols { implicit def toFlagSet(sym: Symbol)(implicit ctx: Context): FlagSet = sym.flags -}
\ No newline at end of file +} diff --git a/src/dotty/tools/dotc/core/Transformers.scala b/src/dotty/tools/dotc/core/Transformers.scala index ae58080e4..ee943e13e 100644 --- a/src/dotty/tools/dotc/core/Transformers.scala +++ b/src/dotty/tools/dotc/core/Transformers.scala @@ -1,15 +1,15 @@ package dotty.tools.dotc package core -import Periods._, Denotations._, Contexts._, Types._, Referenceds._ +import Periods._, SymDenotations._, Contexts._, Types._, Denotations._ import java.lang.AssertionError trait Transformers { self: RootContext => import Transformers._ - def transformersFor(ref: SymRefd): TransformerGroup = ref match { - case _: Denotation => denotTransformers + def transformersFor(ref: SingleDenotation): TransformerGroup = ref match { + case _: SymDenotation => denotTransformers case _ => refTransformers } @@ -28,12 +28,12 @@ object Transformers { def lastPhaseId = nextTransformer(phaseId).phaseId - 1 def validFor(implicit ctx: Context): Period = Period(ctx.runId, phaseId, lastPhaseId) - def transform(ref: SymRefd)(implicit ctx: Context): SymRefd + def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation } object NoTransformer extends Transformer { val phaseId = lastPhaseId + 1 - def transform(ref: SymRefd)(implicit ctx: Context): SymRefd = + def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = unsupported("transform") } @@ -48,4 +48,4 @@ object Transformers { install(pid - 1, trans) } } -}
\ No newline at end of file +} diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index d48526fdb..61e7fa26c 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -10,8 +10,8 @@ import Scopes._ import Constants._ import Contexts._ import Annotations._ +import SymDenotations._ import Denotations._ -import Referenceds._ import Periods._ import scala.util.hashing.{ MurmurHash3 => hashing } import collection.mutable @@ -256,42 +256,42 @@ object Types { } /** The declaration of this type with given name */ - final def decl(name: Name)(implicit ctx: Context): Referenced = + final def decl(name: Name)(implicit ctx: Context): Denotation = findDecl(name, this, Flags.Empty) /** The non-private declaration of this type with given name */ - final def nonPrivateDecl(name: Name)(implicit ctx: Context): Referenced = + final def nonPrivateDecl(name: Name)(implicit ctx: Context): Denotation = findDecl(name, this, Flags.Private) /** The non-private declaration of this type with given name */ - final def findDecl(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Referenced = this match { + final def findDecl(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Denotation = this match { case tp: RefinedType => tp.findDecl(name, pre) case tp: ClassInfo => tp.classd.decls - .refsNamed(name) + .denotsNamed(name) .filterAccessibleFrom(pre) .filterExcluded(excluded) .asSeenFrom(pre, tp.classd.symbol) - .toRef + .toDenot case tp: TypeProxy => tp.underlying.findDecl(name, pre, excluded) } /** The member of this type with given name */ - final def member(name: Name)(implicit ctx: Context): Referenced = + final def member(name: Name)(implicit ctx: Context): Denotation = findMember(name, this, Flags.Empty) /** The non-private member of this type with given name */ - final def nonPrivateMember(name: Name)(implicit ctx: Context): Referenced = + final def nonPrivateMember(name: Name)(implicit ctx: Context): Denotation = findMember(name, this, Flags.Private) /** Find member of this type with given name and - * produce a referenced that contains the type of the member + * produce a denotation that contains the type of the member * as seen from given prefix `pre`. Exclude all members with one * of the flags in `excluded` from consideration. */ - final def findMember(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Referenced = this match { + final def findMember(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Denotation = this match { case tp: RefinedType => tp.parent.findMember(name, pre, excluded | Flags.Private) & tp.findDecl(name, pre) @@ -299,13 +299,13 @@ object Types { tp.underlying.findMember(name, pre, excluded) case tp: ClassInfo => val classd = tp.classd - val candidates = classd.memberRefsNamed(name) + val candidates = classd.membersNamed(name) val resultSyms = candidates .filterAccessibleFrom(pre) .filterExcluded(excluded) .asSeenFrom(pre, classd.symbol) - if (resultSyms.exists) resultSyms.toRef - else new ErrorRefd // todo: refine + if (resultSyms.exists) resultSyms.toDenot + else new ErrorDenotation // todo: refine case tp: AndType => tp.tp1.findMember(name, pre, excluded) & tp.tp2.findMember(name, pre, excluded) case tp: OrType => @@ -395,7 +395,7 @@ object Types { */ def signature: Signature = NullSignature - final def baseType(base: Symbol)(implicit ctx: Context): Type = base.deref match { + final def baseType(base: Symbol)(implicit ctx: Context): Type = base.denot match { case classd: ClassDenotation => classd.baseTypeOf(this) case _ => NoType } @@ -561,35 +561,35 @@ object Types { val prefix: Type val name: Name - private[this] var lastReferenced: Referenced = null + private[this] var lastDenotation: Denotation = null private def checkPrefix(sym: Symbol) = sym.isAbstractType || sym.isClass - /** The referenced currently denoted by this type */ - def deref(implicit ctx: Context): Referenced = { + /** The denotation currently denoted by this type */ + def denot(implicit ctx: Context): Denotation = { val validPeriods = - if (lastReferenced != null) lastReferenced.validFor else Nowhere + if (lastDenotation != null) lastDenotation.validFor else Nowhere if (!(validPeriods contains ctx.period)) { val thisPeriod = ctx.period - lastReferenced = + lastDenotation = if (validPeriods.runId == thisPeriod.runId) - lastReferenced.current + lastDenotation.current else if (thisPeriod.phaseId > name.lastIntroPhaseId) ctx.atPhase(name.lastIntroPhaseId)(prefix.member(name)(_)).current else prefix.member(name) - if (checkPrefix(lastReferenced.symbol) && !prefix.isLegalPrefix) - throw new MalformedType(prefix, lastReferenced.symbol) + if (checkPrefix(lastDenotation.symbol) && !prefix.isLegalPrefix) + throw new MalformedType(prefix, lastDenotation.symbol) } - lastReferenced + lastDenotation } def isType = name.isTypeName def isTerm = name.isTermName - def symbol(implicit ctx: Context): Symbol = deref.symbol - def info(implicit ctx: Context): Type = deref.info + def symbol(implicit ctx: Context): Symbol = denot.symbol + def info(implicit ctx: Context): Type = denot.info override def underlying(implicit ctx: Context): Type = info @@ -610,7 +610,7 @@ object Types { protected val fixedSym: Symbol override def symbol(implicit ctx: Context): Symbol = fixedSym override def info(implicit ctx: Context): Type = fixedSym.info - override def deref(implicit ctx: Context): Referenced = fixedSym.deref + override def denot(implicit ctx: Context): Denotation = fixedSym.denot } final class TermRefNoPrefix(val fixedSym: TermSymbol)(implicit ctx: Context) @@ -619,8 +619,8 @@ object Types { final class TermRefWithSignature(prefix: Type, name: TermName, override val signature: Signature) extends TermRef(prefix, name) { override def computeHash = doHash((name, signature), prefix) - override def deref(implicit ctx: Context): Referenced = - super.deref.atSignature(signature) + override def denot(implicit ctx: Context): Denotation = + super.denot.atSignature(signature) } final class TypeRefNoPrefix(val fixedSym: TypeSymbol)(implicit ctx: Context) @@ -731,17 +731,17 @@ object Types { infos1 map (_.substThis(this, thistp)) } - def findDecl(name: Name, pre: Type)(implicit ctx: Context): Referenced = { + def findDecl(name: Name, pre: Type)(implicit ctx: Context): Denotation = { var ns = names var is = infos - var ref: Referenced = NoRefd - while (ns.nonEmpty && (ref eq NoRefd)) { + var denot: Denotation = NoDenotation + while (ns.nonEmpty && (denot eq NoDenotation)) { if (ns.head == name) - ref = new JointSymRefd(NoSymbol, is.head.substThis(this, pre), Period.allInRun(ctx.runId)) + denot = new JointRefDenotation(NoSymbol, is.head.substThis(this, pre), Period.allInRun(ctx.runId)) ns = ns.tail is = is.tail } - ref + denot } override def computeHash = doHash(names, parent, infos) @@ -1173,4 +1173,4 @@ object Types { } case _ => ys.isEmpty } -}
\ No newline at end of file +} |