Skip to content

Commit 7196517

Browse files
committed
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.
1 parent ae8a246 commit 7196517

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

src/dotty/tools/dotc/typer/Namer.scala

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import annotation.tailrec
1515
import ErrorReporting._
1616
import tpd.ListOfTreeDecorator
1717
import config.Printers._
18+
import Annotations._
1819
import language.implicitConversions
1920

2021
trait NamerContextOps { this: Context =>
@@ -495,8 +496,23 @@ class Namer { typer: Typer =>
495496
completeInCreationContext(denot)
496497
}
497498

498-
def completeInCreationContext(denot: SymDenotation): Unit =
499+
protected def addAnnotations(denot: SymDenotation): Unit = original match {
500+
case original: untpd.MemberDef =>
501+
for (annotTree <- untpd.modsDeco(original).mods.annotations) {
502+
val cls = typedAheadAnnotation(annotTree)
503+
val ann = Annotation.deferred(cls, implicit ctx => typedAnnotation(annotTree))
504+
denot.addAnnotation(ann)
505+
}
506+
case _ =>
507+
}
508+
509+
/** Intentionally left without `implicit ctx` parameter. We need
510+
* to pick up the context at the point where the completer was created.
511+
*/
512+
def completeInCreationContext(denot: SymDenotation): Unit = {
499513
denot.info = typeSig(denot.symbol)
514+
addAnnotations(denot)
515+
}
500516
}
501517

502518
class ClassCompleter(cls: ClassSymbol, original: TypeDef)(ictx: Context) extends Completer(original)(ictx) {
@@ -563,6 +579,7 @@ class Namer { typer: Typer =>
563579

564580
index(rest)(inClassContext(selfInfo))
565581
denot.info = ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo)
582+
addAnnotations(denot)
566583
if (impl.body forall isNoInitMember) cls.setFlag(NoInits)
567584
}
568585
}
@@ -585,6 +602,13 @@ class Namer { typer: Typer =>
585602
def typedAheadExpr(tree: Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree =
586603
typedAheadImpl(tree, pt)(ctx retractMode Mode.PatternOrType)
587604

605+
def typedAheadAnnotation(tree: Tree)(implicit ctx: Context): Symbol = tree match {
606+
case Apply(fn, _) => typedAheadAnnotation(fn)
607+
case TypeApply(fn, _) => typedAheadAnnotation(fn)
608+
case Select(qual, nme.CONSTRUCTOR) => typedAheadAnnotation(qual)
609+
case New(tpt) => typedAheadType(tpt).tpe.classSymbol
610+
}
611+
588612
/** Enter and typecheck parameter list */
589613
def completeParams(params: List[MemberDef])(implicit ctx: Context) = {
590614
index(params)

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
863863

864864
def addTypedModifiersAnnotations(mdef: untpd.MemberDef, sym: Symbol)(implicit ctx: Context): Unit = {
865865
val mods1 = typedModifiers(untpd.modsDeco(mdef).mods, sym)
866-
for (tree <- mods1.annotations) sym.addAnnotation(Annotation(tree))
866+
sym.annotations.foreach(_.tree) // force trees to be computed
867867
}
868868

869869
def typedModifiers(mods: untpd.Modifiers, sym: Symbol)(implicit ctx: Context): Modifiers = track("typedModifiers") {

0 commit comments

Comments
 (0)