1 /*
2  * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package com.sun.tools.javac.comp;
27 
28 import com.sun.tools.javac.code.*;
29 import com.sun.tools.javac.code.Attribute.Compound;
30 import com.sun.tools.javac.code.Attribute.TypeCompound;
31 import com.sun.tools.javac.code.Kinds.KindSelector;
32 import com.sun.tools.javac.code.Scope.WriteableScope;
33 import com.sun.tools.javac.code.Source.Feature;
34 import com.sun.tools.javac.code.Symbol.*;
35 import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
36 import com.sun.tools.javac.comp.Check.CheckContext;
37 import com.sun.tools.javac.resources.CompilerProperties.Errors;
38 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
39 import com.sun.tools.javac.tree.JCTree;
40 import com.sun.tools.javac.tree.JCTree.*;
41 import com.sun.tools.javac.tree.TreeInfo;
42 import com.sun.tools.javac.tree.TreeMaker;
43 import com.sun.tools.javac.tree.TreeScanner;
44 import com.sun.tools.javac.util.*;
45 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
46 import com.sun.tools.javac.util.List;
47 
48 import javax.tools.JavaFileObject;
49 
50 import java.util.*;
51 
52 import static com.sun.tools.javac.code.Flags.SYNTHETIC;
53 import static com.sun.tools.javac.code.Kinds.Kind.MDL;
54 import static com.sun.tools.javac.code.Kinds.Kind.MTH;
55 import static com.sun.tools.javac.code.Kinds.Kind.PCK;
56 import static com.sun.tools.javac.code.Kinds.Kind.VAR;
57 import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
58 import static com.sun.tools.javac.code.TypeTag.ARRAY;
59 import static com.sun.tools.javac.code.TypeTag.CLASS;
60 import static com.sun.tools.javac.tree.JCTree.Tag.ANNOTATION;
61 import static com.sun.tools.javac.tree.JCTree.Tag.ASSIGN;
62 import static com.sun.tools.javac.tree.JCTree.Tag.IDENT;
63 import static com.sun.tools.javac.tree.JCTree.Tag.NEWARRAY;
64 
65 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
66 
67 
68 /** Enter annotations onto symbols and types (and trees).
69  *
70  *  This is also a pseudo stage in the compiler taking care of scheduling when annotations are
71  *  entered.
72  *
73  *  <p><b>This is NOT part of any supported API.
74  *  If you write code that depends on this, you do so at your own risk.
75  *  This code and its internal interfaces are subject to change or
76  *  deletion without notice.</b>
77  */
78 public class Annotate {
79     protected static final Context.Key<Annotate> annotateKey = new Context.Key<>();
80 
instance(Context context)81     public static Annotate instance(Context context) {
82         Annotate instance = context.get(annotateKey);
83         if (instance == null)
84             instance = new Annotate(context);
85         return instance;
86     }
87 
88     private final Attr attr;
89     private final Check chk;
90     private final ConstFold cfolder;
91     private final DeferredLintHandler deferredLintHandler;
92     private final Enter enter;
93     private final Lint lint;
94     private final Log log;
95     private final Names names;
96     private final Resolve resolve;
97     private final TreeMaker make;
98     private final Symtab syms;
99     private final TypeEnvs typeEnvs;
100     private final Types types;
101 
102     private final Attribute theUnfinishedDefaultValue;
103     private final boolean allowRepeatedAnnos;
104     private final String sourceName;
105 
Annotate(Context context)106     protected Annotate(Context context) {
107         context.put(annotateKey, this);
108 
109         attr = Attr.instance(context);
110         chk = Check.instance(context);
111         cfolder = ConstFold.instance(context);
112         deferredLintHandler = DeferredLintHandler.instance(context);
113         enter = Enter.instance(context);
114         log = Log.instance(context);
115         lint = Lint.instance(context);
116         make = TreeMaker.instance(context);
117         names = Names.instance(context);
118         resolve = Resolve.instance(context);
119         syms = Symtab.instance(context);
120         typeEnvs = TypeEnvs.instance(context);
121         types = Types.instance(context);
122 
123         theUnfinishedDefaultValue =  new Attribute.Error(syms.errType);
124 
125         Source source = Source.instance(context);
126         allowRepeatedAnnos = Feature.REPEATED_ANNOTATIONS.allowedInSource(source);
127         sourceName = source.name;
128 
129         blockCount = 1;
130     }
131 
132     /** Semaphore to delay annotation processing */
133     private int blockCount = 0;
134 
135     /** Called when annotations processing needs to be postponed. */
blockAnnotations()136     public void blockAnnotations() {
137         blockCount++;
138     }
139 
140     /** Called when annotation processing can be resumed. */
unblockAnnotations()141     public void unblockAnnotations() {
142         blockCount--;
143         if (blockCount == 0)
144             flush();
145     }
146 
147     /** Variant which allows for a delayed flush of annotations.
148      * Needed by ClassReader */
unblockAnnotationsNoFlush()149     public void unblockAnnotationsNoFlush() {
150         blockCount--;
151     }
152 
153     /** are we blocking annotation processing? */
annotationsBlocked()154     public boolean annotationsBlocked() {return blockCount > 0; }
155 
enterDone()156     public void enterDone() {
157         unblockAnnotations();
158     }
159 
fromAnnotations(List<JCAnnotation> annotations)160     public List<TypeCompound> fromAnnotations(List<JCAnnotation> annotations) {
161         if (annotations.isEmpty()) {
162             return List.nil();
163         }
164 
165         ListBuffer<TypeCompound> buf = new ListBuffer<>();
166         for (JCAnnotation anno : annotations) {
167             Assert.checkNonNull(anno.attribute);
168             buf.append((TypeCompound) anno.attribute);
169         }
170         return buf.toList();
171     }
172 
173     /** Annotate (used for everything else) */
normal(Runnable r)174     public void normal(Runnable r) {
175         q.append(r);
176     }
177 
178     /** Validate, triggers after 'normal' */
validate(Runnable a)179     public void validate(Runnable a) {
180         validateQ.append(a);
181     }
182 
183     /** Flush all annotation queues */
flush()184     public void flush() {
185         if (annotationsBlocked()) return;
186         if (isFlushing()) return;
187 
188         startFlushing();
189         try {
190             while (q.nonEmpty()) {
191                 q.next().run();
192             }
193             while (typesQ.nonEmpty()) {
194                 typesQ.next().run();
195             }
196             while (afterTypesQ.nonEmpty()) {
197                 afterTypesQ.next().run();
198             }
199             while (validateQ.nonEmpty()) {
200                 validateQ.next().run();
201             }
202         } finally {
203             doneFlushing();
204         }
205     }
206 
207     private ListBuffer<Runnable> q = new ListBuffer<>();
208     private ListBuffer<Runnable> validateQ = new ListBuffer<>();
209 
210     private int flushCount = 0;
isFlushing()211     private boolean isFlushing() { return flushCount > 0; }
startFlushing()212     private void startFlushing() { flushCount++; }
doneFlushing()213     private void doneFlushing() { flushCount--; }
214 
215     ListBuffer<Runnable> typesQ = new ListBuffer<>();
216     ListBuffer<Runnable> afterTypesQ = new ListBuffer<>();
217 
218 
typeAnnotation(Runnable a)219     public void typeAnnotation(Runnable a) {
220         typesQ.append(a);
221     }
222 
afterTypes(Runnable a)223     public void afterTypes(Runnable a) {
224         afterTypesQ.append(a);
225     }
226 
227     /**
228      * Queue annotations for later attribution and entering. This is probably the method you are looking for.
229      *
230      * @param annotations the list of JCAnnotations to attribute and enter
231      * @param localEnv    the enclosing env
232      * @param s           ths Symbol on which to enter the annotations
233      * @param deferPos    report errors here
234      */
annotateLater(List<JCAnnotation> annotations, Env<AttrContext> localEnv, Symbol s, DiagnosticPosition deferPos)235     public void annotateLater(List<JCAnnotation> annotations, Env<AttrContext> localEnv,
236             Symbol s, DiagnosticPosition deferPos)
237     {
238         if (annotations.isEmpty()) {
239             return;
240         }
241 
242         s.resetAnnotations(); // mark Annotations as incomplete for now
243 
244         normal(() -> {
245             // Packages are unusual, in that they are the only type of declaration that can legally appear
246             // more than once in a compilation, and in all cases refer to the same underlying symbol.
247             // This means they are the only kind of declaration that syntactically may have multiple sets
248             // of annotations, each on a different package declaration, even though that is ultimately
249             // forbidden by JLS 8 section 7.4.
250             // The corollary here is that all of the annotations on a package symbol may have already
251             // been handled, meaning that the set of annotations pending completion is now empty.
252             Assert.check(s.kind == PCK || s.annotationsPendingCompletion());
253             JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
254             DiagnosticPosition prevLintPos =
255                     deferPos != null
256                             ? deferredLintHandler.setPos(deferPos)
257                             : deferredLintHandler.immediate();
258             Lint prevLint = deferPos != null ? null : chk.setLint(lint);
259             try {
260                 if (s.hasAnnotations() && annotations.nonEmpty())
261                     log.error(annotations.head.pos, Errors.AlreadyAnnotated(Kinds.kindName(s), s));
262 
263                 Assert.checkNonNull(s, "Symbol argument to actualEnterAnnotations is null");
264 
265                 // false is passed as fifth parameter since annotateLater is
266                 // never called for a type parameter
267                 annotateNow(s, annotations, localEnv, false, false);
268             } finally {
269                 if (prevLint != null)
270                     chk.setLint(prevLint);
271                 deferredLintHandler.setPos(prevLintPos);
272                 log.useSource(prev);
273             }
274         });
275 
276         validate(() -> { //validate annotations
277             JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
278             try {
279                 chk.validateAnnotations(annotations, s);
280             } finally {
281                 log.useSource(prev);
282             }
283         });
284     }
285 
286 
287     /** Queue processing of an attribute default value. */
annotateDefaultValueLater(JCExpression defaultValue, Env<AttrContext> localEnv, MethodSymbol m, DiagnosticPosition deferPos)288     public void annotateDefaultValueLater(JCExpression defaultValue, Env<AttrContext> localEnv,
289             MethodSymbol m, DiagnosticPosition deferPos)
290     {
291         normal(() -> {
292             JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
293             DiagnosticPosition prevLintPos = deferredLintHandler.setPos(deferPos);
294             try {
295                 enterDefaultValue(defaultValue, localEnv, m);
296             } finally {
297                 deferredLintHandler.setPos(prevLintPos);
298                 log.useSource(prev);
299             }
300         });
301 
302         validate(() -> { //validate annotations
303             JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
304             try {
305                 // if default value is an annotation, check it is a well-formed
306                 // annotation value (e.g. no duplicate values, no missing values, etc.)
307                 chk.validateAnnotationTree(defaultValue);
308             } finally {
309                 log.useSource(prev);
310             }
311         });
312     }
313 
314     /** Enter a default value for an annotation element. */
enterDefaultValue(JCExpression defaultValue, Env<AttrContext> localEnv, MethodSymbol m)315     private void enterDefaultValue(JCExpression defaultValue,
316             Env<AttrContext> localEnv, MethodSymbol m) {
317         m.defaultValue = attributeAnnotationValue(m.type.getReturnType(), defaultValue, localEnv);
318     }
319 
320     /**
321      * Gather up annotations into a map from type symbols to lists of Compound attributes,
322      * then continue on with repeating annotations processing.
323      */
annotateNow(Symbol toAnnotate, List<JCAnnotation> withAnnotations, Env<AttrContext> env, boolean typeAnnotations, boolean isTypeParam)324     private <T extends Attribute.Compound> void annotateNow(Symbol toAnnotate,
325             List<JCAnnotation> withAnnotations, Env<AttrContext> env, boolean typeAnnotations,
326             boolean isTypeParam)
327     {
328         Map<TypeSymbol, ListBuffer<T>> annotated = new LinkedHashMap<>();
329         Map<T, DiagnosticPosition> pos = new HashMap<>();
330 
331         for (List<JCAnnotation> al = withAnnotations; !al.isEmpty(); al = al.tail) {
332             JCAnnotation a = al.head;
333 
334             T c;
335             if (typeAnnotations) {
336                 @SuppressWarnings("unchecked")
337                 T tmp = (T)attributeTypeAnnotation(a, syms.annotationType, env);
338                 c = tmp;
339             } else {
340                 @SuppressWarnings("unchecked")
341                 T tmp = (T)attributeAnnotation(a, syms.annotationType, env);
342                 c = tmp;
343             }
344 
345             Assert.checkNonNull(c, "Failed to create annotation");
346 
347             if (annotated.containsKey(a.type.tsym)) {
348                 if (!allowRepeatedAnnos) {
349                     log.error(DiagnosticFlag.SOURCE_LEVEL, a.pos(), Feature.REPEATED_ANNOTATIONS.error(sourceName));
350                 }
351                 ListBuffer<T> l = annotated.get(a.type.tsym);
352                 l = l.append(c);
353                 annotated.put(a.type.tsym, l);
354                 pos.put(c, a.pos());
355             } else {
356                 annotated.put(a.type.tsym, ListBuffer.of(c));
357                 pos.put(c, a.pos());
358             }
359 
360             // Note: @Deprecated has no effect on local variables and parameters
361             if (!c.type.isErroneous()
362                     && (toAnnotate.kind == MDL || toAnnotate.owner.kind != MTH)
363                     && types.isSameType(c.type, syms.deprecatedType)) {
364                 toAnnotate.flags_field |= (Flags.DEPRECATED | Flags.DEPRECATED_ANNOTATION);
365                 Attribute fr = c.member(names.forRemoval);
366                 if (fr instanceof Attribute.Constant) {
367                     Attribute.Constant v = (Attribute.Constant) fr;
368                     if (v.type == syms.booleanType && ((Integer) v.value) != 0) {
369                         toAnnotate.flags_field |= Flags.DEPRECATED_REMOVAL;
370                     }
371                 }
372             }
373         }
374 
375         List<T> buf = List.nil();
376         for (ListBuffer<T> lb : annotated.values()) {
377             if (lb.size() == 1) {
378                 buf = buf.prepend(lb.first());
379             } else {
380                 AnnotationContext<T> ctx = new AnnotationContext<>(env, annotated, pos, typeAnnotations);
381                 T res = makeContainerAnnotation(lb.toList(), ctx, toAnnotate, isTypeParam);
382                 if (res != null)
383                     buf = buf.prepend(res);
384             }
385         }
386 
387         if (typeAnnotations) {
388             @SuppressWarnings("unchecked")
389             List<TypeCompound> attrs = (List<TypeCompound>)buf.reverse();
390             toAnnotate.appendUniqueTypeAttributes(attrs);
391         } else {
392             @SuppressWarnings("unchecked")
393             List<Attribute.Compound> attrs =  (List<Attribute.Compound>)buf.reverse();
394             toAnnotate.resetAnnotations();
395             toAnnotate.setDeclarationAttributes(attrs);
396         }
397     }
398 
399     /**
400      * Attribute and store a semantic representation of the annotation tree {@code tree} into the
401      * tree.attribute field.
402      *
403      * @param tree the tree representing an annotation
404      * @param expectedAnnotationType the expected (super)type of the annotation
405      * @param env the current env in where the annotation instance is found
406      */
attributeAnnotation(JCAnnotation tree, Type expectedAnnotationType, Env<AttrContext> env)407     public Attribute.Compound attributeAnnotation(JCAnnotation tree, Type expectedAnnotationType,
408                                                   Env<AttrContext> env)
409     {
410         // The attribute might have been entered if it is Target or Repetable
411         // Because TreeCopier does not copy type, redo this if type is null
412         if (tree.attribute != null && tree.type != null)
413             return tree.attribute;
414 
415         List<Pair<MethodSymbol, Attribute>> elems = attributeAnnotationValues(tree, expectedAnnotationType, env);
416         Attribute.Compound ac = new Attribute.Compound(tree.type, elems);
417 
418         return tree.attribute = ac;
419     }
420 
421     /** Attribute and store a semantic representation of the type annotation tree {@code tree} into
422      * the tree.attribute field.
423      *
424      * @param a the tree representing an annotation
425      * @param expectedAnnotationType the expected (super)type of the annotation
426      * @param env the the current env in where the annotation instance is found
427      */
attributeTypeAnnotation(JCAnnotation a, Type expectedAnnotationType, Env<AttrContext> env)428     public Attribute.TypeCompound attributeTypeAnnotation(JCAnnotation a, Type expectedAnnotationType,
429                                                           Env<AttrContext> env)
430     {
431         // The attribute might have been entered if it is Target or Repetable
432         // Because TreeCopier does not copy type, redo this if type is null
433         if (a.attribute == null || a.type == null || !(a.attribute instanceof Attribute.TypeCompound)) {
434             // Create a new TypeCompound
435             List<Pair<MethodSymbol,Attribute>> elems =
436                     attributeAnnotationValues(a, expectedAnnotationType, env);
437 
438             Attribute.TypeCompound tc =
439                     new Attribute.TypeCompound(a.type, elems, TypeAnnotationPosition.unknown);
440             a.attribute = tc;
441             return tc;
442         } else {
443             // Use an existing TypeCompound
444             return (Attribute.TypeCompound)a.attribute;
445         }
446     }
447 
448     /**
449      *  Attribute annotation elements creating a list of pairs of the Symbol representing that
450      *  element and the value of that element as an Attribute. */
attributeAnnotationValues(JCAnnotation a, Type expected, Env<AttrContext> env)451     private List<Pair<MethodSymbol, Attribute>> attributeAnnotationValues(JCAnnotation a,
452             Type expected, Env<AttrContext> env)
453     {
454         // The annotation might have had its type attributed (but not
455         // checked) by attr.attribAnnotationTypes during MemberEnter,
456         // in which case we do not need to do it again.
457         Type at = (a.annotationType.type != null ?
458                 a.annotationType.type : attr.attribType(a.annotationType, env));
459         a.type = chk.checkType(a.annotationType.pos(), at, expected);
460 
461         boolean isError = a.type.isErroneous();
462         if (!a.type.tsym.isAnnotationType() && !isError) {
463             log.error(a.annotationType.pos(), Errors.NotAnnotationType(a.type));
464             isError = true;
465         }
466 
467         // List of name=value pairs (or implicit "value=" if size 1)
468         List<JCExpression> args = a.args;
469 
470         boolean elidedValue = false;
471         // special case: elided "value=" assumed
472         if (args.length() == 1 && !args.head.hasTag(ASSIGN)) {
473             args.head = make.at(args.head.pos).
474                     Assign(make.Ident(names.value), args.head);
475             elidedValue = true;
476         }
477 
478         ListBuffer<Pair<MethodSymbol,Attribute>> buf = new ListBuffer<>();
479         for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) {
480             Pair<MethodSymbol, Attribute> p = attributeAnnotationNameValuePair(tl.head, a.type, isError, env, elidedValue);
481             if (p != null && !p.fst.type.isErroneous())
482                 buf.append(p);
483         }
484         return buf.toList();
485     }
486 
487     // where
attributeAnnotationNameValuePair(JCExpression nameValuePair, Type thisAnnotationType, boolean badAnnotation, Env<AttrContext> env, boolean elidedValue)488     private Pair<MethodSymbol, Attribute> attributeAnnotationNameValuePair(JCExpression nameValuePair,
489             Type thisAnnotationType, boolean badAnnotation, Env<AttrContext> env, boolean elidedValue)
490     {
491         if (!nameValuePair.hasTag(ASSIGN)) {
492             log.error(nameValuePair.pos(), Errors.AnnotationValueMustBeNameValue);
493             attributeAnnotationValue(nameValuePair.type = syms.errType, nameValuePair, env);
494             return null;
495         }
496         JCAssign assign = (JCAssign)nameValuePair;
497         if (!assign.lhs.hasTag(IDENT)) {
498             log.error(nameValuePair.pos(), Errors.AnnotationValueMustBeNameValue);
499             attributeAnnotationValue(nameValuePair.type = syms.errType, nameValuePair, env);
500             return null;
501         }
502 
503         // Resolve element to MethodSym
504         JCIdent left = (JCIdent)assign.lhs;
505         Symbol method = resolve.resolveQualifiedMethod(elidedValue ? assign.rhs.pos() : left.pos(),
506                 env, thisAnnotationType,
507                 left.name, List.nil(), null);
508         left.sym = method;
509         left.type = method.type;
510         if (method.owner != thisAnnotationType.tsym && !badAnnotation)
511             log.error(left.pos(), Errors.NoAnnotationMember(left.name, thisAnnotationType));
512         Type resultType = method.type.getReturnType();
513 
514         // Compute value part
515         Attribute value = attributeAnnotationValue(resultType, assign.rhs, env);
516         nameValuePair.type = resultType;
517 
518         return method.type.isErroneous() ? null : new Pair<>((MethodSymbol)method, value);
519 
520     }
521 
522     /** Attribute an annotation element value */
attributeAnnotationValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env)523     private Attribute attributeAnnotationValue(Type expectedElementType, JCExpression tree,
524             Env<AttrContext> env)
525     {
526         //first, try completing the symbol for the annotation value - if acompletion
527         //error is thrown, we should recover gracefully, and display an
528         //ordinary resolution diagnostic.
529         try {
530             expectedElementType.tsym.complete();
531         } catch(CompletionFailure e) {
532             log.error(tree.pos(), Errors.CantResolve(Kinds.kindName(e.sym), e.sym.getQualifiedName(), null, null));
533             expectedElementType = syms.errType;
534         }
535 
536         if (expectedElementType.hasTag(ARRAY)) {
537             return getAnnotationArrayValue(expectedElementType, tree, env);
538 
539         }
540 
541         //error recovery
542         if (tree.hasTag(NEWARRAY)) {
543             if (!expectedElementType.isErroneous())
544                 log.error(tree.pos(), Errors.AnnotationValueNotAllowableType);
545             JCNewArray na = (JCNewArray)tree;
546             if (na.elemtype != null) {
547                 log.error(na.elemtype.pos(), Errors.NewNotAllowedInAnnotation);
548             }
549             for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
550                 attributeAnnotationValue(syms.errType,
551                         l.head,
552                         env);
553             }
554             return new Attribute.Error(syms.errType);
555         }
556 
557         if (expectedElementType.tsym.isAnnotationType()) {
558             if (tree.hasTag(ANNOTATION)) {
559                 return attributeAnnotation((JCAnnotation)tree, expectedElementType, env);
560             } else {
561                 log.error(tree.pos(), Errors.AnnotationValueMustBeAnnotation);
562                 expectedElementType = syms.errType;
563             }
564         }
565 
566         //error recovery
567         if (tree.hasTag(ANNOTATION)) {
568             if (!expectedElementType.isErroneous())
569                 log.error(tree.pos(), Errors.AnnotationNotValidForType(expectedElementType));
570             attributeAnnotation((JCAnnotation)tree, syms.errType, env);
571             return new Attribute.Error(((JCAnnotation)tree).annotationType.type);
572         }
573 
574         MemberEnter.InitTreeVisitor initTreeVisitor = new MemberEnter.InitTreeVisitor() {
575             // the methods below are added to allow class literals on top of constant expressions
576             @Override
577             public void visitTypeIdent(JCPrimitiveTypeTree that) {}
578 
579             @Override
580             public void visitTypeArray(JCArrayTypeTree that) {}
581         };
582         tree.accept(initTreeVisitor);
583         if (!initTreeVisitor.result) {
584             log.error(tree.pos(), Errors.ExpressionNotAllowableAsAnnotationValue);
585             return new Attribute.Error(syms.errType);
586         }
587 
588         if (expectedElementType.isPrimitive() ||
589                 (types.isSameType(expectedElementType, syms.stringType) && !expectedElementType.hasTag(TypeTag.ERROR))) {
590             return getAnnotationPrimitiveValue(expectedElementType, tree, env);
591         }
592 
593         if (expectedElementType.tsym == syms.classType.tsym) {
594             return getAnnotationClassValue(expectedElementType, tree, env);
595         }
596 
597         if (expectedElementType.hasTag(CLASS) &&
598                 (expectedElementType.tsym.flags() & Flags.ENUM) != 0) {
599             return getAnnotationEnumValue(expectedElementType, tree, env);
600         }
601 
602         //error recovery:
603         if (!expectedElementType.isErroneous())
604             log.error(tree.pos(), Errors.AnnotationValueNotAllowableType);
605         return new Attribute.Error(attr.attribExpr(tree, env, expectedElementType));
606     }
607 
getAnnotationEnumValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env)608     private Attribute getAnnotationEnumValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
609         Type result = attr.attribTree(tree, env, annotationValueInfo(expectedElementType));
610         Symbol sym = TreeInfo.symbol(tree);
611         if (sym == null ||
612                 TreeInfo.nonstaticSelect(tree) ||
613                 sym.kind != VAR ||
614                 (sym.flags() & Flags.ENUM) == 0) {
615             log.error(tree.pos(), Errors.EnumAnnotationMustBeEnumConstant);
616             return new Attribute.Error(result.getOriginalType());
617         }
618         VarSymbol enumerator = (VarSymbol) sym;
619         return new Attribute.Enum(expectedElementType, enumerator);
620     }
621 
getAnnotationClassValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env)622     private Attribute getAnnotationClassValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
623         Type result = attr.attribTree(tree, env, annotationValueInfo(expectedElementType));
624         if (result.isErroneous()) {
625             // Does it look like an unresolved class literal?
626             if (TreeInfo.name(tree) == names._class &&
627                     ((JCFieldAccess) tree).selected.type.isErroneous()) {
628                 Name n = (((JCFieldAccess) tree).selected).type.tsym.flatName();
629                 return new Attribute.UnresolvedClass(expectedElementType,
630                         types.createErrorType(n,
631                                 syms.unknownSymbol, syms.classType));
632             } else {
633                 return new Attribute.Error(result.getOriginalType());
634             }
635         }
636 
637         // Class literals look like field accesses of a field named class
638         // at the tree level
639         if (TreeInfo.name(tree) != names._class) {
640             log.error(tree.pos(), Errors.AnnotationValueMustBeClassLiteral);
641             return new Attribute.Error(syms.errType);
642         }
643 
644         return new Attribute.Class(types,
645                 (((JCFieldAccess) tree).selected).type);
646     }
647 
getAnnotationPrimitiveValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env)648     private Attribute getAnnotationPrimitiveValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
649         Type result = attr.attribTree(tree, env, annotationValueInfo(expectedElementType));
650         if (result.isErroneous())
651             return new Attribute.Error(result.getOriginalType());
652         if (result.constValue() == null) {
653             log.error(tree.pos(), Errors.AttributeValueMustBeConstant);
654             return new Attribute.Error(expectedElementType);
655         }
656         result = cfolder.coerce(result, expectedElementType);
657         return new Attribute.Constant(expectedElementType, result.constValue());
658     }
659 
annotationValueInfo(Type pt)660     private Attr.ResultInfo annotationValueInfo(Type pt) {
661         return attr.unknownExprInfo.dup(pt, new AnnotationValueContext(attr.unknownExprInfo.checkContext));
662     }
663 
664     class AnnotationValueContext extends Check.NestedCheckContext {
AnnotationValueContext(CheckContext enclosingContext)665         AnnotationValueContext(CheckContext enclosingContext) {
666             super(enclosingContext);
667         }
668 
669         @Override
compatible(Type found, Type req, Warner warn)670         public boolean compatible(Type found, Type req, Warner warn) {
671             //handle non-final implicitly-typed vars (will be rejected later on)
672             return found.hasTag(TypeTag.NONE) || super.compatible(found, req, warn);
673         }
674     }
675 
getAnnotationArrayValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env)676     private Attribute getAnnotationArrayValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
677         // Special case, implicit array
678         if (!tree.hasTag(NEWARRAY)) {
679             tree = make.at(tree.pos).
680                     NewArray(null, List.nil(), List.of(tree));
681         }
682 
683         JCNewArray na = (JCNewArray)tree;
684         if (na.elemtype != null) {
685             log.error(na.elemtype.pos(), Errors.NewNotAllowedInAnnotation);
686         }
687         ListBuffer<Attribute> buf = new ListBuffer<>();
688         for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
689             buf.append(attributeAnnotationValue(types.elemtype(expectedElementType),
690                     l.head,
691                     env));
692         }
693         na.type = expectedElementType;
694         return new Attribute.
695                 Array(expectedElementType, buf.toArray(new Attribute[buf.length()]));
696     }
697 
698     /* *********************************
699      * Support for repeating annotations
700      ***********************************/
701 
702     /**
703      * This context contains all the information needed to synthesize new
704      * annotations trees for repeating annotations.
705      */
706     private class AnnotationContext<T extends Attribute.Compound> {
707         public final Env<AttrContext> env;
708         public final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated;
709         public final Map<T, JCDiagnostic.DiagnosticPosition> pos;
710         public final boolean isTypeCompound;
711 
AnnotationContext(Env<AttrContext> env, Map<Symbol.TypeSymbol, ListBuffer<T>> annotated, Map<T, JCDiagnostic.DiagnosticPosition> pos, boolean isTypeCompound)712         public AnnotationContext(Env<AttrContext> env,
713                                  Map<Symbol.TypeSymbol, ListBuffer<T>> annotated,
714                                  Map<T, JCDiagnostic.DiagnosticPosition> pos,
715                                  boolean isTypeCompound) {
716             Assert.checkNonNull(env);
717             Assert.checkNonNull(annotated);
718             Assert.checkNonNull(pos);
719 
720             this.env = env;
721             this.annotated = annotated;
722             this.pos = pos;
723             this.isTypeCompound = isTypeCompound;
724         }
725     }
726 
727     /* Process repeated annotations. This method returns the
728      * synthesized container annotation or null IFF all repeating
729      * annotation are invalid.  This method reports errors/warnings.
730      */
processRepeatedAnnotations(List<T> annotations, AnnotationContext<T> ctx, Symbol on, boolean isTypeParam)731     private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations,
732             AnnotationContext<T> ctx, Symbol on, boolean isTypeParam)
733     {
734         T firstOccurrence = annotations.head;
735         List<Attribute> repeated = List.nil();
736         Type origAnnoType = null;
737         Type arrayOfOrigAnnoType = null;
738         Type targetContainerType = null;
739         MethodSymbol containerValueSymbol = null;
740 
741         Assert.check(!annotations.isEmpty() && !annotations.tail.isEmpty()); // i.e. size() > 1
742 
743         int count = 0;
744         for (List<T> al = annotations; !al.isEmpty(); al = al.tail) {
745             count++;
746 
747             // There must be more than a single anno in the annotation list
748             Assert.check(count > 1 || !al.tail.isEmpty());
749 
750             T currentAnno = al.head;
751 
752             origAnnoType = currentAnno.type;
753             if (arrayOfOrigAnnoType == null) {
754                 arrayOfOrigAnnoType = types.makeArrayType(origAnnoType);
755             }
756 
757             // Only report errors if this isn't the first occurrence I.E. count > 1
758             boolean reportError = count > 1;
759             Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno), reportError);
760             if (currentContainerType == null) {
761                 continue;
762             }
763             // Assert that the target Container is == for all repeated
764             // annos of the same annotation type, the types should
765             // come from the same Symbol, i.e. be '=='
766             Assert.check(targetContainerType == null || currentContainerType == targetContainerType);
767             targetContainerType = currentContainerType;
768 
769             containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno));
770 
771             if (containerValueSymbol == null) { // Check of CA type failed
772                 // errors are already reported
773                 continue;
774             }
775 
776             repeated = repeated.prepend(currentAnno);
777         }
778 
779         if (!repeated.isEmpty() && targetContainerType == null) {
780             log.error(ctx.pos.get(annotations.head), Errors.DuplicateAnnotationInvalidRepeated(origAnnoType));
781             return null;
782         }
783 
784         if (!repeated.isEmpty()) {
785             repeated = repeated.reverse();
786             DiagnosticPosition pos = ctx.pos.get(firstOccurrence);
787             TreeMaker m = make.at(pos);
788             Pair<MethodSymbol, Attribute> p =
789                     new Pair<MethodSymbol, Attribute>(containerValueSymbol,
790                             new Attribute.Array(arrayOfOrigAnnoType, repeated));
791             if (ctx.isTypeCompound) {
792                 /* TODO: the following code would be cleaner:
793                 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
794                         ((Attribute.TypeCompound)annotations.head).position);
795                 JCTypeAnnotation annoTree = m.TypeAnnotation(at);
796                 at = attributeTypeAnnotation(annoTree, targetContainerType, ctx.env);
797                 */
798                 // However, we directly construct the TypeCompound to keep the
799                 // direct relation to the contained TypeCompounds.
800                 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
801                         ((Attribute.TypeCompound)annotations.head).position);
802 
803                 JCAnnotation annoTree = m.TypeAnnotation(at);
804                 if (!chk.validateAnnotationDeferErrors(annoTree))
805                     log.error(annoTree.pos(), Errors.DuplicateAnnotationInvalidRepeated(origAnnoType));
806 
807                 if (!chk.isTypeAnnotation(annoTree, isTypeParam)) {
808                     log.error(pos, isTypeParam ? Errors.InvalidRepeatableAnnotationNotApplicable(targetContainerType, on)
809                                                : Errors.InvalidRepeatableAnnotationNotApplicableInContext(targetContainerType));
810                 }
811 
812                 at.setSynthesized(true);
813 
814                 @SuppressWarnings("unchecked")
815                 T x = (T) at;
816                 return x;
817             } else {
818                 Attribute.Compound c = new Attribute.Compound(targetContainerType, List.of(p));
819                 JCAnnotation annoTree = m.Annotation(c);
820 
821                 if (!chk.annotationApplicable(annoTree, on)) {
822                     log.error(annoTree.pos(),
823                               Errors.InvalidRepeatableAnnotationNotApplicable(targetContainerType, on));
824                 }
825 
826                 if (!chk.validateAnnotationDeferErrors(annoTree))
827                     log.error(annoTree.pos(), Errors.DuplicateAnnotationInvalidRepeated(origAnnoType));
828 
829                 c = attributeAnnotation(annoTree, targetContainerType, ctx.env);
830                 c.setSynthesized(true);
831 
832                 @SuppressWarnings("unchecked")
833                 T x = (T) c;
834                 return x;
835             }
836         } else {
837             return null; // errors should have been reported elsewhere
838         }
839     }
840 
841     /**
842      * Fetches the actual Type that should be the containing annotation.
843      */
getContainingType(Attribute.Compound currentAnno, DiagnosticPosition pos, boolean reportError)844     private Type getContainingType(Attribute.Compound currentAnno,
845                                    DiagnosticPosition pos,
846                                    boolean reportError)
847     {
848         Type origAnnoType = currentAnno.type;
849         TypeSymbol origAnnoDecl = origAnnoType.tsym;
850 
851         // Fetch the Repeatable annotation from the current
852         // annotation's declaration, or null if it has none
853         Attribute.Compound ca = origAnnoDecl.getAnnotationTypeMetadata().getRepeatable();
854         if (ca == null) { // has no Repeatable annotation
855             if (reportError)
856                 log.error(pos, Errors.DuplicateAnnotationMissingContainer(origAnnoType));
857             return null;
858         }
859 
860         return filterSame(extractContainingType(ca, pos, origAnnoDecl),
861                 origAnnoType);
862     }
863 
864     // returns null if t is same as 's', returns 't' otherwise
filterSame(Type t, Type s)865     private Type filterSame(Type t, Type s) {
866         if (t == null || s == null) {
867             return t;
868         }
869 
870         return types.isSameType(t, s) ? null : t;
871     }
872 
873     /** Extract the actual Type to be used for a containing annotation. */
extractContainingType(Attribute.Compound ca, DiagnosticPosition pos, TypeSymbol annoDecl)874     private Type extractContainingType(Attribute.Compound ca,
875                                        DiagnosticPosition pos,
876                                        TypeSymbol annoDecl)
877     {
878         // The next three checks check that the Repeatable annotation
879         // on the declaration of the annotation type that is repeating is
880         // valid.
881 
882         // Repeatable must have at least one element
883         if (ca.values.isEmpty()) {
884             log.error(pos, Errors.InvalidRepeatableAnnotation(annoDecl));
885             return null;
886         }
887         Pair<MethodSymbol,Attribute> p = ca.values.head;
888         Name name = p.fst.name;
889         if (name != names.value) { // should contain only one element, named "value"
890             log.error(pos, Errors.InvalidRepeatableAnnotation(annoDecl));
891             return null;
892         }
893         if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class
894             log.error(pos, Errors.InvalidRepeatableAnnotation(annoDecl));
895             return null;
896         }
897 
898         return ((Attribute.Class)p.snd).getValue();
899     }
900 
901     /* Validate that the suggested targetContainerType Type is a valid
902      * container type for repeated instances of originalAnnoType
903      * annotations. Return null and report errors if this is not the
904      * case, return the MethodSymbol of the value element in
905      * targetContainerType if it is suitable (this is needed to
906      * synthesize the container). */
validateContainer(Type targetContainerType, Type originalAnnoType, DiagnosticPosition pos)907     private MethodSymbol validateContainer(Type targetContainerType,
908                                            Type originalAnnoType,
909                                            DiagnosticPosition pos) {
910         MethodSymbol containerValueSymbol = null;
911         boolean fatalError = false;
912 
913         // Validate that there is a (and only 1) value method
914         Scope scope = targetContainerType.tsym.members();
915         int nr_value_elems = 0;
916         boolean error = false;
917         for(Symbol elm : scope.getSymbolsByName(names.value)) {
918             nr_value_elems++;
919 
920             if (nr_value_elems == 1 &&
921                     elm.kind == MTH) {
922                 containerValueSymbol = (MethodSymbol)elm;
923             } else {
924                 error = true;
925             }
926         }
927         if (error) {
928             log.error(pos,
929                       Errors.InvalidRepeatableAnnotationMultipleValues(targetContainerType,
930                                                                        nr_value_elems));
931             return null;
932         } else if (nr_value_elems == 0) {
933             log.error(pos,
934                       Errors.InvalidRepeatableAnnotationNoValue(targetContainerType));
935             return null;
936         }
937 
938         // validate that the 'value' element is a method
939         // probably "impossible" to fail this
940         if (containerValueSymbol.kind != MTH) {
941             log.error(pos,
942                     Errors.InvalidRepeatableAnnotationInvalidValue(targetContainerType));
943             fatalError = true;
944         }
945 
946         // validate that the 'value' element has the correct return type
947         // i.e. array of original anno
948         Type valueRetType = containerValueSymbol.type.getReturnType();
949         Type expectedType = types.makeArrayType(originalAnnoType);
950         if (!(types.isArray(valueRetType) &&
951                 types.isSameType(expectedType, valueRetType))) {
952             log.error(pos,
953                       Errors.InvalidRepeatableAnnotationValueReturn(targetContainerType,
954                                                                     valueRetType,
955                                                                     expectedType));
956             fatalError = true;
957         }
958 
959         return fatalError ? null : containerValueSymbol;
960     }
961 
makeContainerAnnotation(List<T> toBeReplaced, AnnotationContext<T> ctx, Symbol sym, boolean isTypeParam)962     private <T extends Attribute.Compound> T makeContainerAnnotation(List<T> toBeReplaced,
963             AnnotationContext<T> ctx, Symbol sym, boolean isTypeParam)
964     {
965         // Process repeated annotations
966         T validRepeated =
967                 processRepeatedAnnotations(toBeReplaced, ctx, sym, isTypeParam);
968 
969         if (validRepeated != null) {
970             // Check that the container isn't manually
971             // present along with repeated instances of
972             // its contained annotation.
973             ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
974             if (manualContainer != null) {
975                 log.error(ctx.pos.get(manualContainer.first()),
976                           Errors.InvalidRepeatableAnnotationRepeatedAndContainerPresent(manualContainer.first().type.tsym));
977             }
978         }
979 
980         // A null return will delete the Placeholder
981         return validRepeated;
982     }
983 
984     /********************
985      * Type annotations *
986      ********************/
987 
988     /**
989      * Attribute the list of annotations and enter them onto s.
990      */
enterTypeAnnotations(List<JCAnnotation> annotations, Env<AttrContext> env, Symbol s, DiagnosticPosition deferPos, boolean isTypeParam)991     public void enterTypeAnnotations(List<JCAnnotation> annotations, Env<AttrContext> env,
992             Symbol s, DiagnosticPosition deferPos, boolean isTypeParam)
993     {
994         Assert.checkNonNull(s, "Symbol argument to actualEnterTypeAnnotations is nul/");
995         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
996         DiagnosticPosition prevLintPos = null;
997 
998         if (deferPos != null) {
999             prevLintPos = deferredLintHandler.setPos(deferPos);
1000         }
1001         try {
1002             annotateNow(s, annotations, env, true, isTypeParam);
1003         } finally {
1004             if (prevLintPos != null)
1005                 deferredLintHandler.setPos(prevLintPos);
1006             log.useSource(prev);
1007         }
1008     }
1009 
1010     /**
1011      * Enqueue tree for scanning of type annotations, attaching to the Symbol sym.
1012      */
queueScanTreeAndTypeAnnotate(JCTree tree, Env<AttrContext> env, Symbol sym, DiagnosticPosition deferPos)1013     public void queueScanTreeAndTypeAnnotate(JCTree tree, Env<AttrContext> env, Symbol sym,
1014             DiagnosticPosition deferPos)
1015     {
1016         Assert.checkNonNull(sym);
1017         normal(() -> tree.accept(new TypeAnnotate(env, sym, deferPos)));
1018     }
1019 
1020     /**
1021      * Apply the annotations to the particular type.
1022      */
annotateTypeSecondStage(JCTree tree, List<JCAnnotation> annotations, Type storeAt)1023     public void annotateTypeSecondStage(JCTree tree, List<JCAnnotation> annotations, Type storeAt) {
1024         typeAnnotation(() -> {
1025             List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
1026             Assert.check(annotations.size() == compounds.size());
1027             storeAt.getMetadataOfKind(Kind.ANNOTATIONS).combine(new TypeMetadata.Annotations(compounds));
1028         });
1029     }
1030 
1031     /**
1032      * Apply the annotations to the particular type.
1033      */
annotateTypeParameterSecondStage(JCTree tree, List<JCAnnotation> annotations)1034     public void annotateTypeParameterSecondStage(JCTree tree, List<JCAnnotation> annotations) {
1035         typeAnnotation(() -> {
1036             List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
1037             Assert.check(annotations.size() == compounds.size());
1038         });
1039     }
1040 
1041     /**
1042      * We need to use a TreeScanner, because it is not enough to visit the top-level
1043      * annotations. We also need to visit type arguments, etc.
1044      */
1045     private class TypeAnnotate extends TreeScanner {
1046         private final Env<AttrContext> env;
1047         private final Symbol sym;
1048         private DiagnosticPosition deferPos;
1049 
TypeAnnotate(Env<AttrContext> env, Symbol sym, DiagnosticPosition deferPos)1050         public TypeAnnotate(Env<AttrContext> env, Symbol sym, DiagnosticPosition deferPos) {
1051 
1052             this.env = env;
1053             this.sym = sym;
1054             this.deferPos = deferPos;
1055         }
1056 
1057         @Override
visitAnnotatedType(JCAnnotatedType tree)1058         public void visitAnnotatedType(JCAnnotatedType tree) {
1059             enterTypeAnnotations(tree.annotations, env, sym, deferPos, false);
1060             scan(tree.underlyingType);
1061         }
1062 
1063         @Override
visitTypeParameter(JCTypeParameter tree)1064         public void visitTypeParameter(JCTypeParameter tree) {
1065             enterTypeAnnotations(tree.annotations, env, sym, deferPos, true);
1066             scan(tree.bounds);
1067         }
1068 
1069         @Override
visitNewArray(JCNewArray tree)1070         public void visitNewArray(JCNewArray tree) {
1071             enterTypeAnnotations(tree.annotations, env, sym, deferPos, false);
1072             for (List<JCAnnotation> dimAnnos : tree.dimAnnotations)
1073                 enterTypeAnnotations(dimAnnos, env, sym, deferPos, false);
1074             scan(tree.elemtype);
1075             scan(tree.elems);
1076         }
1077 
1078         @Override
visitMethodDef(JCMethodDecl tree)1079         public void visitMethodDef(JCMethodDecl tree) {
1080             scan(tree.mods);
1081             scan(tree.restype);
1082             scan(tree.typarams);
1083             scan(tree.recvparam);
1084             scan(tree.params);
1085             scan(tree.thrown);
1086             scan(tree.defaultValue);
1087             // Do not annotate the body, just the signature.
1088         }
1089 
1090         @Override
visitVarDef(JCVariableDecl tree)1091         public void visitVarDef(JCVariableDecl tree) {
1092             DiagnosticPosition prevPos = deferPos;
1093             deferPos = tree.pos();
1094             try {
1095                 if (sym != null && sym.kind == VAR) {
1096                     // Don't visit a parameter once when the sym is the method
1097                     // and once when the sym is the parameter.
1098                     scan(tree.mods);
1099                     scan(tree.vartype);
1100                 }
1101                 scan(tree.init);
1102             } finally {
1103                 deferPos = prevPos;
1104             }
1105         }
1106 
1107         @Override
visitClassDef(JCClassDecl tree)1108         public void visitClassDef(JCClassDecl tree) {
1109             // We can only hit a classdef if it is declared within
1110             // a method. Ignore it - the class will be visited
1111             // separately later.
1112         }
1113 
1114         @Override
visitNewClass(JCNewClass tree)1115         public void visitNewClass(JCNewClass tree) {
1116             scan(tree.encl);
1117             scan(tree.typeargs);
1118             scan(tree.clazz);
1119             scan(tree.args);
1120             // the anonymous class instantiation if any will be visited separately.
1121         }
1122     }
1123 
1124     /*********************
1125      * Completer support *
1126      *********************/
1127 
1128     private AnnotationTypeCompleter theSourceCompleter = new AnnotationTypeCompleter() {
1129         @Override
1130         public void complete(ClassSymbol sym) throws CompletionFailure {
1131             Env<AttrContext> context = typeEnvs.get(sym);
1132             Annotate.this.attributeAnnotationType(context);
1133         }
1134     };
1135 
1136     /* Last stage completer to enter just enough annotations to have a prototype annotation type.
1137      * This currently means entering @Target and @Repetable.
1138      */
annotationTypeSourceCompleter()1139     public AnnotationTypeCompleter annotationTypeSourceCompleter() {
1140         return theSourceCompleter;
1141     }
1142 
attributeAnnotationType(Env<AttrContext> env)1143     private void attributeAnnotationType(Env<AttrContext> env) {
1144         Assert.check(((JCClassDecl)env.tree).sym.isAnnotationType(),
1145                 "Trying to annotation type complete a non-annotation type");
1146 
1147         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
1148         try {
1149             JCClassDecl tree = (JCClassDecl)env.tree;
1150             AnnotationTypeVisitor v = new AnnotationTypeVisitor(attr, chk, syms, typeEnvs);
1151             v.scanAnnotationType(tree);
1152             tree.sym.getAnnotationTypeMetadata().setRepeatable(v.repeatable);
1153             tree.sym.getAnnotationTypeMetadata().setTarget(v.target);
1154         } finally {
1155             log.useSource(prev);
1156         }
1157     }
1158 
unfinishedDefaultValue()1159     public Attribute unfinishedDefaultValue() {
1160         return theUnfinishedDefaultValue;
1161     }
1162 
1163     public static interface AnnotationTypeCompleter {
complete(ClassSymbol sym)1164         void complete(ClassSymbol sym) throws CompletionFailure;
1165     }
1166 
1167     /** Visitor to determine a prototype annotation type for a class declaring an annotation type.
1168      *
1169      *  <p><b>This is NOT part of any supported API.
1170      *  If you write code that depends on this, you do so at your own risk.
1171      *  This code and its internal interfaces are subject to change or
1172      *  deletion without notice.</b>
1173      */
1174     public class AnnotationTypeVisitor extends TreeScanner {
1175         private Env<AttrContext> env;
1176 
1177         private final Attr attr;
1178         private final Check check;
1179         private final Symtab tab;
1180         private final TypeEnvs typeEnvs;
1181 
1182         private Compound target;
1183         private Compound repeatable;
1184 
AnnotationTypeVisitor(Attr attr, Check check, Symtab tab, TypeEnvs typeEnvs)1185         public AnnotationTypeVisitor(Attr attr, Check check, Symtab tab, TypeEnvs typeEnvs) {
1186             this.attr = attr;
1187             this.check = check;
1188             this.tab = tab;
1189             this.typeEnvs = typeEnvs;
1190         }
1191 
getRepeatable()1192         public Compound getRepeatable() {
1193             return repeatable;
1194         }
1195 
getTarget()1196         public Compound getTarget() {
1197             return target;
1198         }
1199 
scanAnnotationType(JCClassDecl decl)1200         public void scanAnnotationType(JCClassDecl decl) {
1201             visitClassDef(decl);
1202         }
1203 
1204         @Override
visitClassDef(JCClassDecl tree)1205         public void visitClassDef(JCClassDecl tree) {
1206             Env<AttrContext> prevEnv = env;
1207             env = typeEnvs.get(tree.sym);
1208             try {
1209                 scan(tree.mods); // look for repeatable and target
1210                 // don't descend into body
1211             } finally {
1212                 env = prevEnv;
1213             }
1214         }
1215 
1216         @Override
visitAnnotation(JCAnnotation tree)1217         public void visitAnnotation(JCAnnotation tree) {
1218             Type t = tree.annotationType.type;
1219             if (t == null) {
1220                 t = attr.attribType(tree.annotationType, env);
1221                 tree.annotationType.type = t = check.checkType(tree.annotationType.pos(), t, tab.annotationType);
1222             }
1223 
1224             if (t == tab.annotationTargetType) {
1225                 target = Annotate.this.attributeAnnotation(tree, tab.annotationTargetType, env);
1226             } else if (t == tab.repeatableType) {
1227                 repeatable = Annotate.this.attributeAnnotation(tree, tab.repeatableType, env);
1228             }
1229         }
1230     }
1231 
1232     /** Represents the semantics of an Annotation Type.
1233      *
1234      *  <p><b>This is NOT part of any supported API.
1235      *  If you write code that depends on this, you do so at your own risk.
1236      *  This code and its internal interfaces are subject to change or
1237      *  deletion without notice.</b>
1238      */
1239     public static class AnnotationTypeMetadata {
1240         final ClassSymbol metaDataFor;
1241         private Compound target;
1242         private Compound repeatable;
1243         private AnnotationTypeCompleter annotationTypeCompleter;
1244 
AnnotationTypeMetadata(ClassSymbol metaDataFor, AnnotationTypeCompleter annotationTypeCompleter)1245         public AnnotationTypeMetadata(ClassSymbol metaDataFor, AnnotationTypeCompleter annotationTypeCompleter) {
1246             this.metaDataFor = metaDataFor;
1247             this.annotationTypeCompleter = annotationTypeCompleter;
1248         }
1249 
init()1250         private void init() {
1251             // Make sure metaDataFor is member entered
1252             while (!metaDataFor.isCompleted())
1253                 metaDataFor.complete();
1254 
1255             if (annotationTypeCompleter != null) {
1256                 AnnotationTypeCompleter c = annotationTypeCompleter;
1257                 annotationTypeCompleter = null;
1258                 c.complete(metaDataFor);
1259             }
1260         }
1261 
complete()1262         public void complete() {
1263             init();
1264         }
1265 
getRepeatable()1266         public Compound getRepeatable() {
1267             init();
1268             return repeatable;
1269         }
1270 
setRepeatable(Compound repeatable)1271         public void setRepeatable(Compound repeatable) {
1272             Assert.checkNull(this.repeatable);
1273             this.repeatable = repeatable;
1274         }
1275 
getTarget()1276         public Compound getTarget() {
1277             init();
1278             return target;
1279         }
1280 
setTarget(Compound target)1281         public void setTarget(Compound target) {
1282             Assert.checkNull(this.target);
1283                 this.target = target;
1284         }
1285 
getAnnotationElements()1286         public Set<MethodSymbol> getAnnotationElements() {
1287             init();
1288             Set<MethodSymbol> members = new LinkedHashSet<>();
1289             WriteableScope s = metaDataFor.members();
1290             Iterable<Symbol> ss = s.getSymbols(NON_RECURSIVE);
1291             for (Symbol sym : ss)
1292                 if (sym.kind == MTH &&
1293                         sym.name != sym.name.table.names.clinit &&
1294                         (sym.flags() & SYNTHETIC) == 0)
1295                     members.add((MethodSymbol)sym);
1296             return members;
1297         }
1298 
getAnnotationElementsWithDefault()1299         public Set<MethodSymbol> getAnnotationElementsWithDefault() {
1300             init();
1301             Set<MethodSymbol> members = getAnnotationElements();
1302             Set<MethodSymbol> res = new LinkedHashSet<>();
1303             for (MethodSymbol m : members)
1304                 if (m.defaultValue != null)
1305                     res.add(m);
1306             return res;
1307         }
1308 
1309         @Override
toString()1310         public String toString() {
1311             return "Annotation type for: " + metaDataFor;
1312         }
1313 
isMetadataForAnnotationType()1314         public boolean isMetadataForAnnotationType() { return true; }
1315 
notAnAnnotationType()1316         public static AnnotationTypeMetadata notAnAnnotationType() {
1317             return NOT_AN_ANNOTATION_TYPE;
1318         }
1319 
1320         private static final AnnotationTypeMetadata NOT_AN_ANNOTATION_TYPE =
1321                 new AnnotationTypeMetadata(null, null) {
1322                     @Override
1323                     public void complete() {
1324                     } // do nothing
1325 
1326                     @Override
1327                     public String toString() {
1328                         return "Not an annotation type";
1329                     }
1330 
1331                     @Override
1332                     public Set<MethodSymbol> getAnnotationElements() {
1333                         return new LinkedHashSet<>(0);
1334                     }
1335 
1336                     @Override
1337                     public Set<MethodSymbol> getAnnotationElementsWithDefault() {
1338                         return new LinkedHashSet<>(0);
1339                     }
1340 
1341                     @Override
1342                     public boolean isMetadataForAnnotationType() {
1343                         return false;
1344                     }
1345 
1346                     @Override
1347                     public Compound getTarget() {
1348                         return null;
1349                     }
1350 
1351                     @Override
1352                     public Compound getRepeatable() {
1353                         return null;
1354                     }
1355                 };
1356     }
1357 
newRound()1358     public void newRound() {
1359         blockCount = 1;
1360     }
1361 }
1362