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