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