forked from scala/scala
/
AnnotationOps.scala
64 lines (54 loc) · 2.18 KB
/
AnnotationOps.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/
package scala.tools.nsc.tasty.bridge
import scala.tools.nsc.tasty.TastyUniverse
/** Adds support for creating annotations from Trees */
trait AnnotationOps { self: TastyUniverse =>
import self.{symbolTable => u}
private[bridge] final def mkAnnotation(tree: Tree): u.Annotation = tree match {
case u.Apply(u.Select(u.New(tpt), u.nme.CONSTRUCTOR), args) =>
u.AnnotationInfo(tpt.tpe, args, Nil)
case u.Apply(u.TypeApply(u.Select(u.New(tpt), u.nme.CONSTRUCTOR), tpargs), args) =>
u.AnnotationInfo(u.appliedType(tpt.tpe, tpargs.map(_.tpe)), args, Nil)
case u.New(tpt) =>
// this is to handle incorrectly formatted annotations in dotty - https://github.com/lampepfl/dotty/issues/10113
u.AnnotationInfo(tpt.tpe, Nil, Nil)
case _ =>
throw new Exception(s"unexpected annotation kind from TASTy: ${u.showRaw(tree)}")
}
abstract class DeferredAnnotation {
private[bridge] def eager(annotee: Symbol)(implicit ctx: Context): u.AnnotationInfo
private[bridge] def lzy(annotee: Symbol)(implicit ctx: Context): u.LazyAnnotationInfo = {
u.AnnotationInfo.lazily {
eager(annotee)
}
}
}
object DeferredAnnotation {
def fromTree(tree: Symbol => Context => Tree) =
new FromTree(tree)
class FromTree(tree: Symbol => Context => Tree) extends DeferredAnnotation {
private[bridge] def eager(annotee: Symbol)(implicit ctx: Context): u.AnnotationInfo = {
val atree = tree(annotee)(ctx)
ctx.log(s"annotation on $annotee: $atree")
val annot = mkAnnotation(atree)
val annotSym = annot.tpe.typeSymbol
if ((annotSym eq defn.TargetNameAnnotationClass) || (annotSym eq defn.StaticMethodAnnotationClass)) {
annotee.addAnnotation(
u.definitions.CompileTimeOnlyAttr,
u.Literal(u.Constant(unsupportedMessage(s"annotation on $annotee: @$annot"))))
}
annot
}
}
}
}