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 26 package com.sun.tools.javac.comp; 27 28 import java.util.HashMap; 29 import java.util.LinkedHashMap; 30 import java.util.Map; 31 32 import javax.tools.JavaFileObject; 33 34 import com.sun.tools.javac.util.*; 35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 36 import com.sun.tools.javac.code.*; 37 import com.sun.tools.javac.code.Symbol.*; 38 import com.sun.tools.javac.tree.*; 39 import com.sun.tools.javac.tree.JCTree.*; 40 41 import static com.sun.tools.javac.code.Kinds.*; 42 import static com.sun.tools.javac.code.TypeTag.ARRAY; 43 import static com.sun.tools.javac.code.TypeTag.CLASS; 44 import static com.sun.tools.javac.tree.JCTree.Tag.*; 45 46 /** Enter annotations on symbols. Annotations accumulate in a queue, 47 * which is processed at the top level of any set of recursive calls 48 * requesting it be processed. 49 * 50 * <p><b>This is NOT part of any supported API. 51 * If you write code that depends on this, you do so at your own risk. 52 * This code and its internal interfaces are subject to change or 53 * deletion without notice.</b> 54 */ 55 public class Annotate { 56 protected static final Context.Key<Annotate> annotateKey = new Context.Key<>(); 57 248 public List<T> getPlaceholderFor() { 249 return placeholderFor; 250 } 251 252 public Annotate.AnnotationContext<T> getRepeatedContext() { 253 return ctx; 254 } 255 } 256 257 258 /* ******************************************************************** 259 * Compute an attribute from its annotation. 260 *********************************************************************/ 261 262 /** Process a single compound annotation, returning its 263 * Attribute. Used from MemberEnter for attaching the attributes 264 * to the annotated symbol. 265 */ 266 Attribute.Compound enterAnnotation(JCAnnotation a, 267 Type expected, 268 Env<AttrContext> env) { 269 List<Pair<MethodSymbol,Attribute>> elems = 270 enterAttributeValues(a, expected, env); 271 Attribute.Compound ac = new Attribute.Compound(a.type, elems); 272 a.attribute = ac; 273 274 return ac; 275 } 276 277 Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a, 278 Type expected, 279 Env<AttrContext> env) { 280 List<Pair<MethodSymbol,Attribute>> elems = 281 enterAttributeValues(a, expected, env); 282 283 if (a.attribute == null || !(a.attribute instanceof Attribute.TypeCompound)) { 284 // Create a new TypeCompound 285 286 Attribute.TypeCompound tc = 287 new Attribute.TypeCompound(a.type, elems, 288 // TODO: Eventually, we will get rid of this use of 289 // unknown, because we'll get a position from 290 // MemberEnter (task 8027262). 291 TypeAnnotationPosition.unknown); 292 a.attribute = tc; 293 return tc; 294 } else { 295 // Use an existing TypeCompound 296 return (Attribute.TypeCompound)a.attribute; 297 } 298 } 299 300 private List<Pair<MethodSymbol,Attribute>> 301 enterAttributeValues(JCAnnotation a, 302 Type expected, 303 Env<AttrContext> env) { 304 // The annotation might have had its type attributed (but not 305 // checked) by attr.attribAnnotationTypes during MemberEnter, 306 // in which case we do not need to do it again. 307 Type at = (a.annotationType.type != null ? a.annotationType.type 308 : attr.attribType(a.annotationType, env)); 309 a.type = chk.checkType(a.annotationType.pos(), at, expected); 310 boolean isError = a.type.isErroneous(); 311 if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0 && !isError) { 312 log.error(a.annotationType.pos(), 313 "not.annotation.type", a.type.toString()); 314 isError = true; 315 } 316 List<JCExpression> args = a.args; 317 if (args.length() == 1 && !args.head.hasTag(ASSIGN)) { 318 // special case: elided "value=" assumed 319 args.head = make.at(args.head.pos). 320 Assign(make.Ident(names.value), args.head); 321 } 322 ListBuffer<Pair<MethodSymbol,Attribute>> buf = 323 new ListBuffer<>(); 324 for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) { 325 JCExpression t = tl.head; 326 if (!t.hasTag(ASSIGN)) { 327 log.error(t.pos(), "annotation.value.must.be.name.value"); 328 enterAttributeValue(t.type = syms.errType, t, env); 329 continue; 330 } 331 JCAssign assign = (JCAssign)t; 332 if (!assign.lhs.hasTag(IDENT)) { 333 log.error(t.pos(), "annotation.value.must.be.name.value"); 334 enterAttributeValue(t.type = syms.errType, t, env); 335 continue; 336 } 337 JCIdent left = (JCIdent)assign.lhs; 338 Symbol method = rs.resolveQualifiedMethod(assign.rhs.pos(), 339 env, 340 a.type, 341 left.name, 342 List.<Type>nil(), 343 null); 344 left.sym = method; 345 left.type = method.type; 346 if (method.owner != a.type.tsym && !isError) 347 log.error(left.pos(), "no.annotation.member", left.name, a.type); 348 Type result = method.type.getReturnType(); 349 Attribute value = enterAttributeValue(result, assign.rhs, env); 350 if (!method.type.isErroneous()) 351 buf.append(new Pair<>((MethodSymbol)method, value)); 352 t.type = result; 353 } 354 return buf.toList(); 355 } 356 357 Attribute enterAttributeValue(Type expected, 358 JCExpression tree, 359 Env<AttrContext> env) { 360 //first, try completing the attribution value sym - if a completion 361 //error is thrown, we should recover gracefully, and display an 362 //ordinary resolution diagnostic. 363 try { 364 expected.tsym.complete(); 365 } catch(CompletionFailure e) { 366 log.error(tree.pos(), "cant.resolve", Kinds.kindName(e.sym), e.sym); 367 expected = syms.errType; 368 } 369 if (expected.hasTag(ARRAY)) { 370 if (!tree.hasTag(NEWARRAY)) { 371 tree = make.at(tree.pos). 372 NewArray(null, List.<JCExpression>nil(), List.of(tree)); 373 } 374 JCNewArray na = (JCNewArray)tree; 375 if (na.elemtype != null) { 376 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation"); 377 } 378 ListBuffer<Attribute> buf = new ListBuffer<>(); 379 for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) { 380 buf.append(enterAttributeValue(types.elemtype(expected), 381 l.head, 382 env)); 383 } 384 na.type = expected; 385 return new Attribute. 386 Array(expected, buf.toArray(new Attribute[buf.length()])); 387 } 388 if (tree.hasTag(NEWARRAY)) { //error recovery 389 if (!expected.isErroneous()) 390 log.error(tree.pos(), "annotation.value.not.allowable.type"); 391 JCNewArray na = (JCNewArray)tree; 392 if (na.elemtype != null) { 393 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation"); 394 } 395 for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) { 396 enterAttributeValue(syms.errType, 397 l.head, 398 env); 399 } 400 return new Attribute.Error(syms.errType); 401 } 402 if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) { 403 if (tree.hasTag(ANNOTATION)) { 404 return enterAnnotation((JCAnnotation)tree, expected, env); 405 } else { 406 log.error(tree.pos(), "annotation.value.must.be.annotation"); 407 expected = syms.errType; 408 } 409 } 410 if (tree.hasTag(ANNOTATION)) { //error recovery 411 if (!expected.isErroneous()) 412 log.error(tree.pos(), "annotation.not.valid.for.type", expected); 413 enterAnnotation((JCAnnotation)tree, syms.errType, env); 414 return new Attribute.Error(((JCAnnotation)tree).annotationType.type); 415 } 416 if (expected.isPrimitive() || 417 (types.isSameType(expected, syms.stringType) && !expected.hasTag(TypeTag.ERROR))) { 418 Type result = attr.attribExpr(tree, env, expected); 419 if (result.isErroneous()) 420 return new Attribute.Error(result.getOriginalType()); 421 if (result.constValue() == null) { 422 log.error(tree.pos(), "attribute.value.must.be.constant"); 423 return new Attribute.Error(expected); 424 } 425 result = cfolder.coerce(result, expected); 426 return new Attribute.Constant(expected, result.constValue()); 427 } 428 if (expected.tsym == syms.classType.tsym) { 429 Type result = attr.attribExpr(tree, env, expected); 430 if (result.isErroneous()) { 431 // Does it look like an unresolved class literal? 432 if (TreeInfo.name(tree) == names._class && 433 ((JCFieldAccess) tree).selected.type.isErroneous()) { 462 } 463 VarSymbol enumerator = (VarSymbol) sym; 464 return new Attribute.Enum(expected, enumerator); 465 } 466 //error recovery: 467 if (!expected.isErroneous()) 468 log.error(tree.pos(), "annotation.value.not.allowable.type"); 469 return new Attribute.Error(attr.attribExpr(tree, env, expected)); 470 } 471 472 /* ********************************* 473 * Support for repeating annotations 474 ***********************************/ 475 476 /* Process repeated annotations. This method returns the 477 * synthesized container annotation or null IFF all repeating 478 * annotation are invalid. This method reports errors/warnings. 479 */ 480 private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations, 481 AnnotationContext<T> ctx, 482 Symbol on) { 483 T firstOccurrence = annotations.head; 484 List<Attribute> repeated = List.nil(); 485 Type origAnnoType = null; 486 Type arrayOfOrigAnnoType = null; 487 Type targetContainerType = null; 488 MethodSymbol containerValueSymbol = null; 489 490 Assert.check(!annotations.isEmpty() && 491 !annotations.tail.isEmpty()); // i.e. size() > 1 492 493 int count = 0; 494 for (List<T> al = annotations; 495 !al.isEmpty(); 496 al = al.tail) 497 { 498 count++; 499 500 // There must be more than a single anno in the annotation list 501 Assert.check(count > 1 || !al.tail.isEmpty()); 502 503 T currentAnno = al.head; 504 505 origAnnoType = currentAnno.type; 506 if (arrayOfOrigAnnoType == null) { 507 arrayOfOrigAnnoType = types.makeArrayType(origAnnoType); 508 } 509 510 // Only report errors if this isn't the first occurrence I.E. count > 1 511 boolean reportError = count > 1; 512 Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno), reportError); 513 if (currentContainerType == null) { 514 continue; 515 } 516 // Assert that the target Container is == for all repeated 517 // annos of the same annotation type, the types should 518 // come from the same Symbol, i.e. be '==' 519 Assert.check(targetContainerType == null || currentContainerType == targetContainerType); 520 targetContainerType = currentContainerType; 521 522 containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno)); 523 524 if (containerValueSymbol == null) { // Check of CA type failed 525 // errors are already reported 526 continue; 527 } 528 529 repeated = repeated.prepend(currentAnno); 530 } 531 532 if (!repeated.isEmpty()) { 533 repeated = repeated.reverse(); 534 TreeMaker m = make.at(ctx.pos.get(firstOccurrence)); 535 Pair<MethodSymbol, Attribute> p = 536 new Pair<MethodSymbol, Attribute>(containerValueSymbol, 537 new Attribute.Array(arrayOfOrigAnnoType, repeated)); 538 if (ctx.isTypeCompound) { 539 /* TODO: the following code would be cleaner: 540 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p), 541 ((Attribute.TypeCompound)annotations.head).position); 542 JCTypeAnnotation annoTree = m.TypeAnnotation(at); 543 at = enterTypeAnnotation(annoTree, targetContainerType, ctx.env); 544 */ 545 // However, we directly construct the TypeCompound to keep the 546 // direct relation to the contained TypeCompounds. 547 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p), 548 ((Attribute.TypeCompound)annotations.head).position); 549 550 // TODO: annotation applicability checks from below? 551 552 at.setSynthesized(true); 553 554 @SuppressWarnings("unchecked") 555 T x = (T) at; 556 return x; 557 } else { 558 Attribute.Compound c = new Attribute.Compound(targetContainerType, List.of(p)); 559 JCAnnotation annoTree = m.Annotation(c); 560 561 if (!chk.annotationApplicable(annoTree, on)) 562 log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType); 563 564 if (!chk.validateAnnotationDeferErrors(annoTree)) 565 log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType); 566 567 c = enterAnnotation(annoTree, targetContainerType, ctx.env); 568 c.setSynthesized(true); 569 570 @SuppressWarnings("unchecked") 571 T x = (T) c; 572 return x; 573 } 574 } else { 575 return null; // errors should have been reported elsewhere 576 } 577 } 578 579 /** Fetches the actual Type that should be the containing annotation. */ 580 private Type getContainingType(Attribute.Compound currentAnno, 581 DiagnosticPosition pos, 582 boolean reportError) 583 { 584 Type origAnnoType = currentAnno.type; 585 TypeSymbol origAnnoDecl = origAnnoType.tsym; 586 587 // Fetch the Repeatable annotation from the current 588 // annotation's declaration, or null if it has none 589 Attribute.Compound ca = origAnnoDecl.attribute(syms.repeatableType.tsym); 590 if (ca == null) { // has no Repeatable annotation 591 if (reportError) 592 log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType); 593 return null; 594 } 595 596 return filterSame(extractContainingType(ca, pos, origAnnoDecl), 597 origAnnoType); 598 } 693 targetContainerType, 694 valueRetType, 695 expectedType); 696 fatalError = true; 697 } 698 if (error) { 699 fatalError = true; 700 } 701 702 // The conditions for a valid containing annotation are made 703 // in Check.validateRepeatedAnnotaton(); 704 705 return fatalError ? null : containerValueSymbol; 706 } 707 708 private <T extends Attribute.Compound> AnnotationContext<T> 709 prepareEnterAnnotations(List<JCAnnotation> annotations, 710 Env<AttrContext> env, 711 Symbol sym, 712 AttributeCreator<T> creator, 713 boolean isTypeCompound) { 714 Map<TypeSymbol, ListBuffer<T>> annotated = new LinkedHashMap<>(); 715 Map<T, DiagnosticPosition> pos = new HashMap<>(); 716 717 for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) { 718 JCAnnotation a = al.head; 719 T c = creator.create(a, syms.annotationType, env); 720 721 Assert.checkNonNull(c, "Failed to create annotation"); 722 723 if (annotated.containsKey(a.type.tsym)) { 724 if (!allowRepeatedAnnos) { 725 log.error(a.pos(), "repeatable.annotations.not.supported.in.source"); 726 allowRepeatedAnnos = true; 727 } 728 ListBuffer<T> l = annotated.get(a.type.tsym); 729 l = l.append(c); 730 annotated.put(a.type.tsym, l); 731 pos.put(c, a.pos()); 732 } else { 733 annotated.put(a.type.tsym, ListBuffer.of(c)); 734 pos.put(c, a.pos()); 735 } 736 737 // Note: @Deprecated has no effect on local variables and parameters 738 if (!c.type.isErroneous() 739 && sym.owner.kind != MTH 740 && types.isSameType(c.type, syms.deprecatedType)) { 741 sym.flags_field |= Flags.DEPRECATED; 742 } 743 } 744 745 return new AnnotationContext<>(env, annotated, pos, 746 isTypeCompound); 747 } 748 749 // Gather up annotations into a map from type symbols to lists of 750 // Compound attributes, then continue on with repeating 751 // annotations processing 752 private <T extends Attribute.Compound> 753 void attachAttributesLater(final List<JCAnnotation> annotations, 754 final Env<AttrContext> env, 755 final Symbol sym, 756 final boolean isTypeCompound, 757 final AttributeCreator<T> creator, 758 final AttributeAttacher<T> attacher) { 759 final AnnotationContext<T> ctx = 760 prepareEnterAnnotations(annotations, env, sym, creator, isTypeCompound); 761 final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = 762 ctx.annotated; 763 boolean hasRepeated = false; 764 765 List<T> buf = List.<T>nil(); 766 for (ListBuffer<T> lb : annotated.values()) { 767 if (lb.size() == 1) { 768 buf = buf.prepend(lb.first()); 769 } else { 770 @SuppressWarnings("unchecked") 771 T res = (T) new Placeholder<>(ctx, lb.toList(), sym); 772 buf = buf.prepend(res); 773 hasRepeated = true; 774 } 775 } 776 777 final List<T> attrs = buf.reverse(); 778 779 if (!isTypeCompound) { 780 // Attach declaration attributes early, so 781 // that @Repeatable and other annotations get attached. 782 // Since the attacher uses setDeclarationAttributes, this 783 // will be overwritten later. 784 attacher.attach(sym, attrs); 785 } 786 if (hasRepeated) { 787 repeated(new Annotate.Worker() { 788 @Override 789 public String toString() { 790 return "repeated annotation pass of: " + sym + " in: " + sym.owner; 791 } 792 793 @Override 794 public void run() { 795 JavaFileObject oldSource = 796 log.useSource(env.toplevel.sourcefile); 797 try { 798 attacher.attach(sym, replacePlaceholders(attrs, ctx, sym)); 799 } finally { 800 log.useSource(oldSource); 801 } 802 } 803 }); 804 } else { 805 attacher.attach(sym, attrs); 806 } 807 } 808 809 private interface AttributeAttacher<T extends Attribute.Compound> { 810 public void attach(Symbol sym, List<T> attrs); 811 } 812 813 private final AttributeAttacher<Attribute.Compound> declAnnotationsAttacher = 814 new AttributeAttacher<Attribute.Compound>() { 815 @Override 816 public void attach(Symbol sym, List<Attribute.Compound> attrs) { 817 sym.resetAnnotations(); 818 sym.setDeclarationAttributes(attrs); 819 } 820 }; 821 822 private final AttributeAttacher<Attribute.TypeCompound> typeAnnotationsAttacher = 823 new AttributeAttacher<Attribute.TypeCompound>() { 824 @Override 825 public void attach(Symbol sym, List<Attribute.TypeCompound> attrs) { 826 sym.appendUniqueTypeAttributes(attrs); 827 } 828 }; 829 830 private <T extends Attribute.Compound> List<T> 831 replacePlaceholders(List<T> buf, 832 Annotate.AnnotationContext<T> ctx, 833 Symbol sym) { 834 List<T> result = List.nil(); 835 for (T a : buf) { 836 if (a instanceof Placeholder) { 837 @SuppressWarnings("unchecked") 838 T replacement = replaceOne((Placeholder<T>) a, ctx, sym); 839 840 if (null != replacement) { 841 result = result.prepend(replacement); 842 } 843 } else { 844 result = result.prepend(a); 845 } 846 } 847 848 return result.reverse(); 849 } 850 851 private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, 852 Annotate.AnnotationContext<T> ctx, 853 Symbol sym) { 854 // Process repeated annotations 855 T validRepeated = 856 processRepeatedAnnotations(placeholder.getPlaceholderFor(), 857 ctx, sym); 858 859 if (validRepeated != null) { 860 // Check that the container isn't manually 861 // present along with repeated instances of 862 // its contained annotation. 863 ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym); 864 if (manualContainer != null) { 865 log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present", 866 manualContainer.first().type.tsym); 867 } 868 } 869 870 // A null return will delete the Placeholder 871 return validRepeated; 872 } 873 874 /* ******************************************************************** 875 * Annotation processing 876 *********************************************************************/ 877 878 /** Queue annotations for later processing. */ 879 void annotateLater(final List<JCAnnotation> annotations, 880 final Env<AttrContext> localEnv, 881 final Symbol s, 882 final DiagnosticPosition deferPos) { 883 if (annotations.isEmpty()) { 884 return; 885 } 886 if (s.kind != PCK) { 887 s.resetAnnotations(); // mark Annotations as incomplete for now 888 } 889 normal(new Annotate.Worker() { 890 @Override 891 public String toString() { 892 return "annotate " + annotations + " onto " + s + " in " + s.owner; 893 } 894 895 @Override 896 public void run() { 897 Assert.check(s.kind == PCK || s.annotationsPendingCompletion()); 898 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); 899 DiagnosticPosition prevLintPos = 900 deferPos != null 901 ? deferredLintHandler.setPos(deferPos) 902 : deferredLintHandler.immediate(); 903 Lint prevLint = deferPos != null ? null : chk.setLint(lint); 904 try { 905 if (s.hasAnnotations() && 906 annotations.nonEmpty()) 907 log.error(annotations.head.pos, 908 "already.annotated", 909 kindName(s), s); 910 actualEnterAnnotations(annotations, localEnv, s); 911 } finally { 912 if (prevLint != null) 913 chk.setLint(prevLint); 914 deferredLintHandler.setPos(prevLintPos); 915 log.useSource(prev); 916 } 917 } 918 }); 919 920 validate(new Annotate.Worker() { //validate annotations 921 @Override 922 public void run() { 923 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); 924 try { 925 chk.validateAnnotations(annotations, s); 926 } finally { 927 log.useSource(prev); 928 } 929 } 930 }); 931 } 932 933 private interface AttributeCreator<T extends Attribute.Compound> { 934 public T create(JCAnnotation a, Type expected, Env<AttrContext> env); 935 } 936 937 // TODO: When SE8 features can be used, these can go away and be 938 // replaced by method refs. 939 private final AttributeCreator<Attribute.Compound> enterAnnotationsCreator = 940 new AttributeCreator<Attribute.Compound>() { 941 @Override 942 public Attribute.Compound create(JCAnnotation a, 943 Type expected, 944 Env<AttrContext> env) { 945 return enterAnnotation(a, syms.annotationType, env); 946 } 947 }; 948 private final AttributeCreator<Attribute.TypeCompound> enterTypeAnnotationsCreator = 949 new AttributeCreator<Attribute.TypeCompound>() { 950 @Override 951 public Attribute.TypeCompound create(JCAnnotation a, 952 Type expected, 953 Env<AttrContext> env) { 954 return enterTypeAnnotation(a, syms.annotationType, env); 955 } 956 }; 957 958 /** Enter a set of annotations. */ 959 private void actualEnterAnnotations(List<JCAnnotation> annotations, 960 Env<AttrContext> env, 961 Symbol s) { 962 Assert.checkNonNull(s, "Symbol argument to actualEnterAnnotations is null"); 963 attachAttributesLater(annotations, env, s, false, 964 enterAnnotationsCreator, 965 declAnnotationsAttacher); 966 } 967 968 /* 969 * If the symbol is non-null, attach the type annotation to it. 970 */ 971 private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations, 972 final Env<AttrContext> env, 973 final Symbol s, 974 final DiagnosticPosition deferPos) { 975 Assert.checkNonNull(s, "Symbol argument to actualEnterTypeAnnotations is nul/"); 976 JavaFileObject prev = log.useSource(env.toplevel.sourcefile); 977 DiagnosticPosition prevLintPos = null; 978 979 if (deferPos != null) { 980 prevLintPos = deferredLintHandler.setPos(deferPos); 981 } 982 try { 983 attachAttributesLater(annotations, env, s, true, 984 enterTypeAnnotationsCreator, 985 typeAnnotationsAttacher); 986 } finally { 987 if (prevLintPos != null) 988 deferredLintHandler.setPos(prevLintPos); 989 log.useSource(prev); 990 } 991 } 992 993 public void annotateTypeLater(final JCTree tree, 994 final Env<AttrContext> env, 995 final Symbol sym, 996 final DiagnosticPosition deferPos) { 997 Assert.checkNonNull(sym); 998 normal(new Annotate.Worker() { 999 @Override 1000 public String toString() { 1001 return "type annotate " + tree + " onto " + sym + " in " + sym.owner; 1002 } 1003 @Override 1004 public void run() { 1005 tree.accept(new TypeAnnotate(env, sym, deferPos)); 1006 } 1007 }); 1008 } 1009 1010 /** 1011 * We need to use a TreeScanner, because it is not enough to visit the top-level 1012 * annotations. We also need to visit type arguments, etc. 1013 */ 1014 private class TypeAnnotate extends TreeScanner { 1015 private final Env<AttrContext> env; 1016 private final Symbol sym; 1017 private DiagnosticPosition deferPos; 1018 1019 public TypeAnnotate(final Env<AttrContext> env, 1020 final Symbol sym, 1021 final DiagnosticPosition deferPos) { 1022 1023 this.env = env; 1024 this.sym = sym; 1025 this.deferPos = deferPos; 1026 } 1027 1028 @Override 1029 public void visitAnnotatedType(final JCAnnotatedType tree) { 1030 actualEnterTypeAnnotations(tree.annotations, env, sym, deferPos); 1031 super.visitAnnotatedType(tree); 1032 } 1033 1034 @Override 1035 public void visitTypeParameter(final JCTypeParameter tree) { 1036 actualEnterTypeAnnotations(tree.annotations, env, sym, deferPos); 1037 super.visitTypeParameter(tree); 1038 } 1039 1040 @Override 1041 public void visitNewArray(final JCNewArray tree) { 1042 actualEnterTypeAnnotations(tree.annotations, env, sym, deferPos); 1043 for (List<JCAnnotation> dimAnnos : tree.dimAnnotations) 1044 actualEnterTypeAnnotations(dimAnnos, env, sym, deferPos); 1045 super.visitNewArray(tree); 1046 } 1047 1048 @Override 1049 public void visitMethodDef(final JCMethodDecl tree) { 1050 scan(tree.mods); 1051 scan(tree.restype); 1052 scan(tree.typarams); 1053 scan(tree.recvparam); 1054 scan(tree.params); 1055 scan(tree.thrown); 1056 scan(tree.defaultValue); 1057 // Do not annotate the body, just the signature. 1058 // scan(tree.body); 1059 } 1060 1061 @Override 1062 public void visitVarDef(final JCVariableDecl tree) { 1063 DiagnosticPosition prevPos = deferPos; 1064 deferPos = tree.pos(); 1065 try { 1066 if (sym != null && sym.kind == Kinds.VAR) { 1067 // Don't visit a parameter once when the sym is the method 1068 // and once when the sym is the parameter. 1069 scan(tree.mods); 1070 scan(tree.vartype); 1071 } 1072 scan(tree.init); 1073 } finally { 1074 deferPos = prevPos; 1075 } 1076 } 1077 1078 @Override 1079 public void visitClassDef(JCClassDecl tree) { 1080 // We can only hit a classdef if it is declared within 1081 // a method. Ignore it - the class will be visited 1082 // separately later. 1083 } 1084 1085 @Override 1086 public void visitNewClass(JCNewClass tree) { 1087 if (tree.def == null) { 1088 // For an anonymous class instantiation the class 1089 // will be visited separately. 1090 super.visitNewClass(tree); 1091 } 1092 } 1093 } 1094 } | 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 26 package com.sun.tools.javac.comp; 27 28 import java.util.HashMap; 29 import java.util.LinkedHashMap; 30 import java.util.Map; 31 32 import javax.lang.model.type.TypeKind; 33 import javax.tools.JavaFileObject; 34 35 import com.sun.tools.javac.util.*; 36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 37 import com.sun.tools.javac.code.*; 38 import com.sun.tools.javac.code.Symbol.*; 39 import com.sun.tools.javac.code.TypeAnnotationPosition.*; 40 import com.sun.tools.javac.tree.*; 41 import com.sun.tools.javac.tree.JCTree.*; 42 43 import static com.sun.tools.javac.code.Kinds.*; 44 import static com.sun.tools.javac.code.TypeTag.ARRAY; 45 import static com.sun.tools.javac.code.TypeTag.CLASS; 46 import static com.sun.tools.javac.tree.JCTree.Tag.*; 47 48 /** Enter annotations on symbols. Annotations accumulate in a queue, 49 * which is processed at the top level of any set of recursive calls 50 * requesting it be processed. 51 * 52 * <p><b>This is NOT part of any supported API. 53 * If you write code that depends on this, you do so at your own risk. 54 * This code and its internal interfaces are subject to change or 55 * deletion without notice.</b> 56 */ 57 public class Annotate { 58 protected static final Context.Key<Annotate> annotateKey = new Context.Key<>(); 59 250 public List<T> getPlaceholderFor() { 251 return placeholderFor; 252 } 253 254 public Annotate.AnnotationContext<T> getRepeatedContext() { 255 return ctx; 256 } 257 } 258 259 260 /* ******************************************************************** 261 * Compute an attribute from its annotation. 262 *********************************************************************/ 263 264 /** Process a single compound annotation, returning its 265 * Attribute. Used from MemberEnter for attaching the attributes 266 * to the annotated symbol. 267 */ 268 Attribute.Compound enterAnnotation(JCAnnotation a, 269 Type expected, 270 Env<AttrContext> env, 271 TypeAnnotationPosition position) { 272 List<Pair<MethodSymbol,Attribute>> buf = 273 enterAttributeValues(a, expected, env, position); 274 Attribute.Compound ac = 275 new Attribute.Compound(a.type, buf, position); 276 a.attribute = ac; 277 278 return ac; 279 } 280 281 Attribute.TypeCompound enterTypeAnnotation(JCAnnotation a, 282 Type expected, 283 Env<AttrContext> env, 284 TypeAnnotationPosition position) { 285 List<Pair<MethodSymbol,Attribute>> buf = 286 enterAttributeValues(a, expected, env, position); 287 288 if (a.attribute == null || !(a.attribute instanceof Attribute.TypeCompound)) { 289 // Create a new TypeCompound 290 Attribute.TypeCompound tc = 291 new Attribute.TypeCompound(a.type, buf, position); 292 a.attribute = tc; 293 return tc; 294 } else { 295 // Use an existing TypeCompound 296 return (Attribute.TypeCompound)a.attribute; 297 } 298 } 299 300 private List<Pair<MethodSymbol,Attribute>> 301 enterAttributeValues(JCAnnotation a, 302 Type expected, 303 Env<AttrContext> env, 304 TypeAnnotationPosition position) { 305 // The annotation might have had its type attributed (but not 306 // checked) by attr.attribAnnotationTypes during MemberEnter, 307 // in which case we do not need to do it again. 308 Type at = (a.annotationType.type != null ? a.annotationType.type 309 : attr.attribType(a.annotationType, env)); 310 a.type = chk.checkType(a.annotationType.pos(), at, expected); 311 boolean isError = a.type.isErroneous(); 312 if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0 && !isError) { 313 log.error(a.annotationType.pos(), 314 "not.annotation.type", a.type.toString()); 315 isError = true; 316 } 317 List<JCExpression> args = a.args; 318 if (args.length() == 1 && !args.head.hasTag(ASSIGN)) { 319 // special case: elided "value=" assumed 320 args.head = make.at(args.head.pos). 321 Assign(make.Ident(names.value), args.head); 322 } 323 ListBuffer<Pair<MethodSymbol,Attribute>> buf = 324 new ListBuffer<>(); 325 for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) { 326 JCExpression t = tl.head; 327 if (!t.hasTag(ASSIGN)) { 328 log.error(t.pos(), "annotation.value.must.be.name.value"); 329 enterAttributeValue(t.type = syms.errType, t, env, position); 330 continue; 331 } 332 JCAssign assign = (JCAssign)t; 333 if (!assign.lhs.hasTag(IDENT)) { 334 log.error(t.pos(), "annotation.value.must.be.name.value"); 335 enterAttributeValue(t.type = syms.errType, t, env, position); 336 continue; 337 } 338 JCIdent left = (JCIdent)assign.lhs; 339 Symbol method = rs.resolveQualifiedMethod(assign.rhs.pos(), 340 env, 341 a.type, 342 left.name, 343 List.<Type>nil(), 344 null); 345 left.sym = method; 346 left.type = method.type; 347 if (method.owner != a.type.tsym && !isError) 348 log.error(left.pos(), "no.annotation.member", left.name, a.type); 349 Type result = method.type.getReturnType(); 350 Attribute value = enterAttributeValue(result, assign.rhs, env, position); 351 if (!method.type.isErroneous()) 352 buf.append(new Pair<>((MethodSymbol)method, value)); 353 t.type = result; 354 } 355 return buf.toList(); 356 } 357 358 Attribute enterAttributeValue(Type expected, 359 JCExpression tree, 360 Env<AttrContext> env, 361 TypeAnnotationPosition position) { 362 //first, try completing the attribution value sym - if a completion 363 //error is thrown, we should recover gracefully, and display an 364 //ordinary resolution diagnostic. 365 try { 366 expected.tsym.complete(); 367 } catch(CompletionFailure e) { 368 log.error(tree.pos(), "cant.resolve", Kinds.kindName(e.sym), e.sym); 369 expected = syms.errType; 370 } 371 if (expected.hasTag(ARRAY)) { 372 if (!tree.hasTag(NEWARRAY)) { 373 tree = make.at(tree.pos). 374 NewArray(null, List.<JCExpression>nil(), List.of(tree)); 375 } 376 JCNewArray na = (JCNewArray)tree; 377 if (na.elemtype != null) { 378 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation"); 379 } 380 ListBuffer<Attribute> buf = new ListBuffer<>(); 381 for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) { 382 buf.append(enterAttributeValue(types.elemtype(expected), 383 l.head, env, position)); 384 } 385 na.type = expected; 386 return new Attribute. 387 Array(expected, buf.toArray(new Attribute[buf.length()])); 388 } 389 if (tree.hasTag(NEWARRAY)) { //error recovery 390 if (!expected.isErroneous()) 391 log.error(tree.pos(), "annotation.value.not.allowable.type"); 392 JCNewArray na = (JCNewArray)tree; 393 if (na.elemtype != null) { 394 log.error(na.elemtype.pos(), "new.not.allowed.in.annotation"); 395 } 396 for (List<JCExpression> l = na.elems; l.nonEmpty(); l=l.tail) { 397 enterAttributeValue(syms.errType, l.head, env, position); 398 } 399 return new Attribute.Error(syms.errType); 400 } 401 if ((expected.tsym.flags() & Flags.ANNOTATION) != 0) { 402 if (tree.hasTag(ANNOTATION)) { 403 return enterAnnotation((JCAnnotation)tree, expected, env, position); 404 } else { 405 log.error(tree.pos(), "annotation.value.must.be.annotation"); 406 expected = syms.errType; 407 } 408 } 409 if (tree.hasTag(ANNOTATION)) { //error recovery 410 if (!expected.isErroneous()) 411 log.error(tree.pos(), "annotation.not.valid.for.type", expected); 412 enterAnnotation((JCAnnotation)tree, syms.errType, env, position); 413 return new Attribute.Error(((JCAnnotation)tree).annotationType.type); 414 } 415 if (expected.isPrimitive() || 416 (types.isSameType(expected, syms.stringType) && !expected.hasTag(TypeTag.ERROR))) { 417 Type result = attr.attribExpr(tree, env, expected); 418 if (result.isErroneous()) 419 return new Attribute.Error(result.getOriginalType()); 420 if (result.constValue() == null) { 421 log.error(tree.pos(), "attribute.value.must.be.constant"); 422 return new Attribute.Error(expected); 423 } 424 result = cfolder.coerce(result, expected); 425 return new Attribute.Constant(expected, result.constValue()); 426 } 427 if (expected.tsym == syms.classType.tsym) { 428 Type result = attr.attribExpr(tree, env, expected); 429 if (result.isErroneous()) { 430 // Does it look like an unresolved class literal? 431 if (TreeInfo.name(tree) == names._class && 432 ((JCFieldAccess) tree).selected.type.isErroneous()) { 461 } 462 VarSymbol enumerator = (VarSymbol) sym; 463 return new Attribute.Enum(expected, enumerator); 464 } 465 //error recovery: 466 if (!expected.isErroneous()) 467 log.error(tree.pos(), "annotation.value.not.allowable.type"); 468 return new Attribute.Error(attr.attribExpr(tree, env, expected)); 469 } 470 471 /* ********************************* 472 * Support for repeating annotations 473 ***********************************/ 474 475 /* Process repeated annotations. This method returns the 476 * synthesized container annotation or null IFF all repeating 477 * annotation are invalid. This method reports errors/warnings. 478 */ 479 private <T extends Attribute.Compound> T processRepeatedAnnotations(List<T> annotations, 480 AnnotationContext<T> ctx, 481 Symbol on, 482 TypeAnnotationPosition position) { 483 T firstOccurrence = annotations.head; 484 List<Attribute> repeated = List.nil(); 485 Type origAnnoType = null; 486 Type arrayOfOrigAnnoType = null; 487 Type targetContainerType = null; 488 MethodSymbol containerValueSymbol = null; 489 490 Assert.check(!annotations.isEmpty() && 491 !annotations.tail.isEmpty()); // i.e. size() > 1 492 493 int count = 0; 494 for (List<T> al = annotations; !al.isEmpty(); al = al.tail) { 495 count++; 496 // There must be more than a single anno in the annotation list 497 Assert.check(count > 1 || !al.tail.isEmpty()); 498 499 T currentAnno = al.head; 500 501 origAnnoType = currentAnno.type; 502 if (arrayOfOrigAnnoType == null) { 503 arrayOfOrigAnnoType = types.makeArrayType(origAnnoType); 504 } 505 506 // Only report errors if this isn't the first occurrence I.E. count > 1 507 boolean reportError = count > 1; 508 Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno), reportError); 509 if (currentContainerType == null) { 510 continue; 511 } 512 // Assert that the target Container is == for all repeated 513 // annos of the same annotation type, the types should 514 // come from the same Symbol, i.e. be '==' 515 Assert.check(targetContainerType == null || currentContainerType == targetContainerType); 516 targetContainerType = currentContainerType; 517 518 containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno)); 519 520 if (containerValueSymbol == null) { // Check of CA type failed 521 // errors are already reported 522 continue; 523 } 524 525 repeated = repeated.prepend(currentAnno); 526 } 527 528 if (!repeated.isEmpty()) { 529 repeated = repeated.reverse(); 530 TreeMaker m = make.at(ctx.pos.get(firstOccurrence)); 531 Pair<MethodSymbol, Attribute> p = 532 new Pair<MethodSymbol, Attribute>(containerValueSymbol, 533 new Attribute.Array(arrayOfOrigAnnoType, repeated)); 534 if (ctx.isTypeCompound) { 535 Attribute.TypeCompound at = new Attribute.TypeCompound(targetContainerType, List.of(p), position); 536 at.setSynthesized(true); 537 538 @SuppressWarnings("unchecked") 539 T x = (T) at; 540 return x; 541 } else { 542 Attribute.Compound c = new Attribute.Compound(targetContainerType, 543 List.of(p), 544 position); 545 JCAnnotation annoTree = m.Annotation(c); 546 547 if (!chk.annotationApplicable(annoTree, on)) 548 log.error(annoTree.pos(), "invalid.repeatable.annotation.incompatible.target", targetContainerType, origAnnoType); 549 550 if (!chk.validateAnnotationDeferErrors(annoTree)) 551 log.error(annoTree.pos(), "duplicate.annotation.invalid.repeated", origAnnoType); 552 553 c = enterAnnotation(annoTree, targetContainerType, ctx.env, position); 554 c.setSynthesized(true); 555 556 @SuppressWarnings("unchecked") 557 T x = (T) c; 558 return x; 559 } 560 } else { 561 return null; // errors should have been reported elsewhere 562 } 563 } 564 565 566 /** Fetches the actual Type that should be the containing annotation. */ 567 private Type getContainingType(Attribute.Compound currentAnno, 568 DiagnosticPosition pos, 569 boolean reportError) 570 { 571 Type origAnnoType = currentAnno.type; 572 TypeSymbol origAnnoDecl = origAnnoType.tsym; 573 574 // Fetch the Repeatable annotation from the current 575 // annotation's declaration, or null if it has none 576 Attribute.Compound ca = origAnnoDecl.attribute(syms.repeatableType.tsym); 577 if (ca == null) { // has no Repeatable annotation 578 if (reportError) 579 log.error(pos, "duplicate.annotation.missing.container", origAnnoType, syms.repeatableType); 580 return null; 581 } 582 583 return filterSame(extractContainingType(ca, pos, origAnnoDecl), 584 origAnnoType); 585 } 680 targetContainerType, 681 valueRetType, 682 expectedType); 683 fatalError = true; 684 } 685 if (error) { 686 fatalError = true; 687 } 688 689 // The conditions for a valid containing annotation are made 690 // in Check.validateRepeatedAnnotaton(); 691 692 return fatalError ? null : containerValueSymbol; 693 } 694 695 private <T extends Attribute.Compound> AnnotationContext<T> 696 prepareEnterAnnotations(List<JCAnnotation> annotations, 697 Env<AttrContext> env, 698 Symbol sym, 699 AttributeCreator<T> creator, 700 boolean isTypeCompound, 701 TypeAnnotationPosition position) { 702 Map<TypeSymbol, ListBuffer<T>> annotated = new LinkedHashMap<>(); 703 Map<T, DiagnosticPosition> pos = new HashMap<>(); 704 705 for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) { 706 JCAnnotation a = al.head; 707 T c = creator.create(a, syms.annotationType, env, position); 708 709 Assert.checkNonNull(c, "Failed to create annotation"); 710 711 if (annotated.containsKey(a.type.tsym)) { 712 if (!allowRepeatedAnnos) { 713 log.error(a.pos(), "repeatable.annotations.not.supported.in.source"); 714 allowRepeatedAnnos = true; 715 } 716 ListBuffer<T> l = annotated.get(a.type.tsym); 717 l = l.append(c); 718 annotated.put(a.type.tsym, l); 719 pos.put(c, a.pos()); 720 } else { 721 annotated.put(a.type.tsym, ListBuffer.of(c)); 722 pos.put(c, a.pos()); 723 } 724 725 // Note: @Deprecated has no effect on local variables and parameters 726 if (!c.type.isErroneous() 727 && sym.owner.kind != MTH 728 && types.isSameType(c.type, syms.deprecatedType)) { 729 sym.flags_field |= Flags.DEPRECATED; 730 } 731 } 732 733 return new AnnotationContext<>(env, annotated, pos, 734 isTypeCompound); 735 } 736 737 // Gather up annotations into a map from type symbols to lists of 738 // Compound attributes, then continue on with repeating 739 // annotations processing 740 private <T extends Attribute.Compound> 741 void attachAttributesLater(final List<JCAnnotation> annotations, 742 final Env<AttrContext> env, 743 final Symbol sym, 744 final boolean isTypeCompound, 745 final TypeAnnotationPosition position, 746 final AttributeCreator<T> creator, 747 final AttributeAttacher<T> attacher) { 748 final AnnotationContext<T> ctx = 749 prepareEnterAnnotations(annotations, env, sym, creator, 750 isTypeCompound, position); 751 final Map<Symbol.TypeSymbol, ListBuffer<T>> annotated = 752 ctx.annotated; 753 boolean hasRepeated = false; 754 755 List<T> buf = List.<T>nil(); 756 for (ListBuffer<T> lb : annotated.values()) { 757 if (lb.size() == 1) { 758 buf = buf.prepend(lb.first()); 759 } else { 760 @SuppressWarnings("unchecked") 761 T res = (T) new Placeholder<>(ctx, lb.toList(), sym); 762 buf = buf.prepend(res); 763 hasRepeated = true; 764 } 765 } 766 767 final List<T> attrs = buf.reverse(); 768 769 if (!isTypeCompound) { 770 // Attach declaration attributes early, so 771 // that @Repeatable and other annotations get attached. 772 // Since the attacher uses setDeclarationAttributes, this 773 // will be overwritten later. 774 @SuppressWarnings("unchecked") 775 List<Attribute.Compound> tempattrs = (List<Attribute.Compound>) attrs; 776 sym.setDeclarationAttributes(tempattrs); 777 } 778 779 if (hasRepeated) { 780 replacePlaceholdersAndAttach(attrs, ctx, env, sym, attacher); 781 } else { 782 attachAttributesAfterRepeated(attrs, env, attacher); 783 } 784 } 785 786 private <T extends Attribute.Compound> 787 void replacePlaceholdersAndAttach(final List<T> attrs, 788 final AnnotationContext<T> ctx, 789 final Env<AttrContext> env, 790 final Symbol sym, 791 final AttributeAttacher<T> attacher) { 792 repeated(new Annotate.Worker() { 793 @Override 794 public String toString() { 795 return "repeated annotation pass of: " + sym + " in: " + sym.owner; 796 } 797 798 @Override 799 public void run() { 800 JavaFileObject oldSource = 801 log.useSource(env.toplevel.sourcefile); 802 try { 803 final List<T> replaced = 804 replacePlaceholders(attrs, ctx, sym); 805 attachAttributesAfterRepeated(replaced, env, attacher); 806 } finally { 807 log.useSource(oldSource); 808 } 809 } 810 }); 811 } 812 813 private <T extends Attribute.Compound> 814 void attachAttributesAfterRepeated(final List<T> attrs, 815 final Env<AttrContext> env, 816 final AttributeAttacher<T> attacher) { 817 afterRepeated(new Worker() { 818 @Override 819 public String toString() { 820 return "attach pass for: " + attrs; 821 } 822 823 @Override 824 public void run() { 825 JavaFileObject oldSource = 826 log.useSource(env.toplevel.sourcefile); 827 try { 828 attacher.attach(attrs); 829 } finally { 830 log.useSource(oldSource); 831 } 832 } 833 }); 834 } 835 836 public interface AttributeAttacher<T extends Attribute.Compound> { 837 public void attach(List<T> attrs); 838 } 839 840 public interface Reporter<T extends Attribute.Compound> { 841 public void report(List<T> attrs); 842 } 843 844 public enum AnnotationType { DECLARATION, TYPE, BOTH } 845 846 /** 847 * Determine whether an annotation is a declaration annotation, 848 * a type annotation, or both. 849 */ 850 public AnnotationType annotationType(Attribute.Compound a, Symbol s) { 851 Attribute.Compound atTarget = 852 a.type.tsym.attribute(syms.annotationTargetType.tsym); 853 if (atTarget == null) { 854 return inferTargetMetaInfo(a, s); 855 } 856 Attribute atValue = atTarget.member(names.value); 857 if (!(atValue instanceof Attribute.Array)) { 858 Assert.error("annotationType(): bad @Target argument " + atValue + 859 " (" + atValue.getClass() + ")"); 860 return AnnotationType.DECLARATION; // error recovery 861 } 862 Attribute.Array arr = (Attribute.Array) atValue; 863 boolean isDecl = false, isType = false; 864 for (Attribute app : arr.values) { 865 if (!(app instanceof Attribute.Enum)) { 866 Assert.error("annotationType(): unrecognized Attribute kind " + app + 867 " (" + app.getClass() + ")"); 868 isDecl = true; 869 continue; 870 } 871 Attribute.Enum e = (Attribute.Enum) app; 872 if (e.value.name == names.TYPE) { 873 if (s.kind == Kinds.TYP) 874 isDecl = true; 875 } else if (e.value.name == names.FIELD) { 876 if (s.kind == Kinds.VAR && 877 s.owner.kind != Kinds.MTH) 878 isDecl = true; 879 } else if (e.value.name == names.METHOD) { 880 if (s.kind == Kinds.MTH && 881 !s.isConstructor()) 882 isDecl = true; 883 } else if (e.value.name == names.PARAMETER) { 884 if (s.kind == Kinds.VAR && 885 s.owner.kind == Kinds.MTH && 886 (s.flags() & Flags.PARAMETER) != 0) 887 isDecl = true; 888 } else if (e.value.name == names.CONSTRUCTOR) { 889 if (s.kind == Kinds.MTH && 890 s.isConstructor()) 891 isDecl = true; 892 } else if (e.value.name == names.LOCAL_VARIABLE) { 893 if (s.kind == Kinds.VAR && 894 s.owner.kind == Kinds.MTH && 895 (s.flags() & Flags.PARAMETER) == 0) 896 isDecl = true; 897 } else if (e.value.name == names.ANNOTATION_TYPE) { 898 if (s.kind == Kinds.TYP && 899 (s.flags() & Flags.ANNOTATION) != 0) 900 isDecl = true; 901 } else if (e.value.name == names.PACKAGE) { 902 if (s.kind == Kinds.PCK) 903 isDecl = true; 904 } else if (e.value.name == names.TYPE_USE) { 905 if (s.kind == Kinds.TYP || 906 s.kind == Kinds.VAR || 907 (s.kind == Kinds.MTH && !s.isConstructor() && 908 !s.type.getReturnType().hasTag(TypeTag.VOID)) || 909 (s.kind == Kinds.MTH && s.isConstructor())) 910 isType = true; 911 } else if (e.value.name == names.TYPE_PARAMETER) { 912 /* Irrelevant in this case */ 913 // TYPE_PARAMETER doesn't aid in distinguishing between 914 // Type annotations and declaration annotations on an 915 // Element 916 } else { 917 Assert.error("annotationType(): unrecognized Attribute name " + e.value.name + 918 " (" + e.value.name.getClass() + ")"); 919 isDecl = true; 920 } 921 } 922 if (isDecl && isType) { 923 return AnnotationType.BOTH; 924 } else if (isType) { 925 return AnnotationType.TYPE; 926 } else { 927 return AnnotationType.DECLARATION; 928 } 929 } 930 931 private Attribute.TypeCompound toTypeCompound(Attribute.Compound a) { 932 // It is safe to alias the position. 933 return new Attribute.TypeCompound(a, a.position); 934 } 935 936 /** Infer the target annotation kind, if none is given. 937 * We only infer declaration annotations. 938 */ 939 private static AnnotationType inferTargetMetaInfo(Attribute.Compound a, Symbol s) { 940 return AnnotationType.DECLARATION; 941 } 942 943 private AttributeAttacher<Attribute.Compound> 944 declAnnotationsAttacher(final Symbol sym) { 945 return new AttributeAttacher<Attribute.Compound>() { 946 @Override 947 public void attach(List<Attribute.Compound> attrs) { 948 sym.resetAnnotations(); 949 sym.setDeclarationAttributes(attrs); 950 } 951 }; 952 } 953 954 private AttributeAttacher<Attribute.TypeCompound> 955 typeAnnotationsAttacher(final Symbol sym) { 956 return new AttributeAttacher<Attribute.TypeCompound>() { 957 @Override 958 public void attach(List<Attribute.TypeCompound> attrs) { 959 if (!attrs.isEmpty()) { 960 attachTypeAnnotations(sym, attrs); 961 } 962 } 963 }; 964 } 965 966 private void reportIllegalScoping(List<Attribute.TypeCompound> attrs, 967 int pos) { 968 switch (attrs.size()) { 969 case 0: 970 // Don't issue an error if all type annotations are 971 // also declaration annotations. 972 // If the annotations are also declaration annotations, they are 973 // illegal as type annotations but might be legal as declaration annotations. 974 // The normal declaration annotation checks make sure that the use is valid. 975 break; 976 case 1: 977 //System.err.println("Reporting illegal scoping"); 978 log.error(pos, "cant.type.annotate.scoping.1", attrs); 979 break; 980 default: 981 //System.err.println("Reporting illegal scoping"); 982 log.error(pos, "cant.type.annotate.scoping", attrs); 983 } 984 } 985 986 private Reporter<Attribute.TypeCompound> 987 illegalScopingReporter(final int pos) { 988 return new Reporter<Attribute.TypeCompound>() { 989 @Override 990 public void report(List<Attribute.TypeCompound> attrs) { 991 reportIllegalScoping(attrs, pos); 992 } 993 }; 994 } 995 996 private AttributeAttacher<Attribute.Compound> 997 classifyingAttacher(final Symbol sym) { 998 return classifyingAttacher(sym, declAnnotationsAttacher(sym), 999 typeAnnotationsAttacher(sym), 1000 null); 1001 } 1002 1003 1004 private AttributeAttacher<Attribute.Compound> 1005 classifyingAttacher(final Symbol sym, 1006 final AttributeAttacher<Attribute.Compound> declAttacher, 1007 final AttributeAttacher<Attribute.TypeCompound> typeAttacher, 1008 final Reporter<Attribute.TypeCompound> reporter) { 1009 return new AttributeAttacher<Attribute.Compound>() { 1010 @Override 1011 public void attach(List<Attribute.Compound> attrs) { 1012 ListBuffer<Attribute.Compound> declAnnos = new ListBuffer<>(); 1013 ListBuffer<Attribute.TypeCompound> typeAnnos = new ListBuffer<>(); 1014 ListBuffer<Attribute.TypeCompound> onlyTypeAnnos = new ListBuffer<>(); 1015 1016 for (Attribute.Compound a : attrs) { 1017 Assert.check(!(a instanceof Placeholder), 1018 "Placeholders found in annotations being attached!"); 1019 switch (annotationType(a, sym)) { 1020 case DECLARATION: 1021 declAnnos.append(a); 1022 break; 1023 case BOTH: { 1024 declAnnos.append(a); 1025 Attribute.TypeCompound ta = toTypeCompound(a); 1026 Assert.checkNonNull(ta.position); 1027 typeAnnos.append(ta); 1028 break; 1029 } 1030 case TYPE: { 1031 Attribute.TypeCompound ta = toTypeCompound(a); 1032 Assert.checkNonNull(ta.position); 1033 typeAnnos.append(ta); 1034 // Also keep track which annotations are only type annotations 1035 onlyTypeAnnos.append(ta); 1036 break; 1037 } 1038 default: 1039 throw new AssertionError("Unknown annotation type"); 1040 } 1041 } 1042 1043 if (declAttacher != null) 1044 declAttacher.attach(declAnnos.toList()); 1045 1046 if (typeAttacher != null) 1047 typeAttacher.attach(typeAnnos.toList()); 1048 1049 if (reporter != null) 1050 reporter.report(onlyTypeAnnos.toList()); 1051 } 1052 }; 1053 } 1054 1055 public void attachTypeAnnotations(Symbol sym, List<Attribute.TypeCompound> attrs) { 1056 sym.appendUniqueTypeAttributes(attrs); 1057 1058 // For type annotations on variables in methods, make 1059 // sure they are attached to the owner too. 1060 switch(sym.getKind()) { 1061 case PARAMETER: 1062 case LOCAL_VARIABLE: 1063 case RESOURCE_VARIABLE: 1064 case EXCEPTION_PARAMETER: 1065 // Make sure all type annotations from the symbol are also 1066 // on the owner. 1067 sym.owner.appendUniqueTypeAttributes(attrs); 1068 break; 1069 } 1070 } 1071 1072 private <T extends Attribute.Compound> List<T> 1073 replacePlaceholders(List<T> buf, 1074 Annotate.AnnotationContext<T> ctx, 1075 Symbol sym) { 1076 List<T> result = List.nil(); 1077 for (T a : buf) { 1078 if (a instanceof Placeholder) { 1079 @SuppressWarnings("unchecked") 1080 T replacement = replaceOne((Placeholder<T>) a, ctx, sym); 1081 1082 if (null != replacement) { 1083 result = result.prepend(replacement); 1084 } 1085 } else { 1086 result = result.prepend(a); 1087 } 1088 } 1089 1090 return result.reverse(); 1091 } 1092 1093 private <T extends Attribute.Compound> T replaceOne(Placeholder<T> placeholder, 1094 Annotate.AnnotationContext<T> ctx, 1095 Symbol sym) { 1096 // Process repeated annotations 1097 T validRepeated = 1098 processRepeatedAnnotations(placeholder.getPlaceholderFor(), 1099 ctx, sym, placeholder.position); 1100 1101 if (validRepeated != null) { 1102 // Check that the container isn't manually 1103 // present along with repeated instances of 1104 // its contained annotation. 1105 ListBuffer<T> manualContainer = ctx.annotated.get(validRepeated.type.tsym); 1106 if (manualContainer != null) { 1107 log.error(ctx.pos.get(manualContainer.first()), "invalid.repeatable.annotation.repeated.and.container.present", 1108 manualContainer.first().type.tsym); 1109 } 1110 } 1111 1112 // A null return will delete the Placeholder 1113 return validRepeated; 1114 } 1115 1116 /* ******************************************************************** 1117 * Annotation processing 1118 *********************************************************************/ 1119 1120 void annotateLater(final List<JCAnnotation> annotations, 1121 final Env<AttrContext> localEnv, 1122 final Symbol s) { 1123 annotateLater(annotations, localEnv, s, null); 1124 } 1125 1126 void annotateLater(final List<JCAnnotation> annotations, 1127 final Env<AttrContext> localEnv, 1128 final Symbol s, 1129 final DiagnosticPosition deferPos) { 1130 annotateLater(annotations, localEnv, s, deferPos, null, 1131 declAnnotationsAttacher(s)); 1132 } 1133 1134 void annotateLater(final List<JCAnnotation> annotations, 1135 final Env<AttrContext> localEnv, 1136 final Symbol s, 1137 final DiagnosticPosition deferPos, 1138 final TypeAnnotationPosition tapos) { 1139 annotateLater(annotations, localEnv, s, deferPos, tapos, 1140 classifyingAttacher(s)); 1141 } 1142 1143 void annotateLater(final List<JCAnnotation> annotations, 1144 final Env<AttrContext> localEnv, 1145 final Symbol s, 1146 final DiagnosticPosition deferPos, 1147 final TypeAnnotationPosition tapos, 1148 final AttributeAttacher<Attribute.Compound> attacher) { 1149 if (annotations.isEmpty()) { 1150 return; 1151 } 1152 if (s.kind != PCK) { 1153 s.resetAnnotations(); // mark Annotations as incomplete for now 1154 } 1155 normal(new Annotate.Worker() { 1156 @Override 1157 public String toString() { 1158 return "annotate " + annotations + " onto " + s + " in " + s.owner; 1159 } 1160 1161 @Override 1162 public void run() { 1163 annotateNow(annotations, localEnv, s, deferPos, 1164 tapos, attacher); 1165 } 1166 }); 1167 1168 validate(annotationValidator(annotations, localEnv, s)); 1169 } 1170 1171 private void annotateNow(final List<JCAnnotation> annotations, 1172 final Env<AttrContext> localEnv, 1173 final Symbol s, 1174 final DiagnosticPosition deferPos, 1175 final TypeAnnotationPosition position, 1176 final AttributeAttacher<Attribute.Compound> attacher) { 1177 if (annotations.isEmpty()) { 1178 return; 1179 } 1180 Assert.check(s.kind == PCK || s.annotationsPendingCompletion()); 1181 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); 1182 DiagnosticPosition prevLintPos = deferPos != null ? 1183 deferredLintHandler.setPos(deferPos) : 1184 deferredLintHandler.immediate(); 1185 Lint prevLint = deferPos != null ? null : chk.setLint(lint); 1186 try { 1187 if (s.hasAnnotations() && 1188 annotations.nonEmpty()) 1189 log.error(annotations.head.pos, 1190 "already.annotated", 1191 kindName(s), s); 1192 actualEnterAnnotations(annotations, localEnv, s, position, attacher); 1193 } finally { 1194 if (prevLint != null) 1195 chk.setLint(prevLint); 1196 deferredLintHandler.setPos(prevLintPos); 1197 log.useSource(prev); 1198 } 1199 } 1200 1201 private Annotate.Worker annotationValidator(final List<JCAnnotation> annotations, 1202 final Env<AttrContext> localEnv, 1203 final Symbol s) { 1204 return new Annotate.Worker() { //validate annotations 1205 @Override 1206 public void run() { 1207 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); 1208 try { 1209 chk.validateAnnotations(annotations, s); 1210 } finally { 1211 log.useSource(prev); 1212 } 1213 } 1214 }; 1215 } 1216 1217 private Annotate.Worker typeAnnotationValidator(final List<JCAnnotation> annotations, 1218 final Env<AttrContext> localEnv, 1219 final boolean isTypeParameter) { 1220 return new Annotate.Worker() { //validate annotations 1221 @Override 1222 public void run() { 1223 JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile); 1224 try { 1225 chk.validateTypeAnnotations(annotations, isTypeParameter); 1226 } finally { 1227 log.useSource(prev); 1228 } 1229 } 1230 }; 1231 } 1232 1233 private interface AttributeCreator<T extends Attribute.Compound> { 1234 public T create(JCAnnotation a, 1235 Type expected, 1236 Env<AttrContext> env, 1237 TypeAnnotationPosition position); 1238 } 1239 1240 // TODO: When SE8 features can be used, these can go away and be 1241 // replaced by method refs. 1242 private final AttributeCreator<Attribute.Compound> enterAnnotationsCreator = 1243 new AttributeCreator<Attribute.Compound>() { 1244 @Override 1245 public Attribute.Compound create(JCAnnotation a, 1246 Type expected, 1247 Env<AttrContext> env, 1248 TypeAnnotationPosition position) { 1249 return enterAnnotation(a, syms.annotationType, env, position); 1250 } 1251 }; 1252 private final AttributeCreator<Attribute.TypeCompound> enterTypeAnnotationsCreator = 1253 new AttributeCreator<Attribute.TypeCompound>() { 1254 @Override 1255 public Attribute.TypeCompound create(JCAnnotation a, 1256 Type expected, 1257 Env<AttrContext> env, 1258 TypeAnnotationPosition position) { 1259 return enterTypeAnnotation(a, syms.annotationType, env, position); 1260 } 1261 }; 1262 1263 /** Enter a set of annotations. */ 1264 private void actualEnterAnnotations(List<JCAnnotation> annotations, 1265 Env<AttrContext> env, 1266 Symbol s, 1267 TypeAnnotationPosition position, 1268 AttributeAttacher<Attribute.Compound> attacher) { 1269 Assert.checkNonNull(s); 1270 attachAttributesLater(annotations, env, s, false, position, 1271 enterAnnotationsCreator, attacher); 1272 } 1273 1274 /* 1275 * If the symbol is non-null, attach the type annotation to it. 1276 */ 1277 private void actualEnterTypeAnnotations(final List<JCAnnotation> annotations, 1278 final Env<AttrContext> env, 1279 final Symbol s, 1280 final DiagnosticPosition deferPos, 1281 final TypeAnnotationPosition position, 1282 final AttributeAttacher<Attribute.TypeCompound> attacher) { 1283 Assert.checkNonNull(s); 1284 JavaFileObject prev = log.useSource(env.toplevel.sourcefile); 1285 DiagnosticPosition prevLintPos = null; 1286 1287 if (deferPos != null) { 1288 prevLintPos = deferredLintHandler.setPos(deferPos); 1289 } 1290 try { 1291 attachAttributesLater(annotations, env, s, true, position, 1292 enterTypeAnnotationsCreator, attacher); 1293 } finally { 1294 if (prevLintPos != null) 1295 deferredLintHandler.setPos(prevLintPos); 1296 log.useSource(prev); 1297 } 1298 } 1299 1300 public void annotateTypeLater(final JCTree tree, 1301 final Env<AttrContext> env, 1302 final Symbol sym, 1303 final DiagnosticPosition deferPos, 1304 final JCLambda currentLambda, 1305 final PositionCreator creator, 1306 final boolean speculative) { 1307 annotateTypeLater(tree, List.<JCAnnotation>nil(), env, sym, 1308 deferPos, currentLambda, creator, speculative); 1309 } 1310 1311 public void annotateTypeLater(final JCTree tree, 1312 final List<JCAnnotation> declAnnos, 1313 final Env<AttrContext> env, 1314 final Symbol sym, 1315 final DiagnosticPosition deferPos, 1316 final JCLambda currentLambda, 1317 final PositionCreator creator, 1318 final boolean speculative) { 1319 Assert.checkNonNull(sym); 1320 Assert.checkNonNull(declAnnos); 1321 Assert.checkNonNull(creator); 1322 1323 normal(new Annotate.Worker() { 1324 @Override 1325 public String toString() { 1326 return "type annotate " + tree + " onto " + sym + " in " + sym.owner; 1327 } 1328 @Override 1329 public void run() { 1330 if (!declAnnos.isEmpty()) { 1331 sym.resetAnnotations(); // mark Annotations as incomplete for now 1332 } 1333 1334 tree.accept(typeAnnotater(declAnnos, sym, env, deferPos, 1335 currentLambda, creator, speculative)); 1336 } 1337 }); 1338 } 1339 1340 /** 1341 * A client passed into various visitors that takes a type path as 1342 * an argument and performs an action (typically creating a 1343 * TypeAnnotationPosition and then creating a {@code Worker} and 1344 * adding it to a queue. 1345 */ 1346 public abstract class PositionCreator { 1347 public TypeAnnotationPosition create() { 1348 return create(List.<TypePathEntry>nil(), null, 0); 1349 } 1350 1351 public TypeAnnotationPosition createNonNull(List<TypePathEntry> path, 1352 JCLambda lambda, 1353 int typeIndex) { 1354 final TypeAnnotationPosition out = create(path, lambda, typeIndex); 1355 1356 if (out != null) 1357 return out; 1358 else 1359 throw new AssertionError("No annotation creator registered"); 1360 } 1361 1362 public abstract TypeAnnotationPosition create(List<TypePathEntry> path, 1363 JCLambda lambda, 1364 int typeIndex); 1365 } 1366 1367 // For when we don't have a creator. Creates null. 1368 public final PositionCreator noCreator = 1369 new PositionCreator() { 1370 @Override 1371 public TypeAnnotationPosition create(List<TypePathEntry> path, 1372 JCLambda lambda, 1373 int typeIndex) { 1374 return null; 1375 } 1376 }; 1377 1378 // Create class extension positions 1379 public final PositionCreator extendsCreator = 1380 new PositionCreator() { 1381 @Override 1382 public TypeAnnotationPosition create(List<TypePathEntry> path, 1383 JCLambda lambda, 1384 int typeIndex) { 1385 return TypeAnnotationPosition.classExtends(path, lambda, -1); 1386 } 1387 }; 1388 1389 // Create interface implementation positions 1390 public PositionCreator implementsCreator(final int idx) { 1391 return new PositionCreator() { 1392 @Override 1393 public TypeAnnotationPosition create(List<TypePathEntry> path, 1394 JCLambda lambda, 1395 int typeIndex) { 1396 return TypeAnnotationPosition.classExtends(path, lambda, idx, -1); 1397 } 1398 }; 1399 } 1400 1401 // Create method parameter positions 1402 public final PositionCreator paramCreator(final int idx) { 1403 return new PositionCreator() { 1404 @Override 1405 public TypeAnnotationPosition create(List<TypePathEntry> path, 1406 JCLambda lambda, 1407 int typeIndex) { 1408 return TypeAnnotationPosition.methodParameter(path, lambda, idx, -1); 1409 } 1410 }; 1411 } 1412 1413 // Create class type parameter positions 1414 public PositionCreator typeParamCreator(final int idx) { 1415 return new PositionCreator() { 1416 @Override 1417 public TypeAnnotationPosition create(List<TypePathEntry> path, 1418 JCLambda lambda, 1419 int typeIndex) { 1420 return TypeAnnotationPosition.typeParameter(path, lambda, idx, -1); 1421 } 1422 }; 1423 } 1424 1425 public PositionCreator typeParamBoundCreator(final JCTypeParameter typaram, 1426 final int param_idx, 1427 final int bound_idx) { 1428 return new PositionCreator() { 1429 @Override 1430 public TypeAnnotationPosition create(List<TypePathEntry> path, 1431 JCLambda lambda, 1432 int typeIndex) { 1433 final int real_bound_idx = 1434 typaram.bounds.head.type.isInterface() ? bound_idx + 1 : bound_idx; 1435 return TypeAnnotationPosition 1436 .typeParameterBound(path, lambda, param_idx, real_bound_idx, -1); 1437 } 1438 }; 1439 } 1440 1441 // Create field positions 1442 public final PositionCreator fieldCreator = 1443 new PositionCreator() { 1444 @Override 1445 public TypeAnnotationPosition create(List<TypePathEntry> path, 1446 JCLambda lambda, 1447 int typeIndex) { 1448 return TypeAnnotationPosition.field(path, lambda, -1); 1449 } 1450 }; 1451 1452 // Create local variable positions 1453 public PositionCreator localVarCreator(final int pos) { 1454 return new PositionCreator() { 1455 @Override 1456 public TypeAnnotationPosition create(List<TypePathEntry> path, 1457 JCLambda lambda, 1458 int typeIndex) { 1459 return TypeAnnotationPosition.localVariable(path, lambda, pos); 1460 } 1461 }; 1462 } 1463 1464 public PositionCreator resourceVarCreator(final int pos) { 1465 return new PositionCreator() { 1466 @Override 1467 public TypeAnnotationPosition create(List<TypePathEntry> path, 1468 JCLambda lambda, 1469 int typeIndex) { 1470 return TypeAnnotationPosition.resourceVariable(path, lambda, pos); 1471 } 1472 }; 1473 } 1474 1475 public PositionCreator exceptionParamCreator(final int pos) { 1476 return new PositionCreator() { 1477 @Override 1478 public TypeAnnotationPosition create(List<TypePathEntry> path, 1479 JCLambda lambda, 1480 int typeIndex) { 1481 return TypeAnnotationPosition.exceptionParameter(path, lambda, 1482 typeIndex, pos); 1483 } 1484 }; 1485 } 1486 1487 public PositionCreator methodTypeParamCreator(final int idx) { 1488 return new PositionCreator() { 1489 @Override 1490 public TypeAnnotationPosition create(List<TypePathEntry> path, 1491 JCLambda lambda, 1492 int typeIndex) { 1493 return TypeAnnotationPosition.methodTypeParameter(path, lambda, idx, -1); 1494 } 1495 }; 1496 } 1497 1498 public PositionCreator methodRefTypeArgCreator(final int idx, 1499 final int pos) { 1500 return new PositionCreator() { 1501 @Override 1502 public TypeAnnotationPosition create(List<TypePathEntry> path, 1503 JCLambda lambda, 1504 int typeIndex) { 1505 return TypeAnnotationPosition.methodRefTypeArg(path, lambda, idx, pos); 1506 } 1507 }; 1508 } 1509 1510 public PositionCreator constructorRefTypeArgCreator(final int idx, 1511 final int pos) { 1512 return new PositionCreator() { 1513 @Override 1514 public TypeAnnotationPosition create(List<TypePathEntry> path, 1515 JCLambda lambda, 1516 int typeIndex) { 1517 return TypeAnnotationPosition 1518 .constructorRefTypeArg(path, lambda, idx, pos); 1519 } 1520 }; 1521 } 1522 1523 public PositionCreator methodInvokeTypeArgCreator(final int idx, 1524 final int pos) { 1525 return new PositionCreator() { 1526 @Override 1527 public TypeAnnotationPosition create(List<TypePathEntry> path, 1528 JCLambda lambda, 1529 int typeIndex) { 1530 return TypeAnnotationPosition.methodInvocationTypeArg(path, lambda, idx, pos); 1531 } 1532 }; 1533 } 1534 1535 public PositionCreator constructorInvokeTypeArgCreator(final int idx, 1536 final int pos) { 1537 return new PositionCreator() { 1538 @Override 1539 public TypeAnnotationPosition create(List<TypePathEntry> path, 1540 JCLambda lambda, 1541 int typeIndex) { 1542 return TypeAnnotationPosition.constructorInvocationTypeArg(path, lambda, idx, pos); 1543 } 1544 }; 1545 } 1546 1547 public PositionCreator methodTypeParamBoundCreator(final JCTypeParameter typaram, 1548 final int param_idx, 1549 final int bound_idx) { 1550 return new PositionCreator() { 1551 @Override 1552 public TypeAnnotationPosition create(List<TypePathEntry> path, 1553 JCLambda lambda, 1554 int typeIndex) { 1555 final int real_bound_idx = 1556 typaram.bounds.head.type.isInterface() ? bound_idx + 1 : bound_idx; 1557 return TypeAnnotationPosition 1558 .methodTypeParameterBound(path, lambda, param_idx, real_bound_idx, -1); 1559 } 1560 }; 1561 } 1562 1563 public PositionCreator throwCreator(final int idx) { 1564 return new PositionCreator() { 1565 @Override 1566 public TypeAnnotationPosition create(List<TypePathEntry> path, 1567 JCLambda lambda, 1568 int typeIndex) { 1569 return TypeAnnotationPosition.methodThrows(path, lambda, idx, -1); 1570 } 1571 }; 1572 } 1573 1574 public final PositionCreator returnCreator = 1575 new PositionCreator() { 1576 @Override 1577 public TypeAnnotationPosition create(List<TypePathEntry> path, 1578 JCLambda lambda, 1579 int typeIndex) { 1580 return TypeAnnotationPosition.methodReturn(path, lambda, -1); 1581 } 1582 }; 1583 1584 public PositionCreator receiverCreator = 1585 new PositionCreator() { 1586 @Override 1587 public TypeAnnotationPosition create(List<TypePathEntry> path, 1588 JCLambda lambda, 1589 int typeIndex) { 1590 return TypeAnnotationPosition.methodReceiver(path, lambda, -1); 1591 } 1592 }; 1593 1594 public PositionCreator methodRefCreator(final int pos) { 1595 return new PositionCreator() { 1596 @Override 1597 public TypeAnnotationPosition create(List<TypePathEntry> path, 1598 JCLambda lambda, 1599 int typeIndex) { 1600 return TypeAnnotationPosition.methodRef(path, lambda, pos); 1601 } 1602 }; 1603 } 1604 1605 public PositionCreator constructorRefCreator(final int pos) { 1606 return new PositionCreator() { 1607 @Override 1608 public TypeAnnotationPosition create(List<TypePathEntry> path, 1609 JCLambda lambda, 1610 int typeIndex) { 1611 return TypeAnnotationPosition.constructorRef(path, lambda, pos); 1612 } 1613 }; 1614 } 1615 1616 public PositionCreator instanceOfCreator(final int pos) { 1617 return new PositionCreator() { 1618 @Override 1619 public TypeAnnotationPosition create(List<TypePathEntry> path, 1620 JCLambda lambda, 1621 int typeIndex) { 1622 return TypeAnnotationPosition.instanceOf(path, lambda, pos); 1623 } 1624 }; 1625 } 1626 1627 public PositionCreator newObjCreator(final int pos) { 1628 return new PositionCreator() { 1629 @Override 1630 public TypeAnnotationPosition create(List<TypePathEntry> path, 1631 JCLambda lambda, 1632 int typeIndex) { 1633 return TypeAnnotationPosition.newObj(path, lambda, pos); 1634 } 1635 }; 1636 } 1637 1638 public PositionCreator castCreator(final int pos) { 1639 return new PositionCreator() { 1640 @Override 1641 public TypeAnnotationPosition create(List<TypePathEntry> path, 1642 JCLambda lambda, 1643 int typeIndex) { 1644 return TypeAnnotationPosition.typeCast(path, lambda, typeIndex, pos); 1645 } 1646 }; 1647 } 1648 1649 private static List<TypePathEntry> addInners(Type type, 1650 List<TypePathEntry> typepath) { 1651 Type encl = type.getEnclosingType(); 1652 while (encl != null && encl.getKind() != TypeKind.NONE && 1653 encl.getKind() != TypeKind.ERROR) { 1654 typepath = typepath.append(TypePathEntry.INNER_TYPE); 1655 encl = encl.getEnclosingType(); 1656 } 1657 return typepath; 1658 } 1659 1660 public TypeAnnotate typeAnnotater(final List<JCAnnotation> declAnnos, 1661 final Symbol sym, 1662 final Env<AttrContext> env, 1663 final DiagnosticPosition deferPos, 1664 final JCLambda currentLambda, 1665 final PositionCreator creator, 1666 final boolean speculative) { 1667 if (!speculative) { 1668 return new TypeAnnotate(declAnnos, sym, env, deferPos, 1669 currentLambda, creator, 1670 declAnnotationsAttacher(sym), 1671 typeAnnotationsAttacher(sym)); 1672 } else { 1673 return new TypeAnnotate(declAnnos, sym, env, deferPos, 1674 currentLambda, creator, null, null); 1675 } 1676 } 1677 1678 private class TypeAnnotate extends TreeScanner { 1679 protected PositionCreator creator; 1680 private List<TypePathEntry> typepath = List.nil(); 1681 private JCLambda currentLambda; 1682 private int type_index = 0; 1683 private boolean innermost; 1684 // These attachers are for declaration annotations 1685 private AttributeAttacher<Attribute.Compound> declAttacher; 1686 private AttributeAttacher<Attribute.TypeCompound> typeAttacher; 1687 private Reporter<Attribute.TypeCompound> reporter; 1688 private final Symbol sym; 1689 private final DiagnosticPosition deferPos; 1690 private final Env<AttrContext> env; 1691 private final List<JCAnnotation> declAnnos; 1692 1693 public TypeAnnotate(final List<JCAnnotation> declAnnos, 1694 final Symbol sym, 1695 final Env<AttrContext> env, 1696 final DiagnosticPosition deferPos, 1697 final JCLambda currentLambda, 1698 final PositionCreator creator, 1699 final AttributeAttacher<Attribute.Compound> declAttacher, 1700 final AttributeAttacher<Attribute.TypeCompound> typeAttacher) { 1701 this.declAnnos = declAnnos; 1702 this.sym = sym; 1703 this.env = env; 1704 this.deferPos = deferPos; 1705 this.currentLambda = currentLambda; 1706 this.creator = creator; 1707 this.innermost = true; 1708 this.declAttacher = declAttacher; 1709 this.typeAttacher = typeAttacher; 1710 this.reporter = null; 1711 } 1712 1713 private void doDeclAnnos() { 1714 if (!declAnnos.isEmpty()) { 1715 final TypeAnnotationPosition tapos = 1716 creator.createNonNull(typepath, currentLambda, type_index); 1717 annotateNow(declAnnos, env, sym, deferPos, tapos, 1718 classifyingAttacher(sym, declAttacher, 1719 typeAttacher, reporter)); 1720 validate(annotationValidator(declAnnos, env, sym)); 1721 } 1722 } 1723 1724 private void doTypeAnnos(List<JCAnnotation> annos, 1725 boolean isTypeParameter) { 1726 if (!annos.isEmpty()) { 1727 final AttributeAttacher<Attribute.TypeCompound> currTypeAttacher = typeAttacher; 1728 final Reporter<Attribute.TypeCompound> currReporter = reporter; 1729 final AttributeAttacher<Attribute.TypeCompound> attacher = 1730 new AttributeAttacher<Attribute.TypeCompound>() { 1731 @Override 1732 public void attach(List<Attribute.TypeCompound> attrs) { 1733 if (currTypeAttacher != null) 1734 currTypeAttacher.attach(attrs); 1735 if (currReporter != null) 1736 currReporter.report(attrs); 1737 } 1738 }; 1739 final TypeAnnotationPosition tapos = 1740 creator.createNonNull(typepath, currentLambda, type_index); 1741 actualEnterTypeAnnotations(annos, env, sym, deferPos, tapos, 1742 attacher); 1743 validate(typeAnnotationValidator(annos, env, isTypeParameter)); 1744 } 1745 } 1746 1747 @Override 1748 public void visitTypeIdent(final JCPrimitiveTypeTree tree) { 1749 if (innermost) { 1750 final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher; 1751 typeAttacher = 1752 new AttributeAttacher<Attribute.TypeCompound>() { 1753 @Override 1754 public void attach(List<Attribute.TypeCompound> attrs) { 1755 if (null != oldTypeAttacher) 1756 oldTypeAttacher.attach(attrs); 1757 1758 if (!attrs.isEmpty()) { 1759 tree.type = tree.type.annotatedType(attrs); 1760 } 1761 } 1762 }; 1763 doDeclAnnos(); 1764 typeAttacher = oldTypeAttacher; 1765 } 1766 } 1767 1768 @Override 1769 public void visitIdent(final JCIdent tree) { 1770 if (innermost) { 1771 final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher; 1772 final Reporter<Attribute.TypeCompound> oldReporter = reporter; 1773 typeAttacher = 1774 new AttributeAttacher<Attribute.TypeCompound>() { 1775 @Override 1776 public void attach(List<Attribute.TypeCompound> attrs) { 1777 if (null != oldTypeAttacher) 1778 oldTypeAttacher.attach(attrs); 1779 1780 if (!attrs.isEmpty() && 1781 !tree.type.hasTag(TypeTag.PACKAGE)) { 1782 tree.type = tree.type.annotatedType(attrs); 1783 } 1784 } 1785 }; 1786 if (tree.type != null) { 1787 final List<TypePathEntry> oldpath = typepath; 1788 typepath = addInners(tree.type, typepath); 1789 doDeclAnnos(); 1790 typepath = oldpath; 1791 } else { 1792 doDeclAnnos(); 1793 } 1794 reporter = oldReporter; 1795 typeAttacher = oldTypeAttacher; 1796 } 1797 } 1798 1799 @Override 1800 public void visitAnnotatedType(JCAnnotatedType tree) { 1801 Assert.checkNonNull(tree.getUnderlyingType().type); 1802 final boolean oldinnermost = innermost; 1803 innermost = false; 1804 scan(tree.annotations); 1805 innermost = oldinnermost; 1806 scan(tree.underlyingType); 1807 final Reporter<Attribute.TypeCompound> oldReporter = reporter; 1808 final List<TypePathEntry> oldpath = typepath; 1809 typepath = addInners(tree.getUnderlyingType().type, typepath); 1810 doTypeAnnos(tree.annotations, false); 1811 typepath = oldpath; 1812 reporter = oldReporter; 1813 } 1814 1815 @Override 1816 public void visitTypeArray(JCArrayTypeTree tree) { 1817 final List<TypePathEntry> oldpath = typepath; 1818 typepath = typepath.append(TypePathEntry.ARRAY); 1819 super.visitTypeArray(tree); 1820 typepath = oldpath; 1821 } 1822 1823 @Override 1824 public void visitTypeApply(JCTypeApply tree) { 1825 Assert.checkNonNull(tree.getType().type); 1826 final List<TypePathEntry> oldpath = typepath; 1827 scan(tree.clazz); 1828 1829 1830 if (tree.getType() != null && tree.getType().type != null) { 1831 typepath = addInners(tree.getType().type, typepath); 1832 } 1833 final boolean oldinnermost = innermost; 1834 innermost = false; 1835 int i = 0; 1836 for (List<JCExpression> l = tree.arguments; l.nonEmpty(); 1837 l = l.tail, i++) { 1838 final JCExpression arg = l.head; 1839 final List<TypePathEntry> noargpath = typepath; 1840 typepath = typepath.append(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, i)); 1841 scan(arg); 1842 typepath = noargpath; 1843 } 1844 typepath = oldpath; 1845 innermost = oldinnermost; 1846 } 1847 1848 @Override 1849 public void visitNewArray(JCNewArray tree) { 1850 final List<TypePathEntry> oldpath = typepath; 1851 final PositionCreator oldcreator = creator; 1852 creator = newObjCreator(tree.pos); 1853 doTypeAnnos(tree.annotations, false); 1854 1855 for (int i = 0; i < tree.dimAnnotations.size(); i++) { 1856 final List<JCAnnotation> dimAnnos = tree.dimAnnotations.get(i); 1857 doTypeAnnos(dimAnnos, false); 1858 // This is right. As per the type annotations spec, 1859 // the first array dimension has no arrays in the type 1860 // path, the second has one, and so on, and the 1861 // element type has n for n dimensions. 1862 typepath = typepath.append(TypePathEntry.ARRAY); 1863 } 1864 1865 // The element type is sometimes null, in the case of 1866 // array literals. 1867 scan(tree.elemtype); 1868 typepath = oldpath; 1869 creator = oldcreator; 1870 } 1871 1872 @Override 1873 public void visitWildcard(JCWildcard tree) { 1874 final List<TypePathEntry> oldpath = typepath; 1875 typepath = typepath.append(TypePathEntry.WILDCARD); 1876 super.visitWildcard(tree); 1877 typepath = oldpath; 1878 } 1879 1880 @Override 1881 public void visitTypeParameter(JCTypeParameter tree) { 1882 scan(tree.annotations); 1883 Assert.checkNonNull(tree.type); 1884 doTypeAnnos(tree.annotations, true); 1885 } 1886 1887 @Override 1888 public void visitLambda(JCLambda tree) { 1889 final JCLambda oldLambda = currentLambda; 1890 currentLambda = tree; 1891 scan(tree.body); 1892 scan(tree.params); 1893 currentLambda = oldLambda; 1894 1895 } 1896 1897 @Override 1898 public void visitTypeIntersection(JCTypeIntersection tree) { 1899 final boolean oldinnermost = innermost; 1900 for (List<JCExpression> l = tree.bounds; l.nonEmpty(); 1901 l = l.tail, type_index++) { 1902 scan(l.head); 1903 // Set innermost to false after the first element 1904 innermost = false; 1905 } 1906 innermost = oldinnermost; 1907 } 1908 1909 @Override 1910 public void visitTypeUnion(JCTypeUnion tree) { 1911 final boolean oldinnermost = innermost; 1912 for (List<JCExpression> l = tree.alternatives; l.nonEmpty(); 1913 l = l.tail, type_index++) { 1914 scan(l.head); 1915 // Set innermost to false after the first element 1916 innermost = false; 1917 } 1918 innermost = oldinnermost; 1919 } 1920 1921 @Override 1922 public void visitSelect(JCFieldAccess tree) { 1923 Symbol sym = tree.sym; 1924 //System.err.println("visitSelect " + tree); 1925 final AttributeAttacher<Attribute.TypeCompound> oldTypeAttacher = typeAttacher; 1926 final Reporter<Attribute.TypeCompound> oldReporter = reporter; 1927 // If we're selecting from an interface or a static class, 1928 // set up attachers that will only attach declaration 1929 // annotations and will report type annotations as errors. 1930 Type selectedTy = tree.selected.type; 1931 if (sym != null && (sym.isStatic() || sym.isInterface() || 1932 selectedTy.hasTag(TypeTag.PACKAGE))) { 1933 typeAttacher = null; 1934 reporter = illegalScopingReporter(tree.pos); 1935 } 1936 super.visitSelect(tree); 1937 typeAttacher = oldTypeAttacher; 1938 reporter = oldReporter; 1939 } 1940 1941 // These methods stop the visitor from continuing on when it 1942 // sees a definition. 1943 @Override 1944 public void visitVarDef(final JCVariableDecl tree) { 1945 } 1946 1947 @Override 1948 public void visitClassDef(JCClassDecl tree) { 1949 // We can only hit a classdef if it is declared within 1950 // a method. Ignore it - the class will be visited 1951 // separately later. 1952 } 1953 1954 @Override 1955 public void visitNewClass(JCNewClass tree) { 1956 // This will be visited by Attr later, so don't do 1957 // anything. 1958 } 1959 } 1960 1961 private class TypeAnnotateExpr extends TypeAnnotate { 1962 public TypeAnnotateExpr(final Symbol sym, 1963 final Env<AttrContext> env, 1964 final DiagnosticPosition deferPos, 1965 final JCLambda currentLambda, 1966 final PositionCreator creator) { 1967 super(List.<JCAnnotation>nil(), sym, env, deferPos, 1968 currentLambda, creator, null, null); 1969 } 1970 1971 @Override 1972 public void visitTypeCast(final JCTypeCast tree) { 1973 final PositionCreator oldcreator = creator; 1974 creator = castCreator(tree.pos); 1975 super.visitTypeCast(tree); 1976 creator = oldcreator; 1977 } 1978 1979 @Override 1980 public void visitTypeTest(JCInstanceOf tree) { 1981 final PositionCreator oldcreator = creator; 1982 creator = instanceOfCreator(tree.pos); 1983 super.visitTypeTest(tree); 1984 creator = oldcreator; 1985 } 1986 } 1987 1988 public void typeAnnotateExprLater(final JCTree tree, 1989 final Env<AttrContext> env, 1990 final Symbol sym, 1991 final DiagnosticPosition deferPos, 1992 final JCLambda currentLambda, 1993 final PositionCreator creator) { 1994 Assert.checkNonNull(sym); 1995 Assert.checkNonNull(creator); 1996 1997 normal(new Annotate.Worker() { 1998 @Override 1999 public String toString() { 2000 return "type annotate " + tree + " onto " + sym + " in " + sym.owner; 2001 } 2002 @Override 2003 public void run() { 2004 tree.accept(new TypeAnnotateExpr(sym, env, deferPos, 2005 currentLambda, creator)); 2006 } 2007 }); 2008 } 2009 } |