aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-01-13 13:33:09 +0100
committerMartin Odersky <odersky@gmail.com>2013-01-13 13:33:09 +0100
commit103a34e256c21d84b3e6b772de999ab804aeb1f3 (patch)
tree12fa00445213220e63956bf711b4c86d9ef08094 /src/dotty/tools/dotc/core
parent1cf21aa86dfd419460ccb8de9c4abb05400fce72 (diff)
downloaddotty-103a34e256c21d84b3e6b772de999ab804aeb1f3.tar.gz
dotty-103a34e256c21d84b3e6b772de999ab804aeb1f3.tar.bz2
dotty-103a34e256c21d84b3e6b772de999ab804aeb1f3.zip
Made Period a value class.
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala3
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala8
-rw-r--r--src/dotty/tools/dotc/core/Periods.scala107
-rw-r--r--src/dotty/tools/dotc/core/References.scala15
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala24
-rw-r--r--src/dotty/tools/dotc/core/Types.scala39
6 files changed, 109 insertions, 87 deletions
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 06f828131..cc60bbf54 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -24,7 +24,6 @@ object Contexts {
def subTyper: SubTyper
def names: NameTable
def phase: Phase = ???
- def stableInterval: Interval = ???
def erasedTypes: Boolean = ???
}
@@ -45,7 +44,7 @@ object Contexts {
def subTyper: SubTyper = ???
val root: RootContext = this
- val period = periodOf(NoRunId, NoPhaseId)
+ val period = Nowhere
val names: NameTable = new NameTable
val variance = 1
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 625189a9d..0882a9343 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -12,7 +12,7 @@ object Denotations {
abstract class Denotation {
/** The validity interval of this symbol */
- var valid: Interval = Nowhere
+ var validFor: Period = Nowhere
/** The next instance of this symbol in the same run */
private[core] var nextInRun: Denotation = this
@@ -22,9 +22,9 @@ object Denotations {
* of this run
*/
def initial: Denotation = {
- var sym = nextInRun
- while (sym.valid > this.valid) sym = sym.nextInRun
- sym
+ var d = nextInRun
+ while (d.validFor.code > this.validFor.code) d = d.nextInRun
+ d
}
def owner: Symbol = ???
diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala
index c22cf3ac1..ed7156d7b 100644
--- a/src/dotty/tools/dotc/core/Periods.scala
+++ b/src/dotty/tools/dotc/core/Periods.scala
@@ -11,10 +11,10 @@ abstract class Periods { self: Context =>
import Periods._
/** The current phase identifier */
- def phaseId = phaseIdOf(period)
+ def phaseId = period.phaseId
/** The current run identifier */
- def runId = runIdOf(period)
+ def runId = period.runId
/** A new context that differs from the current one in its period */
def withPeriod(pd: Period): Context =
@@ -29,12 +29,12 @@ abstract class Periods { self: Context =>
/** Execute `op` at given phase id */
def atPhase[T](pid: PhaseId)(op: Context => T) =
- op(ctx withPeriod periodOf(period, pid))
+ op(ctx withPeriod Period(runId, pid))
}
object Periods {
- /** A period is an ordinal number for a phase in a run.
+ /** A period is represented by an ordinal number for a phase in a run.
* Phases in later runs have higher periods than phases in earlier runs.
* Later phases have higher periods than earlier phases in the same run.
* Periods are coded (in big endian) as:
@@ -43,11 +43,8 @@ object Periods {
* runid 21 bits
* phase id: 5 bits
* unused: 5 bits
- */
- type Period = Int
- final val NoPeriod = 0
-
- /** A period interval is an interval between two periods that share the same runid.
+ *
+ * A period interval is an interval between two periods that share the same runid.
* It is coded as follows:
*
* sign, always 0 1 bit
@@ -55,51 +52,77 @@ object Periods {
* last phase id: 5 bits
* #phases before last: 5 bits
*/
- type Interval = Int
- final val Nowhere = NoPeriod
+ class Period(val code: Int) extends AnyVal {
- /** An ordinal number for compiler runs. First run has number 1. */
- type RunId = Int
- final val NoRunId = 0
+ /** The run identifier of this period. */
+ def runId: Int = code >>> (PhaseWidth * 2)
- /** An ordinal number for phases. First phase has number 1. */
- type PhaseId = Int
- final val NoPhaseId = 0
- final val FirstPhaseId = 1
+ /** The phase identifier of this single-phase period. */
+ def phaseId: Int = {
+ assert((code & PhaseMask) == 0)
+ (code >>> PhaseWidth) & PhaseMask
+ }
- /** The number of bits needed to encode a phase identifier. */
- final val PhaseWidth = 5
- final val PhaseMask = (1 << PhaseWidth) - 1
+ /** The last phase of this period */
+ def lastPhaseId: Int =
+ (code >>> PhaseWidth) & PhaseMask
- /** The run identifier of the given period. */
- final def runIdOf(period: Period): RunId = period >>> (PhaseWidth * 2)
+ /** The first phase of this period */
+ def firstPhaseId = lastPhaseId - (code & PhaseMask)
- /** The phase identifier of the given period. */
- final def phaseIdOf(period: Period): PhaseId = (period >>> PhaseWidth) & PhaseMask
+ /** Does this period contain given period?
+ * this = A .. B
+ */
+ def contains(that: Period): Boolean = {
+ val lastDiff = (code - that.code) >>> PhaseWidth
+ lastDiff + (that.code & PhaseMask ) <= (this.code & PhaseMask)
+ }
+
+ /** Does this period overlpa with given period? */
+ def overlaps(that: Period): Boolean =
+ this.runId == that.runId &&
+ this.firstPhaseId <= that.lastPhaseId &&
+ that.firstPhaseId <= this.lastPhaseId
+
+ def & (that: Period): Period =
+ if (this overlaps that)
+ Period(
+ this.runId,
+ this.firstPhaseId max that.firstPhaseId,
+ this.lastPhaseId min that.lastPhaseId)
+ else
+ Nowhere
+ }
+
+ object Period {
- /** The last phase of the given interval */
- final def lastPhaseIdOf(ivl: Interval) = phaseIdOf(ivl)
+ /** The single-phase period consisting of given run id and phase id */
+ def apply(rid: RunId, pid: PhaseId): Period =
+ new Period(((rid << PhaseWidth) | pid) << PhaseWidth)
- /** The first phase of the given interval */
- final def firstPhaseIdOf(ivl: Interval) = lastPhaseIdOf(ivl) - (ivl & PhaseMask)
+ /** The period consisting of given run id, and lo/hi phase ids */
+ def apply(rid: RunId, loPid: PhaseId, hiPid: PhaseId): Period =
+ new Period(((rid << PhaseWidth) | hiPid) << PhaseWidth | (hiPid - loPid))
- /** Does given interval contain given period */
- final def containsPeriod(ivl: Interval, period: Period): Boolean =
- ((ivl - period) >>> PhaseWidth) <= (ivl & PhaseMask)
+ /** The interval consisting of all periods of given run id */
+ def allInRun(rid: RunId) =
+ apply(rid, 0, PhaseMask)
- final def intervalsOverlap(ivl1: Interval, ivl2: Interval): Boolean = ???
+ }
- final def intersection(ivl1: Interval, ivl2: Interval): Interval = ???
+ final val Nowhere = new Period(0)
- /** The period consisting of given run id and phase id */
- final def periodOf(rid: RunId, pid: PhaseId): Period =
- ((rid << PhaseWidth) | pid) << PhaseWidth
+ /** An ordinal number for compiler runs. First run has number 1. */
+ type RunId = Int
+ final val NoRunId = 0
- /** The interval consisting of given run id, and lo/hi phase ids */
- final def intervalOf(rid: RunId, loPid: PhaseId, hiPid: PhaseId): Interval =
- periodOf(rid, hiPid) | (hiPid - loPid)
+ /** An ordinal number for phases. First phase has number 1. */
+ type PhaseId = Int
+ final val NoPhaseId = 0
+ final val FirstPhaseId = 1
- /** The interval consisting of all periods of given run id */
- def allPeriods(rid: RunId): Interval = intervalOf(rid, 0, PhaseMask)
+ /** The number of bits needed to encode a phase identifier. */
+ final val PhaseWidth = 5
+ final val PhaseMask = (1 << PhaseWidth) - 1
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/References.scala b/src/dotty/tools/dotc/core/References.scala
index 50c322614..bd640ed1d 100644
--- a/src/dotty/tools/dotc/core/References.scala
+++ b/src/dotty/tools/dotc/core/References.scala
@@ -5,7 +5,6 @@ import Denotations.Denotation
import Contexts.Context
import Names.Name
import Names.TypeName
-import Periods.containsPeriod
import Symbols.NoSymbol
import Symbols.Symbol
import Types._, Periods._, Flags._
@@ -73,7 +72,7 @@ object References {
def info: Type
/** The interval during which this reference is valid */
- def validFor: Interval
+ def validFor: Period
/** Is this a reference to a type symbol? */
def isType: Boolean = false
@@ -131,7 +130,7 @@ object References {
else new JointSymRef(
if (sym2Eligible) sym2 else sym1,
bounds1 & bounds2,
- intersection(ref1.validFor, ref2.validFor))
+ ref1.validFor & ref2.validFor)
} else NoRef
}
@@ -162,7 +161,7 @@ object References {
else new JointSymRef(
lubSym(ref1.symbol, ref2.symbol),
ref1.info | ref2.info,
- intersection(ref1.validFor, ref2.validFor))
+ ref1.validFor & ref2.validFor)
case _ =>
throwError
}
@@ -184,7 +183,7 @@ object References {
def signature = unsupported("signature")
def atSignature(sig: Signature): Reference =
ref1.atSignature(sig) orElse ref2.atSignature(sig)
- def validFor = intersection(ref1.validFor, ref2.validFor)
+ def validFor = ref1.validFor & ref2.validFor
}
abstract case class SymRef(override val symbol: Symbol,
@@ -229,16 +228,16 @@ object References {
}
class UniqueSymRef(symbol: Symbol, info: Type)(implicit ctx: Context) extends SymRef(symbol, info) {
- val validFor = symbol.deref.valid
+ val validFor = symbol.deref.validFor
override protected def copy(s: Symbol, i: Type): SymRef = new UniqueSymRef(s, i)
}
- class JointSymRef(symbol: Symbol, info: Type, override val validFor: Interval)(implicit ctx: Context) extends SymRef(symbol, info) {
+ class JointSymRef(symbol: Symbol, info: Type, override val validFor: Period)(implicit ctx: Context) extends SymRef(symbol, info) {
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 = allPeriods(ctx.runId)
+ def validFor = Period.allInRun(ctx.runId)
}
object NoRef extends SymRef(NoSymbol, NoType) {
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index 3d98c8236..8ce7bfa64 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -70,7 +70,7 @@ object Symbols {
*/
def deref(implicit ctx: Context): Denotation = {
val denot = lastDenot
- if (denot != null && containsPeriod(denot.valid, ctx.period))
+ if (denot != null && (denot.validFor contains ctx.period))
denot
else
trackedDenot
@@ -83,40 +83,40 @@ object Symbols {
denot = loadDenot
} else {
val currentPeriod = ctx.period
- val valid = denot.valid
- val currentRunId = runIdOf(currentPeriod)
- val validRunId = runIdOf(valid)
+ val valid = denot.validFor
+ val currentRunId = currentPeriod.runId
+ val validRunId = valid.runId
if (currentRunId != validRunId) {
reloadDenot
- } else if (currentPeriod > valid) {
+ } else if (currentPeriod.code > valid.code) {
// search for containing interval as long as nextInRun
// increases.
var nextDenot = denot.nextInRun
- while (nextDenot.valid > valid && !containsPeriod(nextDenot.valid, currentPeriod)) {
+ while (nextDenot.validFor.code > valid.code && !(nextDenot.validFor contains currentPeriod)) {
denot = nextDenot
nextDenot = nextDenot.nextInRun
}
- if (nextDenot.valid > valid) {
+ 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 = lastPhaseIdOf(denot.valid) + 1
+ 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 = firstPhaseIdOf(denot.valid)
+ startPid = denot.validFor.firstPhaseId
else {
denot.nextInRun = nextDenot
denot = nextDenot
}
- denot.valid = intervalOf(currentRunId, startPid, endPid)
+ denot.validFor = Period(currentRunId, startPid, endPid)
}
} else {
// currentPeriod < valid; in this case a denotation must exist
do {
denot = denot.nextInRun
- } while (!containsPeriod(denot.valid, currentPeriod))
+ } while (!(denot.validFor contains currentPeriod))
}
}
denot
@@ -136,7 +136,7 @@ object Symbols {
if (newSym eq this) { // no change, change validity
var d = initDenot
do {
- d.valid = intervalOf(ctx.runId, firstPhaseIdOf(d.valid), lastPhaseIdOf(d.valid))
+ d.validFor = Period(ctx.runId, d.validFor.firstPhaseId, d.validFor.lastPhaseId)
d = d.nextInRun
} while (d ne initDenot)
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 2a24e75d0..98f63a5b0 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -515,37 +515,38 @@ object Types {
val prefix: Type
val name: Name
- private[this] var referencedVar: Reference = null
+ private[this] var referenceVar: Reference = null
private def checkPrefix(sym: Symbol) =
sym.isAbstractType || sym.isClass
- def referenced(implicit ctx: Context): Reference = {
+ /** The reference currently denoted by this type */
+ def reference(implicit ctx: Context): Reference = {
val validPeriods =
- if (referencedVar != null) referencedVar.validFor else Nowhere
- if (!containsPeriod(validPeriods, ctx.period)) {
+ if (referenceVar != null) referenceVar.validFor else Nowhere
+ if (!(validPeriods contains ctx.period)) {
val thisPeriod = ctx.period
- referencedVar =
- if (runIdOf(validPeriods) == runIdOf(thisPeriod))
- referencedVar.atPhase(phaseIdOf(ctx.period))
- //val ref @ SymRef(clazz: ClassSymbol, _) = referencedVar
+ referenceVar =
+ if (validPeriods.runId == thisPeriod.runId)
+ referenceVar.atPhase(ctx.period.phaseId)
+ //val ref @ SymRef(clazz: ClassSymbol, _) = referenceVar
//ref.derivedSymRef(clazz, ClassInfo(prefix, clazz.deref))
- else if (phaseIdOf(thisPeriod) > name.lastIntroPhaseId)
+ else if (thisPeriod.phaseId > name.lastIntroPhaseId)
ctx.atPhase(name.lastIntroPhaseId)(prefix.member(name)(_))
- .atPhase(phaseIdOf(thisPeriod))
+ .atPhase(thisPeriod.phaseId)
else
prefix.member(name)
- if (checkPrefix(referencedVar.symbol) && !prefix.isLegalPrefix)
- throw new MalformedType(prefix, referencedVar.symbol)
+ if (checkPrefix(referenceVar.symbol) && !prefix.isLegalPrefix)
+ throw new MalformedType(prefix, referenceVar.symbol)
}
- referencedVar
+ referenceVar
}
def isType = name.isTypeName
def isTerm = name.isTermName
- def symbol(implicit ctx: Context): Symbol = referenced.symbol
- def info(implicit ctx: Context): Type = referenced.info
+ def symbol(implicit ctx: Context): Symbol = reference.symbol
+ def info(implicit ctx: Context): Type = reference.info
override def underlying(implicit ctx: Context): Type = info
@@ -566,7 +567,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 referenced(implicit ctx: Context): Reference = new UniqueSymRef(fixedSym, info)
+ override def reference(implicit ctx: Context): Reference = new UniqueSymRef(fixedSym, info)
}
final class TermRefNoPrefix(val fixedSym: TermSymbol)(implicit ctx: Context)
@@ -575,8 +576,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 referenced(implicit ctx: Context): Reference =
- super.referenced.atSignature(signature)
+ override def reference(implicit ctx: Context): Reference =
+ super.reference.atSignature(signature)
}
final class TypeRefNoPrefix(val fixedSym: TypeSymbol)(implicit ctx: Context)
@@ -693,7 +694,7 @@ object Types {
var ref: Reference = NoRef
while (ns.nonEmpty && (ref eq NoRef)) {
if (ns.head == name)
- ref = new JointSymRef(NoSymbol, is.head.substThis(this, pre), allPeriods(ctx.runId))
+ ref = new JointSymRef(NoSymbol, is.head.substThis(this, pre), Period.allInRun(ctx.runId))
ns = ns.tail
is = is.tail
}