src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java
author Dusan Balek <dbalek@netbeans.org>
Fri, 22 Sep 2017 16:50:49 +0200
changeset 5963 9cc61f487a6d
parent 5961 740e1ee04027
permissions -rw-r--r--
Issue #269467 - Editor does not show error with code that does not compile - 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) {
   467             if (!args.head.hasTag(ASSIGN)) {
   468                 args.head = make.at(Position.NOPOS).
   469                         Assign(make.Ident(names.value), args.head);
   470                 elidedValue = true;
   471             } else if (args.head.pos == Position.NOPOS) {
   472                 elidedValue = true;
   473             }
   474         }
   475 
   476         ListBuffer<Pair<MethodSymbol,Attribute>> buf = new ListBuffer<>();
   477         for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) {
   478             Pair<MethodSymbol, Attribute> p = attributeAnnotationNameValuePair(tl.head, a.type, isError, env, elidedValue);
   479             if (p != null && !p.fst.type.isErroneous())
   480                 buf.append(p);
   481         }
   482         return buf.toList();
   483     }
   484 
   485     // where
   486     private Pair<MethodSymbol, Attribute> attributeAnnotationNameValuePair(JCExpression nameValuePair,
   487             Type thisAnnotationType, boolean badAnnotation, Env<AttrContext> env, boolean elidedValue)
   488     {
   489         if (!nameValuePair.hasTag(ASSIGN)) {
   490             log.error(nameValuePair.pos(), "annotation.value.must.be.name.value");
   491             attributeAnnotationValue(nameValuePair.type = syms.errType, nameValuePair, env);
   492             return null;
   493         }
   494         JCAssign assign = (JCAssign)nameValuePair;
   495         if (!assign.lhs.hasTag(IDENT)) {
   496             log.error(nameValuePair.pos(), "annotation.value.must.be.name.value");
   497             attributeAnnotationValue(nameValuePair.type = syms.errType, nameValuePair, env);
   498             return null;
   499         }
   500 
   501         // Resolve element to MethodSym
   502         JCIdent left = (JCIdent)assign.lhs;
   503         Symbol method = resolve.resolveQualifiedMethod(elidedValue ? assign.rhs.pos() : left.pos(),
   504                 env, thisAnnotationType,
   505                 left.name, List.nil(), null);
   506         left.sym = method;
   507         left.type = method.type;
   508         if (method.owner != thisAnnotationType.tsym && !badAnnotation)
   509             log.error(left.pos(), "no.annotation.member", left.name, thisAnnotationType);
   510         Type resultType = method.type.getReturnType();
   511 
   512         // Compute value part
   513         Attribute value = attributeAnnotationValue(resultType, assign.rhs, env);
   514         nameValuePair.type = resultType;
   515 
   516         return method.type.isErroneous() ? null : new Pair<>((MethodSymbol)method, value);
   517 
   518     }
   519 
   520     /** Attribute an annotation element value */
   521     private Attribute attributeAnnotationValue(Type expectedElementType, JCExpression tree,
   522             Env<AttrContext> env)
   523     {
   524         //first, try completing the symbol for the annotation value - if acompletion
   525         //error is thrown, we should recover gracefully, and display an
   526         //ordinary resolution diagnostic.
   527         try {
   528             expectedElementType.tsym.complete();
   529         } catch(CompletionFailure e) {
   530             log.error(tree.pos(), "cant.resolve", Kinds.kindName(e.sym), e.sym);
   531             expectedElementType = syms.errType;
   532         }
   533 
   534         if (expectedElementType.hasTag(ARRAY)) {
   535             return getAnnotationArrayValue(expectedElementType, tree, env);
   536 
   537         }
   538 
   539         //error recovery
   540         if (tree.hasTag(NEWARRAY)) {
   541             if (!expectedElementType.isErroneous())
   542                 log.error(tree.pos(), "annotation.value.not.allowable.type");
   543             JCNewArray na = (JCNewArray)tree;
   544             if (na.elemtype != null) {
   545                 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
   546             }
   547             for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
   548                 attributeAnnotationValue(syms.errType,
   549                         l.head,
   550                         env);
   551             }
   552             return new Attribute.Error(syms.errType);
   553         }
   554 
   555         if (expectedElementType.tsym.isAnnotationType()) {
   556             if (tree.hasTag(ANNOTATION)) {
   557                 return attributeAnnotation((JCAnnotation)tree, expectedElementType, env);
   558             } else {
   559                 log.error(tree.pos(), "annotation.value.must.be.annotation");
   560                 expectedElementType = syms.errType;
   561             }
   562         }
   563 
   564         //error recovery
   565         if (tree.hasTag(ANNOTATION)) {
   566             if (!expectedElementType.isErroneous())
   567                 log.error(tree.pos(), "annotation.not.valid.for.type", expectedElementType);
   568             attributeAnnotation((JCAnnotation)tree, syms.errType, env);
   569             return new Attribute.Error(((JCAnnotation)tree).annotationType.type);
   570         }
   571 
   572         if (expectedElementType.isPrimitive() ||
   573                 (types.isSameType(expectedElementType, syms.stringType) && !expectedElementType.hasTag(TypeTag.ERROR))) {
   574             return getAnnotationPrimitiveValue(expectedElementType, tree, env);
   575         }
   576 
   577         if (expectedElementType.tsym == syms.classType.tsym) {
   578             return getAnnotationClassValue(expectedElementType, tree, env);
   579         }
   580 
   581         if (expectedElementType.hasTag(CLASS) &&
   582                 (expectedElementType.tsym.flags() & Flags.ENUM) != 0) {
   583             return getAnnotationEnumValue(expectedElementType, tree, env);
   584         }
   585 
   586         //error recovery:
   587         if (!expectedElementType.isErroneous())
   588             log.error(tree.pos(), "annotation.value.not.allowable.type");
   589         return new Attribute.Error(attr.attribExpr(tree, env, expectedElementType));
   590     }
   591 
   592     private Attribute getAnnotationEnumValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
   593         Type result = attr.attribExpr(tree, env, expectedElementType);
   594         Symbol sym = TreeInfo.symbol(tree);
   595         if (sym == null ||
   596                 TreeInfo.nonstaticSelect(tree) ||
   597                 sym.kind != VAR ||
   598                 (sym.flags() & Flags.ENUM) == 0) {
   599             log.error(tree.pos(), "enum.annotation.must.be.enum.constant");
   600             return new Attribute.Error(result.getOriginalType());
   601         }
   602         VarSymbol enumerator = (VarSymbol) sym;
   603         return new Attribute.Enum(expectedElementType, enumerator);
   604     }
   605 
   606     private Attribute getAnnotationClassValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
   607         Type result = attr.attribExpr(tree, env, expectedElementType);
   608         if (result.isErroneous()) {
   609             // Does it look like an unresolved class literal?
   610             if (TreeInfo.name(tree) == names._class &&
   611                     ((JCFieldAccess) tree).selected.type.isErroneous()) {
   612                 Name n = (((JCFieldAccess) tree).selected).type.tsym.flatName();
   613                 return new Attribute.UnresolvedClass(expectedElementType,
   614                         types.createErrorType(n,
   615                                 syms.unknownSymbol, syms.classType));
   616             } else {
   617                 return new Attribute.Error(result.getOriginalType());
   618             }
   619         }
   620 
   621         // Class literals look like field accesses of a field named class
   622         // at the tree level
   623         if (TreeInfo.name(tree) != names._class) {
   624             log.error(tree.pos(), "annotation.value.must.be.class.literal");
   625             return new Attribute.Error(syms.errType);
   626         }
   627         return new Attribute.Class(types,
   628                 (((JCFieldAccess) tree).selected).type);
   629     }
   630 
   631     private Attribute getAnnotationPrimitiveValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
   632         Type result = attr.attribExpr(tree, env, expectedElementType);
   633         if (result.isErroneous())
   634             return new Attribute.Error(result.getOriginalType());
   635         if (result.constValue() == null) {
   636             log.error(tree.pos(), "attribute.value.must.be.constant");
   637             return new Attribute.Error(expectedElementType);
   638         }
   639         result = cfolder.coerce(result, expectedElementType);
   640         return new Attribute.Constant(expectedElementType, result.constValue());
   641     }
   642 
   643     private Attribute getAnnotationArrayValue(Type expectedElementType, JCExpression tree, Env<AttrContext> env) {
   644         // Special case, implicit array
   645         if (!tree.hasTag(NEWARRAY)) {
   646             tree = make.at(tree.pos).
   647                     NewArray(null, List.nil(), List.of(tree));
   648         }
   649 
   650         JCNewArray na = (JCNewArray)tree;
   651         if (na.elemtype != null) {
   652             log.error(na.elemtype.pos(), "new.not.allowed.in.annotation");
   653         }
   654         ListBuffer<Attribute> buf = new ListBuffer<>();
   655         if (na.elems != null) {
   656             for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) {
   657                 buf.append(attributeAnnotationValue(types.elemtype(expectedElementType),
   658                         l.head,
   659                         env));
   660             }
   661         }
   662         na.type = expectedElementType;
   663         return new Attribute.
   664                 Array(expectedElementType, buf.toArray(new Attribute[buf.length()]));
   665     }
   666 
   667     /* *********************************
   668      * Support for repeating annotations
   669      ***********************************/
   670 
   671     /**
   672      * This context contains all the information needed to synthesize new
   673      * annotations trees for repeating annotations.
   674      */
   675     private class AnnotationContext<T extends Attribute.Compound> {
   676         public final Env<AttrContext> env;
   677         public final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated;
   678         public final Map<T, JCDiagnostic.DiagnosticPosition> pos;
   679         public final boolean isTypeCompound;
   680 
   681         public AnnotationContext(Env<AttrContext> env,
   682                                  Map<Symbol.TypeSymbol, ListBuffer<T>> annotated,
   683                                  Map<T, JCDiagnostic.DiagnosticPosition> pos,
   684                                  boolean isTypeCompound) {
   685             Assert.checkNonNull(env);
   686             Assert.checkNonNull(annotated);
   687             Assert.checkNonNull(pos);
   688 
   689             this.env = env;
   690             this.annotated = annotated;
   691             this.pos = pos;
   692             this.isTypeCompound = isTypeCompound;
   693         }
   694     }
   695 
   696     /* Process repeated annotations. This method returns the
   697      * synthesized container annotation or null IFF all repeating
   698      * annotation are invalid.  This method reports errors/warnings.
   699      */
   700     private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations,
   701             AnnotationContext<T> ctx, Symbol on, boolean isTypeParam)
   702     {
   703         T firstOccurrence = annotations.head;
   704         List<Attribute> repeated = List.nil();
   705         Type origAnnoType = null;
   706         Type arrayOfOrigAnnoType = null;
   707         Type targetContainerType = null;
   708         MethodSymbol containerValueSymbol = null;
   709 
   710         Assert.check(!annotations.isEmpty() && !annotations.tail.isEmpty()); // i.e. size() > 1
   711 
   712         int count = 0;
   713         for (List<T> al = annotations; !al.isEmpty(); al = al.tail) {
   714             count++;
   715 
   716             // There must be more than a single anno in the annotation list
   717             Assert.check(count > 1 || !al.tail.isEmpty());
   718 
   719             T currentAnno = al.head;
   720 
   721             origAnnoType = currentAnno.type;
   722             if (arrayOfOrigAnnoType == null) {
   723                 arrayOfOrigAnnoType = types.makeArrayType(origAnnoType);
   724             }
   725 
   726             // Only report errors if this isn't the first occurrence I.E. count > 1
   727             boolean reportError = count > 1;
   728             Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno), reportError);
   729             if (currentContainerType == null) {
   730                 continue;
   731             }
   732             // Assert that the target Container is == for all repeated
   733             // annos of the same annotation type, the types should
   734             // come from the same Symbol, i.e. be '=='
   735             Assert.check(targetContainerType == null || currentContainerType == targetContainerType);
   736             targetContainerType = currentContainerType;
   737 
   738             containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno));
   739 
   740             if (containerValueSymbol == null) { // Check of CA type failed
   741                 // errors are already reported
   742                 continue;
   743             }
   744 
   745             repeated = repeated.prepend(currentAnno);
   746         }
   747 
   748         if (!repeated.isEmpty() && targetContainerType == null) {
   749             log.error(ctx.pos.get(annotations.head), "duplicate.annotation.invalid.repeated", origAnnoType);
   750             return null;
   751         }
   752 
   753         if (!repeated.isEmpty()) {
   754             repeated = repeated.reverse();
   755             DiagnosticPosition pos = ctx.pos.get(firstOccurrence);
   756             TreeMaker m = make.at(pos);
   757             Pair<MethodSymbol, Attribute> p =
   758                     new Pair<MethodSymbol, Attribute>(containerValueSymbol,
   759                             new Attribute.Array(arrayOfOrigAnnoType, repeated));
   760             if (ctx.isTypeCompound) {
   761                 /* TODO: the following code would be cleaner:
   762                 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
   763                         ((Attribute.TypeCompound)annotations.head).position);
   764                 JCTypeAnnotation annoTree = m.TypeAnnotation(at);
   765                 at = attributeTypeAnnotation(annoTree, targetContainerType, ctx.env);
   766                 */
   767                 // However, we directly construct the TypeCompound to keep the
   768                 // direct relation to the contained TypeCompounds.
   769                 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p),
   770                         ((Attribute.TypeCompound)annotations.head).position);
   771 
   772                 JCAnnotation annoTree = m.TypeAnnotation(at);
   773                 if (!chk.validateAnnotationDeferErrors(annoTree))
   774                     log.error(annoTree.pos(), Errors.DuplicateAnnotationInvalidRepeated(origAnnoType));
   775 
   776                 if (!chk.isTypeAnnotation(annoTree, isTypeParam)) {
   777                     log.error(pos, isTypeParam ? Errors.InvalidRepeatableAnnotationNotApplicable(targetContainerType, on)
   778                                                : Errors.InvalidRepeatableAnnotationNotApplicableInContext(targetContainerType));
   779                 }
   780 
   781                 at.setSynthesized(true);
   782 
   783                 @SuppressWarnings("unchecked")
   784                 T x = (T) at;
   785                 return x;
   786             } else {
   787                 Attribute.Compound c = new Attribute.Compound(targetContainerType, List.of(p));
   788                 JCAnnotation annoTree = m.Annotation(c);
   789 
   790                 if (!chk.annotationApplicable(annoTree, on)) {
   791                     log.error(annoTree.pos(),
   792                               Errors.InvalidRepeatableAnnotationNotApplicable(targetContainerType, on));
   793                 }
   794 
   795                 if (!chk.validateAnnotationDeferErrors(annoTree))
   796                     log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType);
   797 
   798                 c = attributeAnnotation(annoTree, targetContainerType, ctx.env);
   799                 c.setSynthesized(true);
   800 
   801                 @SuppressWarnings("unchecked")
   802                 T x = (T) c;
   803                 return x;
   804             }
   805         } else {
   806             return null; // errors should have been reported elsewhere
   807         }
   808     }
   809 
   810     /**
   811      * Fetches the actual Type that should be the containing annotation.
   812      */
   813     private Type getContainingType(Attribute.Compound currentAnno,
   814                                    DiagnosticPosition pos,
   815                                    boolean reportError)
   816     {
   817         Type origAnnoType = currentAnno.type;
   818         TypeSymbol origAnnoDecl = origAnnoType.tsym;
   819 
   820         // Fetch the Repeatable annotation from the current
   821         // annotation's declaration, or null if it has none
   822         Attribute.Compound ca = origAnnoDecl.getAnnotationTypeMetadata().getRepeatable();
   823         if (ca == null) { // has no Repeatable annotation
   824             if (reportError)
   825                 log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType);
   826             return null;
   827         }
   828 
   829         return filterSame(extractContainingType(ca, pos, origAnnoDecl),
   830                 origAnnoType);
   831     }
   832 
   833     // returns null if t is same as 's', returns 't' otherwise
   834     private Type filterSame(Type t, Type s) {
   835         if (t == null || s == null) {
   836             return t;
   837         }
   838 
   839         return types.isSameType(t, s) ? null : t;
   840     }
   841 
   842     /** Extract the actual Type to be used for a containing annotation. */
   843     private Type extractContainingType(Attribute.Compound ca,
   844                                        DiagnosticPosition pos,
   845                                        TypeSymbol annoDecl)
   846     {
   847         // The next three checks check that the Repeatable annotation
   848         // on the declaration of the annotation type that is repeating is
   849         // valid.
   850 
   851         // Repeatable must have at least one element
   852         if (ca.values.isEmpty()) {
   853             log.error(pos, "invalid.repeatable.annotation", annoDecl);
   854             return null;
   855         }
   856         Pair<MethodSymbol,Attribute> p = ca.values.head;
   857         Name name = p.fst.name;
   858         if (name != names.value) { // should contain only one element, named "value"
   859             log.error(pos, "invalid.repeatable.annotation", annoDecl);
   860             return null;
   861         }
   862         if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class
   863             log.error(pos, "invalid.repeatable.annotation", annoDecl);
   864             return null;
   865         }
   866 
   867         return ((Attribute.Class)p.snd).getValue();
   868     }
   869 
   870     /* Validate that the suggested targetContainerType Type is a valid
   871      * container type for repeated instances of originalAnnoType
   872      * annotations. Return null and report errors if this is not the
   873      * case, return the MethodSymbol of the value element in
   874      * targetContainerType if it is suitable (this is needed to
   875      * synthesize the container). */
   876     private MethodSymbol validateContainer(Type targetContainerType,
   877                                            Type originalAnnoType,
   878                                            DiagnosticPosition pos) {
   879         MethodSymbol containerValueSymbol = null;
   880         boolean fatalError = false;
   881 
   882         // Validate that there is a (and only 1) value method
   883         Scope scope = targetContainerType.tsym.members();
   884         int nr_value_elems = 0;
   885         boolean error = false;
   886         for(Symbol elm : scope.getSymbolsByName(names.value)) {
   887             nr_value_elems++;
   888 
   889             if (nr_value_elems == 1 &&
   890                     elm.kind == MTH) {
   891                 containerValueSymbol = (MethodSymbol)elm;
   892             } else {
   893                 error = true;
   894             }
   895         }
   896         if (error) {
   897             log.error(pos,
   898                     "invalid.repeatable.annotation.multiple.values",
   899                     targetContainerType,
   900                     nr_value_elems);
   901             return null;
   902         } else if (nr_value_elems == 0) {
   903             log.error(pos,
   904                     "invalid.repeatable.annotation.no.value",
   905                     targetContainerType);
   906             return null;
   907         }
   908 
   909         // validate that the 'value' element is a method
   910         // probably "impossible" to fail this
   911         if (containerValueSymbol.kind != MTH) {
   912             log.error(pos,
   913                     "invalid.repeatable.annotation.invalid.value",
   914                     targetContainerType);
   915             fatalError = true;
   916         }
   917 
   918         // validate that the 'value' element has the correct return type
   919         // i.e. array of original anno
   920         Type valueRetType = containerValueSymbol.type.getReturnType();
   921         Type expectedType = types.makeArrayType(originalAnnoType);
   922         if (!(types.isArray(valueRetType) &&
   923                 types.isSameType(expectedType, valueRetType))) {
   924             log.error(pos,
   925                     "invalid.repeatable.annotation.value.return",
   926                     targetContainerType,
   927                     valueRetType,
   928                     expectedType);
   929             fatalError = true;
   930         }
   931 
   932         return fatalError ? null : containerValueSymbol;
   933     }
   934 
   935     private <T extends Attribute.Compound> T makeContainerAnnotation(List<T> toBeReplaced,
   936             AnnotationContext<T> ctx, Symbol sym, boolean isTypeParam)
   937     {
   938         // Process repeated annotations
   939         T validRepeated =
   940                 processRepeatedAnnotations(toBeReplaced, ctx, sym, isTypeParam);
   941 
   942         if (validRepeated != null) {
   943             // Check that the container isn't manually
   944             // present along with repeated instances of
   945             // its contained annotation.
   946             ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
   947             if (manualContainer != null) {
   948                 log.error(ctx.pos.get(manualContainer.first()),
   949                         "invalid.repeatable.annotation.repeated.and.container.present",
   950                         manualContainer.first().type.tsym);
   951             }
   952         }
   953 
   954         // A null return will delete the Placeholder
   955         return validRepeated;
   956     }
   957 
   958     /********************
   959      * Type annotations *
   960      ********************/
   961 
   962     /**
   963      * Attribute the list of annotations and enter them onto s.
   964      */
   965     public void enterTypeAnnotations(List<JCAnnotation> annotations, Env<AttrContext> env,
   966             Symbol s, DiagnosticPosition deferPos, boolean isTypeParam)
   967     {
   968         Assert.checkNonNull(s, "Symbol argument to actualEnterTypeAnnotations is nul/");
   969         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
   970         DiagnosticPosition prevLintPos = null;
   971 
   972         if (deferPos != null) {
   973             prevLintPos = deferredLintHandler.setPos(deferPos);
   974         }
   975         try {
   976             annotateNow(s, annotations, env, true, isTypeParam);
   977         } finally {
   978             if (prevLintPos != null)
   979                 deferredLintHandler.setPos(prevLintPos);
   980             log.useSource(prev);
   981         }
   982     }
   983 
   984     /**
   985      * Enqueue tree for scanning of type annotations, attaching to the Symbol sym.
   986      */
   987     public void queueScanTreeAndTypeAnnotate(JCTree tree, Env<AttrContext> env, Symbol sym,
   988             DiagnosticPosition deferPos)
   989     {
   990         Assert.checkNonNull(sym);
   991         normal(() -> tree.accept(new TypeAnnotate(env, sym, deferPos)));
   992     }
   993 
   994     /**
   995      * Apply the annotations to the particular type.
   996      */
   997     public void annotateTypeSecondStage(JCTree tree, List<JCAnnotation> annotations, Type storeAt) {
   998         typeAnnotation(() -> {
   999             List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
  1000             Assert.check(annotations.size() == compounds.size());
  1001             storeAt.getMetadataOfKind(Kind.ANNOTATIONS).combine(new TypeMetadata.Annotations(compounds));
  1002         });
  1003     }
  1004 
  1005     /**
  1006      * Apply the annotations to the particular type.
  1007      */
  1008     public void annotateTypeParameterSecondStage(JCTree tree, List<JCAnnotation> annotations) {
  1009         typeAnnotation(() -> {
  1010             List<Attribute.TypeCompound> compounds = fromAnnotations(annotations);
  1011             Assert.check(annotations.size() == compounds.size());
  1012         });
  1013     }
  1014 
  1015     /**
  1016      * We need to use a TreeScanner, because it is not enough to visit the top-level
  1017      * annotations. We also need to visit type arguments, etc.
  1018      */
  1019     private class TypeAnnotate extends TreeScanner {
  1020         private final Env<AttrContext> env;
  1021         private final Symbol sym;
  1022         private DiagnosticPosition deferPos;
  1023 
  1024         public TypeAnnotate(Env<AttrContext> env, Symbol sym, DiagnosticPosition deferPos) {
  1025 
  1026             this.env = env;
  1027             this.sym = sym;
  1028             this.deferPos = deferPos;
  1029         }
  1030 
  1031         @Override
  1032         public void visitAnnotatedType(JCAnnotatedType tree) {
  1033             enterTypeAnnotations(tree.annotations, env, sym, deferPos, false);
  1034             scan(tree.underlyingType);
  1035         }
  1036 
  1037         @Override
  1038         public void visitTypeParameter(JCTypeParameter tree) {
  1039             enterTypeAnnotations(tree.annotations, env, sym, deferPos, true);
  1040             scan(tree.bounds);
  1041         }
  1042 
  1043         @Override
  1044         public void visitNewArray(JCNewArray tree) {
  1045             enterTypeAnnotations(tree.annotations, env, sym, deferPos, false);
  1046             for (List<JCAnnotation> dimAnnos : tree.dimAnnotations)
  1047                 enterTypeAnnotations(dimAnnos, env, sym, deferPos, false);
  1048             scan(tree.elemtype);
  1049             scan(tree.elems);
  1050         }
  1051 
  1052         @Override
  1053         public void visitMethodDef(JCMethodDecl tree) {
  1054             scan(tree.mods);
  1055             scan(tree.restype);
  1056             scan(tree.typarams);
  1057             scan(tree.recvparam);
  1058             scan(tree.params);
  1059             scan(tree.thrown);
  1060             scan(tree.defaultValue);
  1061             // Do not annotate the body, just the signature.
  1062         }
  1063 
  1064         @Override
  1065         public void visitVarDef(JCVariableDecl tree) {
  1066             DiagnosticPosition prevPos = deferPos;
  1067             deferPos = tree.pos();
  1068             try {
  1069                 if (sym != null && sym.kind == VAR) {
  1070                     // Don't visit a parameter once when the sym is the method
  1071                     // and once when the sym is the parameter.
  1072                     scan(tree.mods);
  1073                     scan(tree.vartype);
  1074                 }
  1075                 scan(tree.init);
  1076             } finally {
  1077                 deferPos = prevPos;
  1078             }
  1079         }
  1080 
  1081         @Override
  1082         public void visitClassDef(JCClassDecl tree) {
  1083             // We can only hit a classdef if it is declared within
  1084             // a method. Ignore it - the class will be visited
  1085             // separately later.
  1086         }
  1087 
  1088         @Override
  1089         public void visitNewClass(JCNewClass tree) {
  1090             scan(tree.encl);
  1091             scan(tree.typeargs);
  1092             scan(tree.clazz);
  1093             scan(tree.args);
  1094             // the anonymous class instantiation if any will be visited separately.
  1095         }
  1096 
  1097         @Override
  1098         public void visitErroneous(JCErroneous tree) {
  1099             scan(tree.errs);
  1100         }
  1101     }
  1102 
  1103     /*********************
  1104      * Completer support *
  1105      *********************/
  1106 
  1107     private AnnotationTypeCompleter theSourceCompleter = new AnnotationTypeCompleter() {
  1108         @Override
  1109         public void complete(ClassSymbol sym) throws CompletionFailure {
  1110             Env<AttrContext> context = typeEnvs.get(sym);
  1111             Annotate.this.attributeAnnotationType(context);
  1112         }
  1113     };
  1114 
  1115     /* Last stage completer to enter just enough annotations to have a prototype annotation type.
  1116      * This currently means entering @Target and @Repetable.
  1117      */
  1118     public AnnotationTypeCompleter annotationTypeSourceCompleter() {
  1119         return theSourceCompleter;
  1120     }
  1121 
  1122     private void attributeAnnotationType(Env<AttrContext> env) {
  1123         Assert.check(((JCClassDecl)env.tree).sym.isAnnotationType(),
  1124                 "Trying to annotation type complete a non-annotation type");
  1125 
  1126         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
  1127         try {
  1128             JCClassDecl tree = (JCClassDecl)env.tree;
  1129             AnnotationTypeVisitor v = new AnnotationTypeVisitor(attr, chk, syms, typeEnvs);
  1130             v.scanAnnotationType(tree);
  1131             tree.sym.getAnnotationTypeMetadata().setRepeatable(v.repeatable);
  1132             tree.sym.getAnnotationTypeMetadata().setTarget(v.target);
  1133         } finally {
  1134             log.useSource(prev);
  1135         }
  1136     }
  1137 
  1138     public Attribute unfinishedDefaultValue() {
  1139         return theUnfinishedDefaultValue;
  1140     }
  1141 
  1142     public static interface AnnotationTypeCompleter {
  1143         void complete(ClassSymbol sym) throws CompletionFailure;
  1144     }
  1145 
  1146     /** Visitor to determine a prototype annotation type for a class declaring an annotation type.
  1147      *
  1148      *  <p><b>This is NOT part of any supported API.
  1149      *  If you write code that depends on this, you do so at your own risk.
  1150      *  This code and its internal interfaces are subject to change or
  1151      *  deletion without notice.</b>
  1152      */
  1153     public class AnnotationTypeVisitor extends TreeScanner {
  1154         private Env<AttrContext> env;
  1155 
  1156         private final Attr attr;
  1157         private final Check check;
  1158         private final Symtab tab;
  1159         private final TypeEnvs typeEnvs;
  1160 
  1161         private Compound target;
  1162         private Compound repeatable;
  1163 
  1164         public AnnotationTypeVisitor(Attr attr, Check check, Symtab tab, TypeEnvs typeEnvs) {
  1165             this.attr = attr;
  1166             this.check = check;
  1167             this.tab = tab;
  1168             this.typeEnvs = typeEnvs;
  1169         }
  1170 
  1171         public Compound getRepeatable() {
  1172             return repeatable;
  1173         }
  1174 
  1175         public Compound getTarget() {
  1176             return target;
  1177         }
  1178 
  1179         public void scanAnnotationType(JCClassDecl decl) {
  1180             visitClassDef(decl);
  1181         }
  1182 
  1183         @Override
  1184         public void visitClassDef(JCClassDecl tree) {
  1185             Env<AttrContext> prevEnv = env;
  1186             env = typeEnvs.get(tree.sym);
  1187             try {
  1188                 scan(tree.mods); // look for repeatable and target
  1189                 // don't descend into body
  1190             } finally {
  1191                 env = prevEnv;
  1192             }
  1193         }
  1194 
  1195         @Override
  1196         public void visitAnnotation(JCAnnotation tree) {
  1197             Type t = tree.annotationType.type;
  1198             if (t == null) {
  1199                 t = attr.attribType(tree.annotationType, env);
  1200                 tree.annotationType.type = t = check.checkType(tree.annotationType.pos(), t, tab.annotationType);
  1201             }
  1202 
  1203             if (t == tab.annotationTargetType) {
  1204                 target = Annotate.this.attributeAnnotation(tree, tab.annotationTargetType, env);
  1205             } else if (t == tab.repeatableType) {
  1206                 repeatable = Annotate.this.attributeAnnotation(tree, tab.repeatableType, env);
  1207             }
  1208         }
  1209 
  1210         @Override
  1211         public void visitErroneous(JCErroneous tree) {
  1212             scan(tree.errs);
  1213         }
  1214     }
  1215 
  1216     /** Represents the semantics of an Annotation Type.
  1217      *
  1218      *  <p><b>This is NOT part of any supported API.
  1219      *  If you write code that depends on this, you do so at your own risk.
  1220      *  This code and its internal interfaces are subject to change or
  1221      *  deletion without notice.</b>
  1222      */
  1223     public static class AnnotationTypeMetadata {
  1224         final ClassSymbol metaDataFor;
  1225         private Compound target;
  1226         private Compound repeatable;
  1227         private AnnotationTypeCompleter annotationTypeCompleter;
  1228 
  1229         public AnnotationTypeMetadata(ClassSymbol metaDataFor, AnnotationTypeCompleter annotationTypeCompleter) {
  1230             this.metaDataFor = metaDataFor;
  1231             this.annotationTypeCompleter = annotationTypeCompleter;
  1232         }
  1233 
  1234         private void init() {
  1235             // Make sure metaDataFor is member entered
  1236             while (!metaDataFor.isCompleted())
  1237                 metaDataFor.complete();
  1238 
  1239             if (annotationTypeCompleter != null) {
  1240                 AnnotationTypeCompleter c = annotationTypeCompleter;
  1241                 annotationTypeCompleter = null;
  1242                 c.complete(metaDataFor);
  1243             }
  1244         }
  1245 
  1246         public void complete() {
  1247             init();
  1248         }
  1249 
  1250         public Compound getRepeatable() {
  1251             init();
  1252             return repeatable;
  1253         }
  1254 
  1255         public void setRepeatable(Compound repeatable) {
  1256             Assert.checkNull(this.repeatable);
  1257             this.repeatable = repeatable;
  1258         }
  1259 
  1260         public Compound getTarget() {
  1261             init();
  1262             return target;
  1263         }
  1264 
  1265         public void setTarget(Compound target) {
  1266             Assert.checkNull(this.target);
  1267                 this.target = target;
  1268         }
  1269 
  1270         public Set<MethodSymbol> getAnnotationElements() {
  1271             init();
  1272             Set<MethodSymbol> members = new LinkedHashSet<>();
  1273             WriteableScope s = metaDataFor.members();
  1274             Iterable<Symbol> ss = s.getSymbols(NON_RECURSIVE);
  1275             for (Symbol sym : ss)
  1276                 if (sym.kind == MTH &&
  1277                         sym.name != sym.name.table.names.clinit &&
  1278                         (sym.flags() & SYNTHETIC) == 0)
  1279                     members.add((MethodSymbol)sym);
  1280             return members;
  1281         }
  1282 
  1283         public Set<MethodSymbol> getAnnotationElementsWithDefault() {
  1284             init();
  1285             Set<MethodSymbol> members = getAnnotationElements();
  1286             Set<MethodSymbol> res = new LinkedHashSet<>();
  1287             for (MethodSymbol m : members)
  1288                 if (m.defaultValue != null)
  1289                     res.add(m);
  1290             return res;
  1291         }
  1292 
  1293         @Override
  1294         public String toString() {
  1295             return "Annotation type for: " + metaDataFor;
  1296         }
  1297 
  1298         public boolean isMetadataForAnnotationType() { return true; }
  1299 
  1300         public static AnnotationTypeMetadata notAnAnnotationType() {
  1301             return NOT_AN_ANNOTATION_TYPE;
  1302         }
  1303 
  1304         private static final AnnotationTypeMetadata NOT_AN_ANNOTATION_TYPE =
  1305                 new AnnotationTypeMetadata(null, null) {
  1306                     @Override
  1307                     public void complete() {
  1308                     } // do nothing
  1309 
  1310                     @Override
  1311                     public String toString() {
  1312                         return "Not an annotation type";
  1313                     }
  1314 
  1315                     @Override
  1316                     public Set<MethodSymbol> getAnnotationElements() {
  1317                         return new LinkedHashSet<>(0);
  1318                     }
  1319 
  1320                     @Override
  1321                     public Set<MethodSymbol> getAnnotationElementsWithDefault() {
  1322                         return new LinkedHashSet<>(0);
  1323                     }
  1324 
  1325                     @Override
  1326                     public boolean isMetadataForAnnotationType() {
  1327                         return false;
  1328                     }
  1329 
  1330                     @Override
  1331                     public Compound getTarget() {
  1332                         return null;
  1333                     }
  1334 
  1335                     @Override
  1336                     public Compound getRepeatable() {
  1337                         return null;
  1338                     }
  1339                 };
  1340     }
  1341 
  1342     public void newRound() {
  1343         blockCount = 1;
  1344     }
  1345 }