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