aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Namer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-06-14 18:50:23 +0200
committerMartin Odersky <odersky@gmail.com>2015-06-19 12:03:38 +0200
commitd70d184d793971a598452b02ea3ab87e3ff4cf03 (patch)
tree5057f09631f73985f0d0f2cb8af5e0bc00391568 /src/dotty/tools/dotc/typer/Namer.scala
parent0a504655329dc01a0dc91b847de7ac2b1a688692 (diff)
downloaddotty-d70d184d793971a598452b02ea3ab87e3ff4cf03.tar.gz
dotty-d70d184d793971a598452b02ea3ab87e3ff4cf03.tar.bz2
dotty-d70d184d793971a598452b02ea3ab87e3ff4cf03.zip
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.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Namer.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala26
1 files changed, 25 insertions, 1 deletions
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)