aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala6
-rw-r--r--src/dotty/tools/dotc/core/Names.scala7
-rw-r--r--src/dotty/tools/dotc/core/Periods.scala5
-rw-r--r--src/dotty/tools/dotc/core/Types.scala28
4 files changed, 27 insertions, 19 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index f9c4fde8f..77ae86fd6 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -331,7 +331,9 @@ object Denotations {
// --------------- DenotationSets -------------------------------------------------
- /** A DenotationSet represents a set of denotation */
+ /** A DenotationSet represents a set of single denotations
+ * It is used as an optimization to avoid forming MultiDenotations too eagerly.
+ */
trait DenotationSet {
def exists: Boolean
def toDenot(implicit ctx: Context): Denotation
@@ -348,7 +350,7 @@ object Denotations {
}
case class DenotUnion(denots1: DenotationSet, denots2: DenotationSet) extends DenotationSet {
- assert(denots1.exists && !denots2.exists)
+ assert(denots1.exists && denots2.exists)
private def derivedUnion(s1: DenotationSet, s2: DenotationSet) =
if (!s1.exists) s2
else if (!s2.exists) s1
diff --git a/src/dotty/tools/dotc/core/Names.scala b/src/dotty/tools/dotc/core/Names.scala
index 78d9beede..30d80a938 100644
--- a/src/dotty/tools/dotc/core/Names.scala
+++ b/src/dotty/tools/dotc/core/Names.scala
@@ -16,7 +16,7 @@ object Names {
* 3. Names are intended to be encoded strings. @see dotc.util.NameTransformer.
* The encoding will be applied when converting a string to a name.
*/
- abstract class Name {
+ abstract class Name extends DotClass {
/** The basis in which this name is stored */
val basis: NameTable
@@ -59,7 +59,7 @@ object Names {
* to other entities (e.g. strings).
* One always should use the ==(Name) method instead.
*/
- final override def equals(that: Any): Boolean = ??? // do not implement
+ final override def equals(that: Any): Boolean = unsupported("equals")
/** The only authorized == method on names */
def == (that: Name): Boolean = (
@@ -84,9 +84,6 @@ object Names {
/** Convert to string replacing operator symbols by corresponding \$op_name. */
def decode: String = NameTransformer.decode(toString)
-
- /** The last phase id where symbols with this name can be created. */
- def lastIntroPhaseId: PhaseId = ???
}
class TermName(val basis: NameTable, val start: Int, val length: Int, val next: TermName) extends Name {
diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala
index ed7156d7b..97384e509 100644
--- a/src/dotty/tools/dotc/core/Periods.scala
+++ b/src/dotty/tools/dotc/core/Periods.scala
@@ -23,13 +23,16 @@ abstract class Periods { self: Context =>
override val period = pd
}
+ /** A new context that differs from the current one in its phase */
+ def withPhase(pid: PhaseId): Context = withPeriod(Period(runId, pid))
+
/** Execute `op` at given period */
def atPeriod[T](pd: Period)(op: Context => T) =
op(ctx withPeriod pd)
/** Execute `op` at given phase id */
def atPhase[T](pid: PhaseId)(op: Context => T) =
- op(ctx withPeriod Period(runId, pid))
+ op(ctx withPhase pid)
}
object Periods {
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 61e7fa26c..460265e3d 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -300,11 +300,11 @@ object Types {
case tp: ClassInfo =>
val classd = tp.classd
val candidates = classd.membersNamed(name)
- val resultSyms = candidates
+ val results = candidates
.filterAccessibleFrom(pre)
.filterExcluded(excluded)
.asSeenFrom(pre, classd.symbol)
- if (resultSyms.exists) resultSyms.toDenot
+ if (results.exists) results.toDenot
else new ErrorDenotation // todo: refine
case tp: AndType =>
tp.tp1.findMember(name, pre, excluded) & tp.tp2.findMember(name, pre, excluded)
@@ -573,18 +573,24 @@ object Types {
if (!(validPeriods contains ctx.period)) {
val thisPeriod = ctx.period
lastDenotation =
- if (validPeriods.runId == thisPeriod.runId)
+ if (validPeriods.runId == thisPeriod.runId) {
lastDenotation.current
- else if (thisPeriod.phaseId > name.lastIntroPhaseId)
- ctx.atPhase(name.lastIntroPhaseId)(prefix.member(name)(_)).current
- else
- prefix.member(name)
- if (checkPrefix(lastDenotation.symbol) && !prefix.isLegalPrefix)
- throw new MalformedType(prefix, lastDenotation.symbol)
+ } else {
+ val d = loadDenot
+ if (d.exists || ctx.phaseId == FirstPhaseId) {
+ if (checkPrefix(d.symbol) && !prefix.isLegalPrefix)
+ throw new MalformedType(prefix, d.symbol)
+ d
+ } else {// name has changed; try load in earlier phase and make current
+ denot(ctx.withPhase(ctx.phaseId - 1)).current
+ }
+ }
}
lastDenotation
}
+ protected def loadDenot(implicit ctx: Context) = prefix.member(name)
+
def isType = name.isTypeName
def isTerm = name.isTermName
@@ -619,8 +625,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 denot(implicit ctx: Context): Denotation =
- super.denot.atSignature(signature)
+ override def loadDenot(implicit ctx: Context): Denotation =
+ super.loadDenot.atSignature(signature)
}
final class TypeRefNoPrefix(val fixedSym: TypeSymbol)(implicit ctx: Context)