diff options
author | Martin Odersky <odersky@gmail.com> | 2013-01-13 13:33:09 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-01-13 13:33:09 +0100 |
commit | 103a34e256c21d84b3e6b772de999ab804aeb1f3 (patch) | |
tree | 12fa00445213220e63956bf711b4c86d9ef08094 | |
parent | 1cf21aa86dfd419460ccb8de9c4abb05400fce72 (diff) | |
download | dotty-103a34e256c21d84b3e6b772de999ab804aeb1f3.tar.gz dotty-103a34e256c21d84b3e6b772de999ab804aeb1f3.tar.bz2 dotty-103a34e256c21d84b3e6b772de999ab804aeb1f3.zip |
Made Period a value class.
-rw-r--r-- | src/dotty/tools/dotc/core/Contexts.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Periods.scala | 107 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/References.scala | 15 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 24 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 39 |
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 } |