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