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