diff options
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 114 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Flags.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 18 | ||||
-rw-r--r-- | src/dotty/tools/dotc/printing/PlainPrinter.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 3 |
6 files changed, 115 insertions, 31 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index b69997836..76c5d79b4 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -213,8 +213,8 @@ object Denotations { else this.asInstanceOf[SingleDenotation] - /** Form a denotation by conjoining with denotation `that` */ - def & (that: Denotation)(implicit ctx: Context): Denotation = + /** Form a denotation by conjoining with denotation `that` (OUTDATED, kept only for checking) */ + private def & (that: Denotation)(implicit ctx: Context): Denotation = if (this eq that) this else if (!this.exists) that else if (!that.exists) this @@ -227,7 +227,7 @@ object Denotations { } /** Try to merge denot1 and denot2 without adding a new signature. - * If unsuccessful, return NoDenotation. + * If unsuccessful, return NoDenotation. (OUTDATED, kept only for checking) */ private def mergeDenot(denot1: Denotation, denot2: SingleDenotation)(implicit ctx: Context): Denotation = denot1 match { case denot1 @ MultiDenotation(denot11, denot12) => @@ -266,17 +266,97 @@ object Denotations { } } + + /** Form a denotation by conjoining with denotation `that` */ + def & (that: Denotation, pre: Type)(implicit ctx: Context): Denotation = { + + /** Try to merge denot1 and denot2 without adding a new signature. + * If unsuccessful, return NoDenotation. + */ + def mergeDenot(denot1: Denotation, denot2: SingleDenotation): Denotation = denot1 match { + case denot1 @ MultiDenotation(denot11, denot12) => + val d1 = mergeDenot(denot11, denot2) + if (d1.exists) denot1.derivedMultiDenotation(d1, denot2) + else { + val d2 = mergeDenot(denot12, denot2) + if (d2.exists) denot1.derivedMultiDenotation(denot11, d2) + else NoDenotation + } + case denot1: SingleDenotation => + if (denot1 eq denot2) denot1 + else if (denot1.signature != denot2.signature) NoDenotation + else { + val info1 = denot1.info + val info2 = denot2.info + val sym2 = denot2.symbol + def sym2Accessible = sym2.isAccessibleFrom(pre) + if (info2 <:< info1 && sym2Accessible) denot2 + else { + val sym1 = denot1.symbol + def sym1Accessible = sym1.isAccessibleFrom(pre) + if (info1 <:< info2 && sym1Accessible) denot1 + else { + val sym = + if (!sym1Accessible) sym2 + else if (!sym2Accessible) sym1 + else if (sym2 isAsConcrete sym1) sym2 + else sym1 + new JointRefDenotation(sym, info1 & info2, denot1.validFor & denot2.validFor) + } + } + } + } + + val result = + 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.exists) r else MultiDenotation(this, that) + case that @ MultiDenotation(denot1, denot2) => + this & (denot1, pre) & (denot2, pre) + } + if (ctx.settings.debug.value) { + val alt = this & that + if (result != alt && (result.info != alt.info || result.symbol != alt.symbol)) + println(s"""discrepancy when computing $this & $that from $pre + |previousy: $alt + |now : $result + |this.info = ${this.info.show} + |that.info = ${that.info.show} + |${this.info <:< that.info} ${that.info <:< this.info}""".stripMargin) + } + result + } + /** Form a choice between this denotation and that one. * @param pre The prefix type of the members of the denotation, used * to determine an accessible symbol if it exists. */ - def | (that: Denotation)(pre: Type)(implicit ctx: Context): Denotation = { + def | (that: Denotation, pre: Type)(implicit ctx: Context): Denotation = { - def lubSym(sym1: Symbol, sym2: Symbol): Symbol = { - def qualifies(sym: Symbol) = - sym.isAccessibleFrom(pre) && sym2.owner.isSubClass(sym.owner) - sym1.allOverriddenSymbols findSymbol qualifies - } + def unionDenot(denot1: SingleDenotation, denot2: SingleDenotation): Denotation = + if (denot1.signature != denot2.signature) NoDenotation + else { + val info1 = denot1.info + val info2 = denot2.info + val sym2 = denot2.symbol + def sym2Accessible = sym2.isAccessibleFrom(pre) + if (info1 <:< info2 && sym2Accessible) denot2 + else { + val sym1 = denot1.symbol + def sym1Accessible = sym1.isAccessibleFrom(pre) + if (info2 <:< info1 && sym1Accessible) denot1 + else { + def qualifies(sym: Symbol) = + sym.isAccessibleFrom(pre) && sym2.owner.isSubClass(sym.owner) + val lubSym = sym1.allOverriddenSymbols findSymbol qualifies + new JointRefDenotation(lubSym, info1 | info2, denot1.validFor & denot2.validFor) + } + } + } def throwError = throw new MatchError(s"$this | $that") @@ -285,19 +365,15 @@ object Denotations { else if (!that.exists) that else this match { case denot1 @ MultiDenotation(denot11, denot12) => - denot1.derivedMultiDenotation((denot11 | that)(pre), (denot12 | that)(pre)) + denot1.derivedMultiDenotation(denot11 | (that, pre), denot12 | (that, pre)) case _ => that match { case denot2 @ MultiDenotation(denot21, denot22) => - denot2.derivedMultiDenotation((this | denot21)(pre), (this | denot22)(pre)) + 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) + unionDenot(denot1, denot2) case _ => throwError } @@ -506,7 +582,7 @@ object Denotations { // ------ PreDenotation ops ---------------------------------------------- final def first = this - final def toDenot(implicit ctx: Context) = this + final def toDenot(pre: Type)(implicit ctx: Context) = this final def containsSig(sig: Signature)(implicit ctx: Context) = exists && signature == sig final def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): SingleDenotation = @@ -573,7 +649,7 @@ object Denotations { def first: Denotation /** Convert to full denotation by &-ing all elements */ - def toDenot(implicit ctx: Context): Denotation + def toDenot(pre: Type)(implicit ctx: Context): Denotation /** Group contains a denotation with given signature */ def containsSig(sig: Signature)(implicit ctx: Context): Boolean @@ -604,7 +680,7 @@ object Denotations { assert(denots1.exists && denots2.exists) def exists = true def first = denots1.first - def toDenot(implicit ctx: Context) = denots1.toDenot & denots2.toDenot + def toDenot(pre: Type)(implicit ctx: Context) = (denots1 toDenot pre) & (denots2 toDenot pre, pre) def containsSig(sig: Signature)(implicit ctx: Context) = (denots1 containsSig sig) || (denots2 containsSig sig) def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): PreDenotation = diff --git a/src/dotty/tools/dotc/core/Flags.scala b/src/dotty/tools/dotc/core/Flags.scala index 6e4777749..9f4cce728 100644 --- a/src/dotty/tools/dotc/core/Flags.scala +++ b/src/dotty/tools/dotc/core/Flags.scala @@ -274,11 +274,12 @@ object Flags { final val Label = termFlag(22, "<label>") /** Labeled with `abstract` modifier (an abstract class) + * Note: You should never see Abstract on any symbol except a class. * Note: the flag counts as common, because it can be combined with OVERRIDE in a term. */ final val Abstract = commonFlag(23, "abstract") - /** Labeled with of abstract & override */ + /** Labeled with of abstract & override (needed?) */ final val AbsOverride = termFlag(24, "abstract override") /** Method is assumed to be stable */ @@ -376,7 +377,7 @@ object Flags { Erroneous assert(FromStartFlags.isTermFlags && FromStartFlags.isTypeFlags) - // TODO: Should check that FromStartFlags do not changed in completion + // TODO: Should check that FromStartFlags do not change in completion /** A value that's unstable unless complemented with a Stable flag */ final val UnstableValue = Mutable | Method diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 3026562a3..95798d701 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -874,7 +874,7 @@ object SymDenotations { } else NoDenotation override final def findMember(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Denotation = - membersNamed(name).filterExcluded(excluded).asSeenFrom(pre).toDenot + membersNamed(name).filterExcluded(excluded).asSeenFrom(pre).toDenot(pre) private[this] var baseTypeCache: java.util.HashMap[CachedType, Type] = null private[this] var baseTypeValid: RunId = NoRunId diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 1a1789eeb..851eb1301 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -295,7 +295,7 @@ object Types { */ final def findDecl(name: Name, excluded: FlagSet)(implicit ctx: Context): Denotation = this match { case tp: ClassInfo => - tp.decls.denotsNamed(name).filterExcluded(excluded).toDenot + tp.decls.denotsNamed(name).filterExcluded(excluded).toDenot(NoPrefix) case tp: TypeProxy => tp.underlying.findDecl(name, excluded) } @@ -317,7 +317,7 @@ object Types { case tp: RefinedType => val pdenot = tp.parent.findMember(name, pre, excluded) if (name eq tp.refinedName) - pdenot & new JointRefDenotation(NoSymbol, tp.refinedInfo.substThis(tp, pre), Period.allInRun(ctx.runId)) + pdenot & (new JointRefDenotation(NoSymbol, tp.refinedInfo.substThis(tp, pre), Period.allInRun(ctx.runId)), pre) else pdenot case tp: ThisType => @@ -341,9 +341,9 @@ object Types { case tp: ClassInfo => tp.cls.findMember(name, pre, excluded) case AndType(l, r) => - l.findMember(name, pre, excluded) & r.findMember(name, pre, excluded) + l.findMember(name, pre, excluded) & (r.findMember(name, pre, excluded), pre) case OrType(l, r) => - (l.findMember(name, pre, excluded) | r.findMember(name, pre, excluded))(pre) + l.findMember(name, pre, excluded) | (r.findMember(name, pre, excluded), pre) case NoType => NoDenotation } /* !!! DEBUG ensuring { denot => @@ -1527,12 +1527,12 @@ object Types { if (optSelfType.exists) optSelfType else cls.typeConstructor def rebase(tp: Type)(implicit ctx: Context): Type = - if (prefix eq cls.owner.thisType) tp - else tp.substThis(cls, prefix) + if ((prefix eq cls.owner.thisType) || !cls.owner.isClass) tp + else tp.substThis(cls.owner.asClass, prefix) def typeConstructor(implicit ctx: Context): Type = if ((cls is PackageClass) || cls.owner.isTerm) TypeRef.withSym(prefix, cls) - else TypeRef(prefix, cls.name).withDenot(cls.denot.asSeenFrom(prefix)) + else TypeRef(prefix, cls.name).withDenot(cls.denot.asSeenFrom(prefix)) // this ??? // cached because baseType needs parents private var parentsCache: List[TypeRef] = null @@ -1584,6 +1584,7 @@ object Types { override def & (that: Type)(implicit ctx: Context) = that match { case that: TypeBounds => this & that + case that: ClassInfo => this & that.bounds } override def | (that: Type)(implicit ctx: Context) = that match { @@ -1733,6 +1734,9 @@ object Types { tp.derivedTypeBounds(this(lo), this(hi)) } + case tp @ ClassInfo(prefix, _, _, _, _) => + tp.derivedClassInfo(this(prefix)) + case tp @ AnnotatedType(annot, underlying) => tp.derivedAnnotatedType(mapOver(annot), this(underlying)) diff --git a/src/dotty/tools/dotc/printing/PlainPrinter.scala b/src/dotty/tools/dotc/printing/PlainPrinter.scala index 0ada9eac5..5766dd2ec 100644 --- a/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -216,7 +216,9 @@ class PlainPrinter(_ctx: Context) extends Printer { val parentsText = Text(cparents.map(p => toTextLocal(reconstituteParent(cls, p))), " with ") val trueDecls = otherDecls.filterNot(treatAsTypeArg) - val declsText = if (trueDecls.isEmpty) Text() else dclsText(trueDecls) + val declsText = + if (trueDecls.isEmpty || !ctx.settings.debug.value) Text() + else dclsText(trueDecls) tparamsText ~ " extends " ~ parentsText ~ "{" ~ selfText ~ declsText ~ "} at " ~ preText case _ => diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 47ffa40ce..4861b3949 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -158,7 +158,8 @@ class Typer extends Namer { if (curOwner.isClass && (curOwner ne outer.owner)) curOwner.asClass.membersNamed(name) else curScope.denotsNamed(name) if (defDenots.exists) { - val found = NamedType(curOwner.thisType, name).withDenot(defDenots.toDenot) + val pre = curOwner.thisType + val found = NamedType(pre, name).withDenot(defDenots toDenot pre) if (!(curOwner is Package) || isDefinedInCurrentUnit(defDenots)) return checkNewOrShadowed(found, definition) // no need to go further out, we found highest prec entry else if (prevPrec < packageClause) |