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