aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-01-17 09:54:05 +0100
committerMartin Odersky <odersky@gmail.com>2013-01-17 09:54:05 +0100
commitb43de54be5c4d91762d8dc6a4ce7b612935639f9 (patch)
tree50b1e5f8593748d429f2505676a8854fd7a62c42 /src/dotty
parentdc2d3c7a138a30e74836928e0ad8872cdf8a00ab (diff)
downloaddotty-b43de54be5c4d91762d8dc6a4ce7b612935639f9.tar.gz
dotty-b43de54be5c4d91762d8dc6a4ce7b612935639f9.tar.bz2
dotty-b43de54be5c4d91762d8dc6a4ce7b612935639f9.zip
Completed period-tracking in named types. Made Denotation a subtype of symblic referenced and generalized denotation versioning to referenced versioning.
Diffstat (limited to 'src/dotty')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala25
-rw-r--r--src/dotty/tools/dotc/core/References.scala135
-rw-r--r--src/dotty/tools/dotc/core/Scopes.scala2
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala66
-rw-r--r--src/dotty/tools/dotc/core/Types.scala9
5 files changed, 124 insertions, 113 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 0882a9343..8aae7d644 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -2,30 +2,16 @@ package dotty.tools.dotc
package core
import Periods._, Contexts._, Symbols._, References._, Names._
-import Types._, Flags._, Decorators._
+import Types._, Flags._, Decorators._, Transformers._
import Scopes.Scope
import collection.mutable
import collection.immutable.BitSet
object Denotations {
- abstract class Denotation {
+ abstract class Denotation extends SymRef {
- /** The validity interval of this symbol */
- var validFor: Period = Nowhere
-
- /** The next instance of this symbol in the same run */
- private[core] var nextInRun: Denotation = this
-
- /**
- * The version of this symbol that was valid in the first phase
- * of this run
- */
- def initial: Denotation = {
- var d = nextInRun
- while (d.validFor.code > this.validFor.code) d = d.nextInRun
- d
- }
+ def symbol: Symbol = ???
def owner: Symbol = ???
@@ -57,9 +43,6 @@ object Denotations {
* interval starting in FirstPhaseId.
*/
- /** is this symbol a type? */
- def isType: Boolean = false
-
/** is this symbol a class? */
def isClass: Boolean = false
@@ -70,6 +53,8 @@ object Denotations {
def isError: Boolean = false
def withType(tp: Type): Denotation = ???
+
+ override protected def copy(s: Symbol, i: Type): SymRef = new UniqueSymRef(s, i, validFor)
}
object NameFilter {
diff --git a/src/dotty/tools/dotc/core/References.scala b/src/dotty/tools/dotc/core/References.scala
index bd640ed1d..d102edc77 100644
--- a/src/dotty/tools/dotc/core/References.scala
+++ b/src/dotty/tools/dotc/core/References.scala
@@ -7,18 +7,18 @@ import Names.Name
import Names.TypeName
import Symbols.NoSymbol
import Symbols.Symbol
-import Types._, Periods._, Flags._
+import Types._, Periods._, Flags._, Transformers._
-/** Classes that implement references and sets of references
+/** Classes that implement referenced items and sets of them
*/
object References {
- /** The signature of a reference.
- * Overloaded references with the same name are distinguished by
+ /** 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
- * reference. For instance a reference to the definition
+ * referenced. For instance a referenced definition
*
* def f(x: Int)(y: List[String]): String
*
@@ -33,24 +33,24 @@ object References {
*/
val NullSignature = List(Names.EmptyTypeName)
- /** A reference is the result of resolving a name (either simple identifier or select)
- * during a given period interval.
+ /** A referenced is the result of resolving
+ * a name (either simple identifier or select) during a given period.
*
- * Reference has two subclasses: OverloadedRef and SymRef.
+ * Referenced has two subclasses: OverloadedRefd and SymRefd.
*
- * A SymRef refers to a `symbol` and a type (`info`) that the symbol has
- * when referred through this reference.
+ * A SymRefd refers to a `symbol` and a type (`info`) that the symbol has
+ * when seen from the reference.
*
- * References (`SymRef`s) can be combined with `&` and `|`.
+ * References 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`.
+ * an empty reference `NoRefd`.
*
- * A reference might refer to `NoSymbol`. This is the case if the reference
- * was produced from a disjunction of two references with different symbols
+ * 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:
*
@@ -61,7 +61,7 @@ object References {
* val x: A | B = if (???) new A else new B
* val y = x.f
*
- * Then the reference of `y` is `SymRef(NoSymbol, A | B)`.
+ * Then the referenced of `y` is `SymRef(NoSymbol, A | B)`.
*/
abstract class Reference extends DotClass {
@@ -74,6 +74,9 @@ object References {
/** The interval during which this reference is valid */
def validFor: Period
+ /** The previous reference */
+ def prev: Reference = ???
+
/** Is this a reference to a type symbol? */
def isType: Boolean = false
@@ -83,10 +86,8 @@ object References {
/** Resolve overloaded reference to pick the one with the given signature */
def atSignature(sig: Signature): Reference
- /** This reference at given phase */
- def atPhase(pid: PhaseId)(implicit ctx: Context): Reference = {
- ???
- }
+ /** The variant of this reference that's current in the given context. */
+ def current(implicit ctx: Context): Reference
def exists: Boolean = true
@@ -98,7 +99,7 @@ object References {
else if (!this.exists) that
else if (!that.exists) this
else that match {
- case that @ SymRef(sym2, info2) =>
+ case that: SymRef =>
val r = mergeRef(this, that)
if (r ne NoRef) r else OverloadedRef(this, that)
case that @ OverloadedRef(ref1, ref2) =>
@@ -112,15 +113,18 @@ object References {
case ref1 @ OverloadedRef(ref11, ref12) =>
val r1 = mergeRef(ref11, ref2)
if (r1 ne NoRef) r1 else mergeRef(ref12, ref2)
- case ref1 @ SymRef(sym1, info1) =>
+ case ref1: SymRef =>
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 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)
@@ -184,10 +188,12 @@ object References {
def atSignature(sig: Signature): Reference =
ref1.atSignature(sig) orElse ref2.atSignature(sig)
def validFor = ref1.validFor & ref2.validFor
+ def current(implicit ctx: Context): Reference =
+ derivedOverloadedRef(ref1.current, ref2.current)
}
- abstract case class SymRef(override val symbol: Symbol,
- override val info: Type) extends Reference with RefSet {
+ abstract class SymRef extends Reference with RefSet {
+
override def isType = symbol.isType
override def signature: Signature = {
def sig(tp: Type): Signature = tp match {
@@ -210,6 +216,62 @@ object References {
def atSignature(sig: Signature): Reference =
if (sig == signature) this else NoRef
+ // ------ Transformations -----------------------------------------
+
+ var validFor: Period = Nowhere
+
+ /** The next SymRef in this run, with wrap-around from last to first. */
+ var nextInRun: SymRef = this
+
+ /** The version of this SymRef that was valid in the first phase
+ * of this run.
+ */
+ def initial: SymRef = {
+ var current = nextInRun
+ while (current.validFor.code > this.validFor.code) current = current.nextInRun
+ current
+ }
+
+ def current(implicit ctx: Context): SymRef = {
+ 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]
+
// ------ RefSet ops ----------------------------------------------
def toRef(implicit ctx: Context) = this
@@ -227,21 +289,30 @@ object References {
derivedSymRef(symbol, info.asSeenFrom(pre, owner))
}
- class UniqueSymRef(symbol: Symbol, info: Type)(implicit ctx: Context) extends SymRef(symbol, info) {
- val validFor = symbol.deref.validFor
- override protected def copy(s: Symbol, i: Type): SymRef = new UniqueSymRef(s, i)
+ class UniqueSymRef(val symbol: Symbol,
+ val info: Type,
+ initValidFor: Period) extends SymRef {
+ validFor = initValidFor
+ override protected def copy(s: Symbol, i: Type): SymRef = new UniqueSymRef(s, i, validFor)
}
- class JointSymRef(symbol: Symbol, info: Type, override val validFor: Period)(implicit ctx: Context) extends SymRef(symbol, info) {
+ class JointSymRef(val symbol: Symbol,
+ val info: Type,
+ initValidFor: Period) extends SymRef {
+ validFor = initValidFor
override protected def copy(s: Symbol, i: Type): SymRef = new JointSymRef(s, i, validFor)
}
- class ErrorRef(implicit ctx: Context) extends SymRef(NoSymbol, NoType) {
- def validFor = Period.allInRun(ctx.runId)
+ class ErrorRef(implicit ctx: Context) extends SymRef {
+ val symbol = NoSymbol
+ val info = NoType
+ validFor = Period.allInRun(ctx.runId)
}
- object NoRef extends SymRef(NoSymbol, NoType) {
- def validFor = Nowhere
+ object NoRef extends SymRef {
+ val symbol = NoSymbol
+ val info = NoType
+ validFor = Nowhere
override def exists = false
}
diff --git a/src/dotty/tools/dotc/core/Scopes.scala b/src/dotty/tools/dotc/core/Scopes.scala
index e3d3c29ce..7a827ccf1 100644
--- a/src/dotty/tools/dotc/core/Scopes.scala
+++ b/src/dotty/tools/dotc/core/Scopes.scala
@@ -199,7 +199,7 @@ object Scopes {
var syms: RefSet = NoRef
var e = lookupEntry(name)
while (e != null) {
- syms = syms union e.sym.thisRef
+ syms = syms union e.sym.deref
e = lookupNextEntry(e)
}
syms
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index 8ce7bfa64..3f14fd37b 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -2,7 +2,7 @@ package dotty.tools.dotc
package core
import Periods._
-import DenotationTransformers._
+import Transformers._
import Names._
import Flags._
import java.lang.AssertionError
@@ -11,7 +11,7 @@ import Symbols._
import Contexts._
import Denotations._
import Types._
-import References.{Reference, SymRef, UniqueSymRef, OverloadedRef}
+import References.{Reference, SymRef, OverloadedRef}
import collection.mutable
object Symbols {
@@ -70,74 +70,32 @@ object Symbols {
*/
def deref(implicit ctx: Context): Denotation = {
val denot = lastDenot
- if (denot != null && (denot.validFor contains ctx.period))
- denot
- else
- trackedDenot
- }
-
- /** Get referenced denotation if lastDenot points to a different instance */
- private def trackedDenot(implicit ctx: Context): Denotation = {
- var denot = lastDenot
- if (denot == null) {
- denot = loadDenot
- } else {
+ if (denot == null) loadDenot
+ else {
val currentPeriod = ctx.period
val valid = denot.validFor
- val currentRunId = currentPeriod.runId
- val validRunId = valid.runId
- if (currentRunId != validRunId) {
- reloadDenot
- } else if (currentPeriod.code > valid.code) {
- // search for containing interval as long as nextInRun
- // increases.
- var nextDenot = denot.nextInRun
- while (nextDenot.validFor.code > valid.code && !(nextDenot.validFor contains currentPeriod)) {
- denot = nextDenot
- nextDenot = nextDenot.nextInRun
- }
- if (nextDenot.validFor.code > valid.code) {
- // in this case, containsPeriod(nextDenot.valid, currentPeriod)
- denot = nextDenot
- } else {
- // not found, denot points to highest existing variant
- var startPid = denot.validFor.lastPhaseId + 1
- val endPid = ctx.root.nextTransformer(startPid + 1).phaseId - 1
- nextDenot = ctx.root.nextTransformer(startPid) transform denot
- if (nextDenot eq denot)
- startPid = denot.validFor.firstPhaseId
- else {
- denot.nextInRun = nextDenot
- denot = nextDenot
- }
- denot.validFor = Period(currentRunId, startPid, endPid)
- }
- } else {
- // currentPeriod < valid; in this case a denotation must exist
- do {
- denot = denot.nextInRun
- } while (!(denot.validFor contains currentPeriod))
- }
+ if (valid contains currentPeriod) denot
+ else if (valid.runId != currentPeriod.runId) reloadDenot
+ else denot.current.asDenotation
}
- denot
}
/**
* Get loaded denotation if lastDenot points to a denotation from
- * a different run.
+ * a different run. !!! needed?
*/
private def reloadDenot(implicit ctx: Context): Denotation = {
- val initDenot = lastDenot.initial
+ val initDenot = lastDenot.initial.asDenotation
val newSym: Symbol =
ctx.atPhase(FirstPhaseId) { implicit ctx =>
initDenot.owner.info.decl(initDenot.name)
- .atSignature(thisRef.signature).symbol
+ .atSignature(deref.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
+ d = d.nextInRun.asDenotation
} while (d ne initDenot)
}
newSym.deref
@@ -146,8 +104,6 @@ object Symbols {
def isType: Boolean
def isTerm = !isType
- def thisRef(implicit ctx: Context): SymRef = new UniqueSymRef(this, info)
-
// forwarders for sym methods
def owner(implicit ctx: Context): Symbol = deref.owner
def name(implicit ctx: Context): Name = deref.name
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 98f63a5b0..3c5530bb0 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -528,13 +528,12 @@ object Types {
val thisPeriod = ctx.period
referenceVar =
if (validPeriods.runId == thisPeriod.runId)
- referenceVar.atPhase(ctx.period.phaseId)
+ referenceVar.current
//val ref @ SymRef(clazz: ClassSymbol, _) = referenceVar
//ref.derivedSymRef(clazz, ClassInfo(prefix, clazz.deref))
else if (thisPeriod.phaseId > name.lastIntroPhaseId)
- ctx.atPhase(name.lastIntroPhaseId)(prefix.member(name)(_))
- .atPhase(thisPeriod.phaseId)
- else
+ ctx.atPhase(name.lastIntroPhaseId)(prefix.member(name)(_)).current
+ else
prefix.member(name)
if (checkPrefix(referenceVar.symbol) && !prefix.isLegalPrefix)
throw new MalformedType(prefix, referenceVar.symbol)
@@ -567,7 +566,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 reference(implicit ctx: Context): Reference = new UniqueSymRef(fixedSym, info)
+ override def reference(implicit ctx: Context): Reference = fixedSym.deref
}
final class TermRefNoPrefix(val fixedSym: TermSymbol)(implicit ctx: Context)