From 6edf859c9dae24aa4232110244a8b1119b0c63e0 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 7 May 2015 15:15:54 +0200 Subject: 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. --- src/dotty/tools/dotc/core/Denotations.scala | 35 ++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'src/dotty/tools/dotc/core/Denotations.scala') 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}" -- cgit v1.2.3