From d70d184d793971a598452b02ea3ab87e3ff4cf03 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 14 Jun 2015 18:50:23 +0200 Subject: Evaluate annotations in Namer Annotations were evaluated in Typer, which meant that they could be used only after type checking was complete (or compilation order dependencies would be introduced). This commit makes annotations be installed as part of completion in Namer. However, annotations are now lazy so as to avoid cyclic references. This is completely analogous to the scheme in unpickler and ClassfileParser. --- src/dotty/tools/dotc/typer/Namer.scala | 26 +++++++++++++++++++++++++- src/dotty/tools/dotc/typer/Typer.scala | 2 +- 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'src/dotty/tools/dotc/typer') diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index c81857e6f..11a0bd76e 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -15,6 +15,7 @@ import annotation.tailrec import ErrorReporting._ import tpd.ListOfTreeDecorator import config.Printers._ +import Annotations._ import language.implicitConversions trait NamerContextOps { this: Context => @@ -495,8 +496,23 @@ class Namer { typer: Typer => completeInCreationContext(denot) } - def completeInCreationContext(denot: SymDenotation): Unit = + protected def addAnnotations(denot: SymDenotation): Unit = original match { + case original: untpd.MemberDef => + for (annotTree <- untpd.modsDeco(original).mods.annotations) { + val cls = typedAheadAnnotation(annotTree) + val ann = Annotation.deferred(cls, implicit ctx => typedAnnotation(annotTree)) + denot.addAnnotation(ann) + } + case _ => + } + + /** Intentionally left without `implicit ctx` parameter. We need + * to pick up the context at the point where the completer was created. + */ + def completeInCreationContext(denot: SymDenotation): Unit = { denot.info = typeSig(denot.symbol) + addAnnotations(denot) + } } class ClassCompleter(cls: ClassSymbol, original: TypeDef)(ictx: Context) extends Completer(original)(ictx) { @@ -563,6 +579,7 @@ class Namer { typer: Typer => index(rest)(inClassContext(selfInfo)) denot.info = ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo) + addAnnotations(denot) cls.setApplicableFlags( (NoInitsInterface /: impl.body)((fs, stat) => fs & defKind(stat))) } @@ -586,6 +603,13 @@ class Namer { typer: Typer => def typedAheadExpr(tree: Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree = typedAheadImpl(tree, pt)(ctx retractMode Mode.PatternOrType) + def typedAheadAnnotation(tree: Tree)(implicit ctx: Context): Symbol = tree match { + case Apply(fn, _) => typedAheadAnnotation(fn) + case TypeApply(fn, _) => typedAheadAnnotation(fn) + case Select(qual, nme.CONSTRUCTOR) => typedAheadAnnotation(qual) + case New(tpt) => typedAheadType(tpt).tpe.classSymbol + } + /** Enter and typecheck parameter list */ def completeParams(params: List[MemberDef])(implicit ctx: Context) = { index(params) diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 5f03d19e7..db3ae9319 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -861,7 +861,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit def addTypedModifiersAnnotations(mdef: untpd.MemberDef, sym: Symbol)(implicit ctx: Context): Unit = { val mods1 = typedModifiers(untpd.modsDeco(mdef).mods, sym) - for (tree <- mods1.annotations) sym.addAnnotation(Annotation(tree)) + sym.annotations.foreach(_.tree) // force trees to be computed } def typedModifiers(mods: untpd.Modifiers, sym: Symbol)(implicit ctx: Context): Modifiers = track("typedModifiers") { -- cgit v1.2.3