Skip to content

Commit d70d184

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 0a50465 commit d70d184

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
cls.setApplicableFlags(
567584
(NoInitsInterface /: impl.body)((fs, stat) => fs & defKind(stat)))
568585
}
@@ -586,6 +603,13 @@ class Namer { typer: Typer =>
586603
def typedAheadExpr(tree: Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree =
587604
typedAheadImpl(tree, pt)(ctx retractMode Mode.PatternOrType)
588605

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

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

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

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

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

0 commit comments

Comments
 (0)