@@ -3,122 +3,195 @@ package api
33
44import scala .collection .immutable .ListMap
55
6- /**
7- * Defines the type hierarchy for annotations.
6+ /** This trait provides annotation support for the reflection API.
7+ *
8+ * The API distinguishes between two kinds of annotations:
9+ *
10+ * <ul>
11+ * <li>''Java annotations'': annotations on definitions produced by the Java compiler, i.e., subtypes of [[java.lang.annotation.Annotation ]]
12+ * attached to program definitions. When read by Scala reflection, the [[scala.annotation.ClassfileAnnotation ]] trait
13+ * is automatically added as a subclass to every Java annotation.</li>
14+ * <li>''Scala annotations'': annotations on definitions or types produced by the Scala compiler.</li>
15+ * </ul>
16+ *
17+ * When a Scala annotation that inherits from [[scala.annotation.StaticAnnotation ]] or [[scala.annotation.ClassfileAnnotation ]] is compiled,
18+ * it is stored as special attributes in the corresponding classfile, and not as a Java annotation. Note that subclassing
19+ * just [[scala.annotation.Annotation ]] is not enough to have the corresponding metadata persisted for runtime reflection.
20+ *
21+ * The distinction between Java and Scala annotations is manifested in the contract of [[scala.reflect.api.Annotations#Annotation ]], which exposes
22+ * both `scalaArgs` and `javaArgs`. For Scala or Java annotations extending [[scala.annotation.ClassfileAnnotation ]] `scalaArgs` is empty
23+ * and arguments are stored in `javaArgs`. For all other Scala annotations, arguments are stored in `scalaArgs` and `javaArgs` is empty.
24+ *
25+ * Arguments in `scalaArgs` are represented as typed trees. Note that these trees are not transformed by any phases
26+ * following the type-checker. Arguments in `javaArgs` are repesented as a map from [[scala.reflect.api.Names#Name ]] to
27+ * [[scala.reflect.api.Annotations#JavaArgument ]]. Instances of `JavaArgument` represent different kinds of Java annotation arguments:
28+ * - literals (primitive and string constants),
29+ * - arrays and
30+ * - nested annotations.
31+ *
32+ * @contentDiagram hideNodes "*Api"
833 */
934trait Annotations { self : Universe =>
1035
11- /** Typed information about an annotation. It can be attached to either a symbol or an annotated type.
12- *
13- * Annotations are either ''Scala annotations'', which conform to [[scala.annotation.StaticAnnotation ]]
14- * or ''Java annotations'', which conform to [[scala.annotation.ClassfileAnnotation ]].
15- * Trait `ClassfileAnnotation` is automatically added to every Java annotation by the scalac classfile parser.
36+ /** Information about an annotation.
37+ * @template
38+ * @group Annotations
1639 */
1740 type Annotation >: Null <: AnyRef with AnnotationApi
1841
1942 /** A tag that preserves the identity of the `Annotation` abstract type from erasure.
2043 * Can be used for pattern matching, instance tests, serialization and likes.
44+ * @group Tags
2145 */
2246 implicit val AnnotationTag : ClassTag [Annotation ]
2347
24- /** The constructor/deconstructor for `Annotation` instances. */
48+ /** The constructor/deconstructor for `Annotation` instances.
49+ * @group Extractors
50+ */
2551 val Annotation : AnnotationExtractor
2652
27- /** An extractor class to create and pattern match with syntax `Annotation(atp, scalaArgs, javaArgs)`.
28- * Here, `atp` is the annotation type, `scalaArgs` the arguments, and `javaArgs` the annotation's key-value
29- * pairs.
30- *
31- * Annotations are pickled, i.e. written to scala symtab attribute in the classfile.
32- * Annotations are written to the classfile as Java annotations if `atp` conforms to `ClassfileAnnotation`.
33- *
34- * For Scala annotations, arguments are stored in `scalaArgs` and `javaArgs` is empty. Arguments in
35- * `scalaArgs` are represented as typed trees. Note that these trees are not transformed by any phases
36- * following the type-checker. For Java annotations, `scalaArgs` is empty and arguments are stored in
37- * `javaArgs`.
38- */
53+ /** An extractor class to create and pattern match with syntax `Annotation(tpe, scalaArgs, javaArgs)`.
54+ * Here, `tpe` is the annotation type, `scalaArgs` the payload of Scala annotations, and `javaArgs` the payload of Java annotations.
55+ * @group Extractors
56+ */
3957 abstract class AnnotationExtractor {
4058 def apply (tpe : Type , scalaArgs : List [Tree ], javaArgs : ListMap [Name , JavaArgument ]): Annotation
4159 def unapply (ann : Annotation ): Option [(Type , List [Tree ], ListMap [Name , JavaArgument ])]
4260 }
4361
62+ /** The API of `Annotation` instances.
63+ * The main source of information about annotations is the [[scala.reflect.api.Annotations ]] page.
64+ * @group API
65+ */
4466 trait AnnotationApi {
67+ /** The type of the annotation. */
4568 def tpe : Type
69+
70+ /** Payload of the Scala annotation: a list of abstract syntax trees that represent the argument.
71+ * Empty for Java annotations.
72+ */
4673 def scalaArgs : List [Tree ]
74+
75+ /** Payload of the Java annotation: a list of name-value pairs.
76+ * Empty for Scala annotations.
77+ */
4778 def javaArgs : ListMap [Name , JavaArgument ]
4879 }
4980
50- /** A Java annotation argument */
81+ /** A Java annotation argument
82+ * @template
83+ * @group Annotations
84+ */
5185 type JavaArgument >: Null <: AnyRef
86+
87+ /** A tag that preserves the identity of the `JavaArgument` abstract type from erasure.
88+ * Can be used for pattern matching, instance tests, serialization and likes.
89+ * @group Tags
90+ */
5291 implicit val JavaArgumentTag : ClassTag [JavaArgument ]
5392
54- /** A literal argument to a Java annotation as `"Use X instead"` in `@Deprecated("Use X instead")`*/
93+ /** A literal argument to a Java annotation as `"Use X instead"` in `@Deprecated("Use X instead")`
94+ * @template
95+ * @group Annotations
96+ */
5597 type LiteralArgument >: Null <: AnyRef with JavaArgument with LiteralArgumentApi
5698
5799 /** A tag that preserves the identity of the `LiteralArgument` abstract type from erasure.
58100 * Can be used for pattern matching, instance tests, serialization and likes.
101+ * @group Tags
59102 */
60103 implicit val LiteralArgumentTag : ClassTag [LiteralArgument ]
61104
62- /** The constructor/deconstructor for `LiteralArgument` instances. */
105+ /** The constructor/deconstructor for `LiteralArgument` instances.
106+ * @group Extractors
107+ */
63108 val LiteralArgument : LiteralArgumentExtractor
64109
65110 /** An extractor class to create and pattern match with syntax `LiteralArgument(value)`
66111 * where `value` is the constant argument.
112+ * @group Extractors
67113 */
68114 abstract class LiteralArgumentExtractor {
69115 def apply (value : Constant ): LiteralArgument
70116 def unapply (arg : LiteralArgument ): Option [Constant ]
71117 }
72118
119+ /** The API of `LiteralArgument` instances.
120+ * The main source of information about annotations is the [[scala.reflect.api.Annotations ]] page.
121+ * @group API
122+ */
73123 trait LiteralArgumentApi {
124+ /** The underlying compile-time constant value. */
74125 def value : Constant
75126 }
76127
77128 /** An array argument to a Java annotation as in `@Target(value={TYPE,FIELD,METHOD,PARAMETER})`
129+ * @template
130+ * @group Annotations
78131 */
79132 type ArrayArgument >: Null <: AnyRef with JavaArgument with ArrayArgumentApi
80133
81134 /** A tag that preserves the identity of the `ArrayArgument` abstract type from erasure.
82135 * Can be used for pattern matching, instance tests, serialization and likes.
136+ * @group Tags
83137 */
84138 implicit val ArrayArgumentTag : ClassTag [ArrayArgument ]
85139
86- /** The constructor/deconstructor for `ArrayArgument` instances. */
140+ /** The constructor/deconstructor for `ArrayArgument` instances.
141+ * @group Extractors
142+ */
87143 val ArrayArgument : ArrayArgumentExtractor
88144
89145 /** An extractor class to create and pattern match with syntax `ArrayArgument(args)`
90146 * where `args` is the argument array.
147+ * @group Extractors
91148 */
92149 abstract class ArrayArgumentExtractor {
93150 def apply (args : Array [JavaArgument ]): ArrayArgument
94151 def unapply (arg : ArrayArgument ): Option [Array [JavaArgument ]]
95152 }
96153
154+ /** API of `ArrayArgument` instances.
155+ * The main source of information about annotations is the [[scala.reflect.api.Annotations ]] page.
156+ * @group API
157+ */
97158 trait ArrayArgumentApi {
159+ /** The underlying array of Java annotation arguments. */
98160 def args : Array [JavaArgument ]
99161 }
100162
101163 /** A nested annotation argument to a Java annotation as `@Nested` in `@Outer(@Nested)`.
164+ * @template
165+ * @group Annotations
102166 */
103167 type NestedArgument >: Null <: AnyRef with JavaArgument with NestedArgumentApi
104168
105169 /** A tag that preserves the identity of the `NestedArgument` abstract type from erasure.
106170 * Can be used for pattern matching, instance tests, serialization and likes.
171+ * @group Tags
107172 */
108173 implicit val NestedArgumentTag : ClassTag [NestedArgument ]
109174
110- /** The constructor/deconstructor for `NestedArgument` instances. */
175+ /** The constructor/deconstructor for `NestedArgument` instances.
176+ * @group Extractors
177+ */
111178 val NestedArgument : NestedArgumentExtractor
112179
113180 /** An extractor class to create and pattern match with syntax `NestedArgument(annotation)`
114181 * where `annotation` is the nested annotation.
182+ * @group Extractors
115183 */
116184 abstract class NestedArgumentExtractor {
117185 def apply (annotation : Annotation ): NestedArgument
118186 def unapply (arg : NestedArgument ): Option [Annotation ]
119187 }
120188
189+ /** API of `NestedArgument` instances.
190+ * The main source of information about annotations is the [[scala.reflect.api.Annotations ]] page.
191+ * @group API
192+ */
121193 trait NestedArgumentApi {
194+ /** The underlying nested annotation. */
122195 def annotation : Annotation
123196 }
124197}
0 commit comments