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