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