diff options
author | Martin Odersky <odersky@gmail.com> | 2015-05-07 15:15:54 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2015-05-08 13:33:52 +0200 |
commit | 6edf859c9dae24aa4232110244a8b1119b0c63e0 (patch) | |
tree | 46bae50dbc04cc79fb4a92900ff09e775a8b692c /src/dotty/tools/dotc/core/Denotations.scala | |
parent | 7972f3d6864429dad967b19d0673c403fb80d208 (diff) | |
download | dotty-6edf859c9dae24aa4232110244a8b1119b0c63e0.tar.gz dotty-6edf859c9dae24aa4232110244a8b1119b0c63e0.tar.bz2 dotty-6edf859c9dae24aa4232110244a8b1119b0c63e0.zip |
Reload denotations that are not defined at current phase
Up to now a NotDefinedHere exception was thrown if a denotation
was not defined at the current phase, but was defined elsewhere
in the current run. However, if the denotation is a SingleDenotation
or MultiDenotation it is possible that the particular Single- or Multi-Denotation
was not computed at the current phase, but the underlying SymDenotation
is valid. With the changes in this commit, we reaload the denotation as
a second try.
Diffstat (limited to 'src/dotty/tools/dotc/core/Denotations.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 6502c4a40..756e0b02d 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -2,7 +2,7 @@ package dotty.tools package dotc package core -import SymDenotations.{ SymDenotation, ClassDenotation, NoDenotation } +import SymDenotations.{ SymDenotation, ClassDenotation, NoDenotation, NotDefinedHereDenotation } import Contexts.{Context, ContextBase} import Names.{Name, PreName} import Names.TypeName @@ -128,7 +128,17 @@ object Denotations { */ def atSignature(sig: Signature, site: Type = NoPrefix)(implicit ctx: Context): SingleDenotation - /** The variant of this denotation that's current in the given context. */ + /** The variant of this denotation that's current in the given context, or + * `NotDefinedHereDenotation` if this denotation does not exist at current phase, but + * is defined elsewhere in this run. + */ + def currentIfExists(implicit ctx: Context): Denotation + + /** The variant of this denotation that's current in the given context. + * If no such denotation exists: If Mode.FutureDefs is set, the + * denotation with each alternative at its first point of definition, + * otherwise a `NotDefinedHere` exception is thrown. + */ def current(implicit ctx: Context): Denotation /** Is this denotation different from NoDenotation or an ErrorDenotation? */ @@ -349,6 +359,8 @@ object Denotations { final def signature(implicit ctx: Context) = Signature.OverloadedSignature def atSignature(sig: Signature, site: Type)(implicit ctx: Context): SingleDenotation = denot1.atSignature(sig, site) orElse denot2.atSignature(sig, site) + def currentIfExists(implicit ctx: Context): Denotation = + derivedMultiDenotation(denot1.currentIfExists, denot2.currentIfExists) def current(implicit ctx: Context): Denotation = derivedMultiDenotation(denot1.current, denot2.current) def altsWith(p: Symbol => Boolean): List[SingleDenotation] = @@ -530,7 +542,7 @@ object Denotations { * is brought forward to be valid in the new runId. Otherwise * the symbol is stale, which constitutes an internal error. */ - def current(implicit ctx: Context): SingleDenotation = { + def currentIfExists(implicit ctx: Context): SingleDenotation = { val currentPeriod = ctx.period val valid = myValidFor if (valid.code <= 0) { @@ -593,17 +605,24 @@ object Denotations { //println(s"searching: $cur at $currentPeriod, valid for ${cur.validFor}") cur = cur.nextInRun cnt += 1 - if (cnt > MaxPossiblePhaseId) - if (ctx.mode is Mode.FutureDefsOK) - return current(ctx.withPhase(coveredInterval.firstPhaseId)) - else - throw new NotDefinedHere(demandOutsideDefinedMsg) + if (cnt > MaxPossiblePhaseId) return NotDefinedHereDenotation } cur } } } + def current(implicit ctx: Context): SingleDenotation = { + val d = currentIfExists + if (d ne NotDefinedHereDenotation) d else currentNoDefinedHere + } + + private def currentNoDefinedHere(implicit ctx: Context): SingleDenotation = + if (ctx.mode is Mode.FutureDefsOK) + current(ctx.withPhase(coveredInterval.firstPhaseId)) + else + throw new NotDefinedHere(demandOutsideDefinedMsg) + private def demandOutsideDefinedMsg(implicit ctx: Context): String = s"demanding denotation of $this at phase ${ctx.phase}(${ctx.phaseId}) outside defined interval: defined periods are${definedPeriodsString}" |