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