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