aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-01-21 14:24:32 +0100
committerMartin Odersky <odersky@gmail.com>2013-01-21 14:24:32 +0100
commit4822da28b769484f9dac3ec83d437149e0559a48 (patch)
treec3cb89f91f786a375a8ee2c4308a541d8b05be81 /src/dotty/tools/dotc
parente59b8822f53fa6fad057ac9642d31e4026800bf5 (diff)
downloaddotty-4822da28b769484f9dac3ec83d437149e0559a48.tar.gz
dotty-4822da28b769484f9dac3ec83d437149e0559a48.tar.bz2
dotty-4822da28b769484f9dac3ec83d437149e0559a48.zip
Changed NamedType dereferencing so that we need not keep track of name validity periods. Instead, we simply retry on missing member lookup in an earlier phase. This scheme is less complicated and works as long as names that are renamed in phase A are not re-used in a phase B >= A.
Diffstat (limited to 'src/dotty/tools/dotc')
-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)