diff options
Diffstat (limited to 'src/dotty/tools/dotc/core/References.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/References.scala | 274 |
1 files changed, 0 insertions, 274 deletions
diff --git a/src/dotty/tools/dotc/core/References.scala b/src/dotty/tools/dotc/core/References.scala deleted file mode 100644 index a5756ebec..000000000 --- a/src/dotty/tools/dotc/core/References.scala +++ /dev/null @@ -1,274 +0,0 @@ -package dotty.tools.dotc -package core - -import Denotations.Denotation -import Contexts.Context -import Names.Name -import Names.TypeName -import Periods.containsPeriod -import Symbols.NoSymbol -import Symbols.Symbol -import Types._ -import Flags._ - - -/** Classes that implement references and sets of references - */ -object References { - - /** The signature of a reference. - * Overloaded references 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 - * reference. For instance a reference to the 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 reference is the result of resolving a name (either simple identifier or select). - * - * Reference has two subclasses: OverloadedRef and SymRef. - * - * A SymRef refers to a `symbol` and a type (`info`) that the symbol has - * when referred through this reference. - * - * References (`SymRef`s) 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 `NoRef`. - * - * A reference might refer to `NoSymbo`. This is the case if the reference - * was produced from a disjunction of two references 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 reference of `y` is `SymRef(NoSymbol, A | B)`. - */ - abstract class Reference { - - /** The referenced symbol, exists only for non-overloaded references */ - def symbol: Symbol = - throw new UnsupportedOperationException(this.getClass + ".symbol") - - /** The type info of the reference, exists only for non-overloaded references */ - def info: Type = - throw new UnsupportedOperationException(this.getClass+".info") - - /** Is this a reference to a type symbol? */ - def isType: Boolean = false - - /** The signature of the reference */ - def signature: Signature = - throw new UnsupportedOperationException(this.getClass+".signature") - - /** Resolve overloaded reference to pick the one with the given signature */ - def atSignature(sig: Signature): Reference - - def exists: Boolean = true - - def orElse(that: => Reference) = if (this.exists) this else that - - /** Form a reference by conjoining with reference `that` */ - def & (that: Reference)(implicit ctx: Context): Reference = - if (this eq that) this - else if (!this.exists) that - else if (!that.exists) this - else that match { - case that @ SymRef(sym2, info2) => - val r = mergeRef(this, that) - if (r ne NoRef) 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 NoRef. - */ - private def mergeRef(ref1: Reference, ref2: SymRef)(implicit ctx: Context): Reference = ref1 match { - case ref1 @ OverloadedRef(ref11, ref12) => - val r1 = mergeRef(ref11, ref2) - if (r1 ne NoRef) r1 else mergeRef(ref12, ref2) - case ref1 @ SymRef(sym1, info1) => - if (ref1 eq ref2) ref1 - else if (ref1.signature == ref2.signature) { - val SymRef(sym2, info2) = ref2 - 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 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 JointSymRef(if (sym2Eligible) sym2 else sym1, bounds1 & bounds2) - } else NoRef - } - - def | (that: Reference)(pre: Type)(implicit ctx: Context): Reference = { - - 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: SymRef => - this match { - case ref1: SymRef => - if (ref1.signature != ref2.signature) NoRef - else new JointSymRef(lubSym(ref1.symbol, ref2.symbol), ref1.info | ref2.info) - case _ => - throwError - } - case _ => - throwError - } - } - } - } - - /** The class of overloaded references - * @param variants The overloaded variants indexed by thheir signatures. - */ - case class OverloadedRef(ref1: Reference, ref2: Reference) extends Reference { - def derivedOverloadedRef(r1: Reference, r2: Reference) = - if ((r1 eq ref1) && (r2 eq ref2)) this else OverloadedRef(r1, r2) - def atSignature(sig: Signature): Reference = - ref1.atSignature(sig) orElse ref2.atSignature(sig) - } - - abstract case class SymRef(override val symbol: Symbol, - override val info: Type) extends Reference with RefSet { - 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 derivedSymRef(s: Symbol, i: Type): SymRef = - if ((s eq symbol) && (i eq info)) this else copy(s, i) - - protected def copy(s: Symbol, i: Type): SymRef = this - - def atSignature(sig: Signature): Reference = - if (sig == signature) this else NoRef - - // ------ RefSet ops ---------------------------------------------- - - def toRef(implicit ctx: Context) = this - def containsSig(sig: Signature)(implicit ctx: Context) = - signature == sig - def filter(p: Symbol => Boolean)(implicit ctx: Context): RefSet = - if (p(symbol)) this else NoRef - def filterDisjoint(refs: RefSet)(implicit ctx: Context): RefSet = - if (refs.containsSig(signature)) NoRef else this - def filterExcluded(flags: FlagSet)(implicit ctx: Context): RefSet = - if (symbol.hasFlag(flags)) NoRef else this - def filterAccessibleFrom(pre: Type)(implicit ctx: Context): RefSet = - if (symbol.isAccessibleFrom(pre)) this else NoRef - def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): RefSet = - derivedSymRef(symbol, info.asSeenFrom(pre, owner)) - } - - class UniqueSymRef(symbol: Symbol, info: Type)(implicit ctx: Context) extends SymRef(symbol, info) { - private val denot = symbol.deref - private val runid = ctx.runId - override protected def copy(s: Symbol, i: Type): SymRef = new UniqueSymRef(s, i) - } - - class JointSymRef(symbol: Symbol, info: Type)(implicit ctx: Context) extends SymRef(symbol, info) { - private val period = ctx.period - override protected def copy(s: Symbol, i: Type): SymRef = new JointSymRef(s, i) - } - - object ErrorRef extends SymRef(NoSymbol, NoType) { - } - - object NoRef extends SymRef(NoSymbol, NoType) { - override def exists = false - } - -// --------------- RefSets ------------------------------------------------- - - trait RefSet { - def exists: Boolean - def toRef(implicit ctx: Context): Reference - def containsSig(sig: Signature)(implicit ctx: Context): Boolean - def filter(p: Symbol => Boolean)(implicit ctx: Context): RefSet - def filterDisjoint(refs: RefSet)(implicit ctx: Context): RefSet - def filterExcluded(flags: FlagSet)(implicit ctx: Context): RefSet - def filterAccessibleFrom(pre: Type)(implicit ctx: Context): RefSet - def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): RefSet - def union(that: RefSet) = - if (!this.exists) that - else if (that.exists) this - else RefUnion(this, that) - } - - case class RefUnion(refs1: RefSet, refs2: RefSet) extends RefSet { - assert(refs1.exists && !refs2.exists) - private def derivedUnion(s1: RefSet, s2: RefSet) = - 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: RefSet)(implicit ctx: Context): RefSet = - derivedUnion(refs1 filterDisjoint refs, refs2 filterDisjoint refs) - def filterExcluded(flags: FlagSet)(implicit ctx: Context): RefSet = - derivedUnion(refs1 filterExcluded flags, refs2 filterExcluded flags) - def filterAccessibleFrom(pre: Type)(implicit ctx: Context): RefSet = - derivedUnion(refs1 filterAccessibleFrom pre, refs2 filterAccessibleFrom pre) - def asSeenFrom(pre: Type, owner: Symbol)(implicit ctx: Context): RefSet = - derivedUnion(refs1.asSeenFrom(pre, owner), refs2.asSeenFrom(pre, owner)) - } -} - |