24 */ |
24 */ |
25 |
25 |
26 package com.sun.tools.javac.comp; |
26 package com.sun.tools.javac.comp; |
27 |
27 |
28 import java.util.*; |
28 import java.util.*; |
29 import java.util.Set; |
29 |
30 import javax.tools.JavaFileManager; |
30 import javax.tools.JavaFileManager; |
31 |
31 |
32 import com.sun.tools.javac.code.*; |
32 import com.sun.tools.javac.code.*; |
33 import com.sun.tools.javac.jvm.*; |
33 import com.sun.tools.javac.jvm.*; |
34 import com.sun.tools.javac.tree.*; |
34 import com.sun.tools.javac.tree.*; |
35 import com.sun.tools.javac.util.*; |
35 import com.sun.tools.javac.util.*; |
36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
37 import com.sun.tools.javac.util.List; |
37 import com.sun.tools.javac.util.List; |
38 |
38 |
39 import com.sun.tools.javac.tree.JCTree.*; |
|
40 import com.sun.tools.javac.code.Lint; |
39 import com.sun.tools.javac.code.Lint; |
41 import com.sun.tools.javac.code.Lint.LintCategory; |
40 import com.sun.tools.javac.code.Lint.LintCategory; |
42 import com.sun.tools.javac.code.Type.*; |
41 import com.sun.tools.javac.code.Type.*; |
43 import com.sun.tools.javac.code.Symbol.*; |
42 import com.sun.tools.javac.code.Symbol.*; |
44 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext; |
43 import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext; |
45 import com.sun.tools.javac.comp.Infer.InferenceContext; |
44 import com.sun.tools.javac.comp.Infer.InferenceContext; |
46 import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener; |
45 import com.sun.tools.javac.comp.Infer.InferenceContext.FreeTypeListener; |
|
46 import com.sun.tools.javac.tree.JCTree.*; |
|
47 import com.sun.tools.javac.tree.JCTree.JCPolyExpression.*; |
47 |
48 |
48 import static com.sun.tools.javac.code.Flags.*; |
49 import static com.sun.tools.javac.code.Flags.*; |
49 import static com.sun.tools.javac.code.Flags.ANNOTATION; |
50 import static com.sun.tools.javac.code.Flags.ANNOTATION; |
50 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED; |
51 import static com.sun.tools.javac.code.Flags.SYNCHRONIZED; |
51 import static com.sun.tools.javac.code.Kinds.*; |
52 import static com.sun.tools.javac.code.Kinds.*; |
572 */ |
576 */ |
573 public void checkRedundantCast(Env<AttrContext> env, JCTypeCast tree) { |
577 public void checkRedundantCast(Env<AttrContext> env, JCTypeCast tree) { |
574 if (!tree.type.isErroneous() && |
578 if (!tree.type.isErroneous() && |
575 (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST)) |
579 (env.info.lint == null || env.info.lint.isEnabled(Lint.LintCategory.CAST)) |
576 && types.isSameType(tree.expr.type, tree.clazz.type) |
580 && types.isSameType(tree.expr.type, tree.clazz.type) |
|
581 && !(ignoreAnnotatedCasts && TreeInfo.containsTypeAnnotation(tree.clazz)) |
577 && !is292targetTypeCast(tree)) { |
582 && !is292targetTypeCast(tree)) { |
578 log.warning(Lint.LintCategory.CAST, |
583 log.warning(Lint.LintCategory.CAST, |
579 tree.pos(), "redundant.cast", tree.expr.type); |
584 tree.pos(), "redundant.cast", tree.expr.type); |
580 } |
585 } |
581 } |
586 } |
582 //where |
587 //where |
583 private boolean is292targetTypeCast(JCTypeCast tree) { |
588 private boolean is292targetTypeCast(JCTypeCast tree) { |
584 boolean is292targetTypeCast = false; |
589 boolean is292targetTypeCast = false; |
585 JCExpression expr = TreeInfo.skipParens(tree.expr); |
590 JCExpression expr = TreeInfo.skipParens(tree.expr); |
586 if (expr.hasTag(APPLY)) { |
591 if (expr.hasTag(APPLY)) { |
587 JCMethodInvocation apply = (JCMethodInvocation)expr; |
592 JCMethodInvocation apply = (JCMethodInvocation)expr; |
588 Symbol sym = TreeInfo.symbol(apply.meth); |
593 Symbol sym = TreeInfo.symbol(apply.meth); |
589 is292targetTypeCast = sym != null && |
594 is292targetTypeCast = sym != null && |
590 sym.kind == MTH && |
595 sym.kind == MTH && |
591 (sym.flags() & HYPOTHETICAL) != 0; |
596 (sym.flags() & HYPOTHETICAL) != 0; |
592 } |
597 } |
593 return is292targetTypeCast; |
598 return is292targetTypeCast; |
594 } |
599 } |
595 |
600 |
596 |
601 private static final boolean ignoreAnnotatedCasts = true; |
597 |
|
598 //where |
|
599 /** Is type a type variable, or a (possibly multi-dimensional) array of |
|
600 * type variables? |
|
601 */ |
|
602 boolean isTypeVar(Type t) { |
|
603 return t.hasTag(TYPEVAR) || t.hasTag(ARRAY) && isTypeVar(types.elemtype(t)); |
|
604 } |
|
605 |
602 |
606 /** Check that a type is within some bounds. |
603 /** Check that a type is within some bounds. |
607 * |
604 * |
608 * Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid |
605 * Used in TypeApply to verify that, e.g., X in {@code V<X>} is a valid |
609 * type argument. |
606 * type argument. |
635 } else { |
632 } else { |
636 return t; |
633 return t; |
637 } |
634 } |
638 } |
635 } |
639 |
636 |
|
637 Type checkClassOrArrayType(DiagnosticPosition pos, Type t) { |
|
638 if (!t.hasTag(CLASS) && !t.hasTag(ARRAY) && !t.hasTag(ERROR)) { |
|
639 return typeTagError(pos, |
|
640 diags.fragment("type.req.class.array"), |
|
641 asTypeParam(t)); |
|
642 } else { |
|
643 return t; |
|
644 } |
|
645 } |
|
646 |
640 /** Check that type is a class or interface type. |
647 /** Check that type is a class or interface type. |
641 * @param pos Position to be used for error reporting. |
648 * @param pos Position to be used for error reporting. |
642 * @param t The type to be checked. |
649 * @param t The type to be checked. |
643 */ |
650 */ |
644 Type checkClassType(DiagnosticPosition pos, Type t) { |
651 Type checkClassType(DiagnosticPosition pos, Type t) { |
645 if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) |
652 if (!t.hasTag(CLASS) && !t.hasTag(ERROR)) { |
646 return typeTagError(pos, |
653 return typeTagError(pos, |
647 diags.fragment("type.req.class"), |
654 diags.fragment("type.req.class"), |
648 (t.hasTag(TYPEVAR)) |
655 asTypeParam(t)); |
649 ? diags.fragment("type.parameter", t) |
656 } else { |
650 : t); |
|
651 else |
|
652 return t; |
657 return t; |
653 } |
658 } |
|
659 } |
|
660 //where |
|
661 private Object asTypeParam(Type t) { |
|
662 return (t.hasTag(TYPEVAR)) |
|
663 ? diags.fragment("type.parameter", t) |
|
664 : t; |
|
665 } |
654 |
666 |
655 /** Check that type is a valid qualifier for a constructor reference expression |
667 /** Check that type is a valid qualifier for a constructor reference expression |
656 */ |
668 */ |
657 Type checkConstructorRefType(DiagnosticPosition pos, Type t) { |
669 Type checkConstructorRefType(DiagnosticPosition pos, Type t) { |
658 t = checkClassType(pos, t); |
670 t = checkClassOrArrayType(pos, t); |
659 if (t.hasTag(CLASS)) { |
671 if (t.hasTag(CLASS)) { |
660 if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) { |
672 if ((t.tsym.flags() & (ABSTRACT | INTERFACE)) != 0) { |
661 log.error(pos, "abstract.cant.be.instantiated"); |
673 log.error(pos, "abstract.cant.be.instantiated"); |
662 t = types.createErrorType(t); |
674 t = types.createErrorType(t); |
663 } else if ((t.tsym.flags() & ENUM) != 0) { |
675 } else if ((t.tsym.flags() & ENUM) != 0) { |
889 types.erasure(owntype.getReturnType()), |
898 types.erasure(owntype.getReturnType()), |
890 types.erasure(owntype.getThrownTypes()), |
899 types.erasure(owntype.getThrownTypes()), |
891 syms.methodClass); |
900 syms.methodClass); |
892 } |
901 } |
893 if (useVarargs) { |
902 if (useVarargs) { |
894 JCTree tree = env.tree; |
|
895 Type argtype = owntype.getParameterTypes().last(); |
903 Type argtype = owntype.getParameterTypes().last(); |
896 if (!types.isReifiable(argtype) && |
904 if (!types.isReifiable(argtype) && |
897 (!allowSimplifiedVarargs || |
905 (!allowSimplifiedVarargs || |
898 sym.attribute(syms.trustMeType.tsym) == null || |
906 sym.attribute(syms.trustMeType.tsym) == null || |
899 !isTrustMeAllowedOnMethod(sym))) { |
907 !isTrustMeAllowedOnMethod(sym))) { |
900 warnUnchecked(env.tree.pos(), |
908 warnUnchecked(env.tree.pos(), |
901 "unchecked.generic.array.creation", |
909 "unchecked.generic.array.creation", |
902 argtype); |
910 argtype); |
903 } |
911 } |
904 if (!((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types)) { |
912 if (!((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types)) { |
905 Type elemtype = types.elemtype(argtype); |
913 TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype)); |
906 switch (tree.getTag()) { |
|
907 case APPLY: |
|
908 ((JCMethodInvocation) tree).varargsElement = elemtype; |
|
909 break; |
|
910 case NEWCLASS: |
|
911 ((JCNewClass) tree).varargsElement = elemtype; |
|
912 break; |
|
913 case REFERENCE: |
|
914 ((JCMemberReference) tree).varargsElement = elemtype; |
|
915 break; |
|
916 default: |
|
917 throw new AssertionError(""+tree); |
|
918 } |
|
919 } |
914 } |
920 } |
915 } |
|
916 PolyKind pkind = (sym.type.hasTag(FORALL) && |
|
917 sym.type.getReturnType().containsAny(((ForAll)sym.type).tvars)) ? |
|
918 PolyKind.POLY : PolyKind.STANDALONE; |
|
919 TreeInfo.setPolyKind(env.tree, pkind); |
921 return owntype; |
920 return owntype; |
922 } |
921 } |
923 //where |
922 //where |
924 private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) { |
923 private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) { |
925 if (types.isConvertible(actual, formal, warn)) |
924 if (types.isConvertible(actual, formal, warn)) |
2590 |
2608 |
2591 if (a.annotationType.type.tsym == syms.overrideType.tsym) { |
2609 if (a.annotationType.type.tsym == syms.overrideType.tsym) { |
2592 if (!isOverrider(s)) |
2610 if (!isOverrider(s)) |
2593 log.error(a.pos(), "method.does.not.override.superclass"); |
2611 log.error(a.pos(), "method.does.not.override.superclass"); |
2594 } |
2612 } |
|
2613 |
|
2614 if (a.annotationType.type.tsym == syms.functionalInterfaceType.tsym) { |
|
2615 if (s.kind != TYP) { |
|
2616 log.error(a.pos(), "bad.functional.intf.anno"); |
|
2617 } else { |
|
2618 try { |
|
2619 types.findDescriptorSymbol((TypeSymbol)s); |
|
2620 } catch (Types.FunctionDescriptorLookupError ex) { |
|
2621 log.error(a.pos(), "bad.functional.intf.anno.1", ex.getDiagnostic()); |
|
2622 } |
|
2623 } |
|
2624 } |
|
2625 } |
|
2626 |
|
2627 public void validateTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { |
|
2628 Assert.checkNonNull(a.type, "annotation tree hasn't been attributed yet: " + a); |
|
2629 validateAnnotationTree(a); |
|
2630 |
|
2631 if (!isTypeAnnotation(a, isTypeParameter)) |
|
2632 log.error(a.pos(), "annotation.type.not.applicable"); |
2595 } |
2633 } |
2596 |
2634 |
2597 /** |
2635 /** |
2598 * Validate the proposed container 'containedBy' on the |
2636 * Validate the proposed container 'repeatable' on the |
2599 * annotation type symbol 's'. Report errors at position |
2637 * annotation type symbol 's'. Report errors at position |
2600 * 'pos'. |
2638 * 'pos'. |
2601 * |
2639 * |
2602 * @param s The (annotation)type declaration annotated with a @ContainedBy |
2640 * @param s The (annotation)type declaration annotated with a @Repeatable |
2603 * @param containedBy the @ContainedBy on 's' |
2641 * @param repeatable the @Repeatable on 's' |
2604 * @param pos where to report errors |
2642 * @param pos where to report errors |
2605 */ |
2643 */ |
2606 public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) { |
2644 public void validateRepeatable(TypeSymbol s, Attribute.Compound repeatable, DiagnosticPosition pos) { |
2607 Assert.check(types.isSameType(containedBy.type, syms.containedByType)); |
2645 Assert.check(types.isSameType(repeatable.type, syms.repeatableType)); |
2608 |
2646 |
2609 Type t = null; |
2647 Type t = null; |
2610 List<Pair<MethodSymbol,Attribute>> l = containedBy.values; |
2648 List<Pair<MethodSymbol,Attribute>> l = repeatable.values; |
2611 if (!l.isEmpty()) { |
2649 if (!l.isEmpty()) { |
2612 Assert.check(l.head.fst.name == names.value); |
2650 Assert.check(l.head.fst.name == names.value); |
2613 t = ((Attribute.Class)l.head.snd).getValue(); |
2651 t = ((Attribute.Class)l.head.snd).getValue(); |
2614 } |
2652 } |
2615 |
2653 |
2616 if (t == null) { |
2654 if (t == null) { |
2617 log.error(pos, "invalid.container.wrong.containedby", s, containedBy); |
2655 // errors should already have been reported during Annotate |
2618 return; |
2656 return; |
2619 } |
2657 } |
2620 |
2658 |
2621 validateHasContainerFor(t.tsym, s, pos); |
2659 validateValue(t.tsym, s, pos); |
2622 validateRetention(t.tsym, s, pos); |
2660 validateRetention(t.tsym, s, pos); |
2623 validateDocumented(t.tsym, s, pos); |
2661 validateDocumented(t.tsym, s, pos); |
2624 validateInherited(t.tsym, s, pos); |
2662 validateInherited(t.tsym, s, pos); |
2625 validateTarget(t.tsym, s, pos); |
2663 validateTarget(t.tsym, s, pos); |
2626 validateDefault(t.tsym, s, pos); |
2664 validateDefault(t.tsym, s, pos); |
2627 } |
2665 } |
2628 |
2666 |
2629 /** |
2667 private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { |
2630 * Validate the proposed container 'containerFor' on the |
2668 Scope.Entry e = container.members().lookup(names.value); |
2631 * annotation type symbol 's'. Report errors at position |
2669 if (e.scope != null && e.sym.kind == MTH) { |
2632 * 'pos'. |
2670 MethodSymbol m = (MethodSymbol) e.sym; |
2633 * |
2671 Type ret = m.getReturnType(); |
2634 * @param s The (annotation)type declaration annotated with a @ContainerFor |
2672 if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) { |
2635 * @param containerFor the @ContainedFor on 's' |
2673 log.error(pos, "invalid.repeatable.annotation.value.return", |
2636 * @param pos where to report errors |
2674 container, ret, types.makeArrayType(contained.type)); |
2637 */ |
2675 } |
2638 public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) { |
2676 } else { |
2639 Assert.check(types.isSameType(containerFor.type, syms.containerForType)); |
2677 log.error(pos, "invalid.repeatable.annotation.no.value", container); |
2640 |
2678 } |
2641 Type t = null; |
|
2642 List<Pair<MethodSymbol,Attribute>> l = containerFor.values; |
|
2643 if (!l.isEmpty()) { |
|
2644 Assert.check(l.head.fst.name == names.value); |
|
2645 t = ((Attribute.Class)l.head.snd).getValue(); |
|
2646 } |
|
2647 |
|
2648 if (t == null) { |
|
2649 log.error(pos, "invalid.container.wrong.containerfor", s, containerFor); |
|
2650 return; |
|
2651 } |
|
2652 |
|
2653 validateHasContainedBy(t.tsym, s, pos); |
|
2654 } |
|
2655 |
|
2656 private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { |
|
2657 Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym); |
|
2658 |
|
2659 if (containedBy == null) { |
|
2660 log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym); |
|
2661 return; |
|
2662 } |
|
2663 |
|
2664 Type t = null; |
|
2665 List<Pair<MethodSymbol,Attribute>> l = containedBy.values; |
|
2666 if (!l.isEmpty()) { |
|
2667 Assert.check(l.head.fst.name == names.value); |
|
2668 t = ((Attribute.Class)l.head.snd).getValue(); |
|
2669 } |
|
2670 |
|
2671 if (t == null) { |
|
2672 log.error(pos, "invalid.container.wrong.containedby", container, contained); |
|
2673 return; |
|
2674 } |
|
2675 |
|
2676 if (!types.isSameType(t, contained.type)) |
|
2677 log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained); |
|
2678 } |
|
2679 |
|
2680 private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { |
|
2681 Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym); |
|
2682 |
|
2683 if (containerFor == null) { |
|
2684 log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym); |
|
2685 return; |
|
2686 } |
|
2687 |
|
2688 Type t = null; |
|
2689 List<Pair<MethodSymbol,Attribute>> l = containerFor.values; |
|
2690 if (!l.isEmpty()) { |
|
2691 Assert.check(l.head.fst.name == names.value); |
|
2692 t = ((Attribute.Class)l.head.snd).getValue(); |
|
2693 } |
|
2694 |
|
2695 if (t == null) { |
|
2696 log.error(pos, "invalid.container.wrong.containerfor", container, contained); |
|
2697 return; |
|
2698 } |
|
2699 |
|
2700 if (!types.isSameType(t, contained.type)) |
|
2701 log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained); |
|
2702 } |
2679 } |
2703 |
2680 |
2704 private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2681 private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2705 Attribute.RetentionPolicy containerRetention = types.getRetention(container); |
2682 Attribute.RetentionPolicy containerRetention = types.getRetention(container); |
2706 Attribute.RetentionPolicy containedRetention = types.getRetention(contained); |
2683 Attribute.RetentionPolicy containedRetention = types.getRetention(contained); |
2716 if (containerRetention == Attribute.RetentionPolicy.SOURCE) { |
2693 if (containerRetention == Attribute.RetentionPolicy.SOURCE) { |
2717 error = true; |
2694 error = true; |
2718 } |
2695 } |
2719 } |
2696 } |
2720 if (error ) { |
2697 if (error ) { |
2721 log.error(pos, "invalid.containedby.annotation.retention", |
2698 log.error(pos, "invalid.repeatable.annotation.retention", |
2722 container, containerRetention, |
2699 container, containerRetention, |
2723 contained, containedRetention); |
2700 contained, containedRetention); |
2724 } |
2701 } |
2725 } |
2702 } |
2726 |
2703 |
2727 private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2704 private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2728 if (contained.attribute(syms.documentedType.tsym) != null) { |
2705 if (contained.attribute(syms.documentedType.tsym) != null) { |
2729 if (container.attribute(syms.documentedType.tsym) == null) { |
2706 if (container.attribute(syms.documentedType.tsym) == null) { |
2730 log.error(pos, "invalid.containedby.annotation.not.documented", container, contained); |
2707 log.error(pos, "invalid.repeatable.annotation.not.documented", container, contained); |
2731 } |
2708 } |
2732 } |
2709 } |
2733 } |
2710 } |
2734 |
2711 |
2735 private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2712 private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2736 if (contained.attribute(syms.inheritedType.tsym) != null) { |
2713 if (contained.attribute(syms.inheritedType.tsym) != null) { |
2737 if (container.attribute(syms.inheritedType.tsym) == null) { |
2714 if (container.attribute(syms.inheritedType.tsym) == null) { |
2738 log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained); |
2715 log.error(pos, "invalid.repeatable.annotation.not.inherited", container, contained); |
2739 } |
2716 } |
2740 } |
2717 } |
2741 } |
2718 } |
2742 |
2719 |
2743 private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2720 private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) { |
2835 } |
2812 } |
2836 } |
2813 } |
2837 return false; |
2814 return false; |
2838 } |
2815 } |
2839 |
2816 |
|
2817 /** Is the annotation applicable to type annotations? */ |
|
2818 protected boolean isTypeAnnotation(JCAnnotation a, boolean isTypeParameter) { |
|
2819 Attribute.Compound atTarget = |
|
2820 a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym); |
|
2821 if (atTarget == null) { |
|
2822 // An annotation without @Target is not a type annotation. |
|
2823 return false; |
|
2824 } |
|
2825 |
|
2826 Attribute atValue = atTarget.member(names.value); |
|
2827 if (!(atValue instanceof Attribute.Array)) { |
|
2828 return false; // error recovery |
|
2829 } |
|
2830 |
|
2831 Attribute.Array arr = (Attribute.Array) atValue; |
|
2832 for (Attribute app : arr.values) { |
|
2833 if (!(app instanceof Attribute.Enum)) { |
|
2834 return false; // recovery |
|
2835 } |
|
2836 Attribute.Enum e = (Attribute.Enum) app; |
|
2837 |
|
2838 if (e.value.name == names.TYPE_USE) |
|
2839 return true; |
|
2840 else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER) |
|
2841 return true; |
|
2842 } |
|
2843 return false; |
|
2844 } |
|
2845 |
2840 /** Is the annotation applicable to the symbol? */ |
2846 /** Is the annotation applicable to the symbol? */ |
2841 boolean annotationApplicable(JCAnnotation a, Symbol s) { |
2847 boolean annotationApplicable(JCAnnotation a, Symbol s) { |
2842 Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); |
2848 Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym); |
|
2849 Name[] targets; |
|
2850 |
2843 if (arr == null) { |
2851 if (arr == null) { |
2844 return true; |
2852 targets = defaultTargetMetaInfo(a, s); |
2845 } |
2853 } else { |
2846 for (Attribute app : arr.values) { |
2854 // TODO: can we optimize this? |
2847 if (!(app instanceof Attribute.Enum)) return true; // recovery |
2855 targets = new Name[arr.values.length]; |
2848 Attribute.Enum e = (Attribute.Enum) app; |
2856 for (int i=0; i<arr.values.length; ++i) { |
2849 if (e.value.name == names.TYPE) |
2857 Attribute app = arr.values[i]; |
|
2858 if (!(app instanceof Attribute.Enum)) { |
|
2859 return true; // recovery |
|
2860 } |
|
2861 Attribute.Enum e = (Attribute.Enum) app; |
|
2862 targets[i] = e.value.name; |
|
2863 } |
|
2864 } |
|
2865 for (Name target : targets) { |
|
2866 if (target == names.TYPE) |
2850 { if (s.kind == TYP) return true; } |
2867 { if (s.kind == TYP) return true; } |
2851 else if (e.value.name == names.FIELD) |
2868 else if (target == names.FIELD) |
2852 { if (s.kind == VAR && s.owner.kind != MTH) return true; } |
2869 { if (s.kind == VAR && s.owner.kind != MTH) return true; } |
2853 else if (e.value.name == names.METHOD) |
2870 else if (target == names.METHOD) |
2854 { if (s.kind == MTH && !s.isConstructor()) return true; } |
2871 { if (s.kind == MTH && !s.isConstructor()) return true; } |
2855 else if (e.value.name == names.PARAMETER) |
2872 else if (target == names.PARAMETER) |
2856 { if (s.kind == VAR && |
2873 { if (s.kind == VAR && |
2857 s.owner.kind == MTH && |
2874 s.owner.kind == MTH && |
2858 (s.flags() & PARAMETER) != 0) |
2875 (s.flags() & PARAMETER) != 0) |
2859 return true; |
2876 return true; |
2860 } |
2877 } |
2861 else if (e.value.name == names.CONSTRUCTOR) |
2878 else if (target == names.CONSTRUCTOR) |
2862 { if (s.kind == MTH && s.isConstructor()) return true; } |
2879 { if (s.kind == MTH && s.isConstructor()) return true; } |
2863 else if (e.value.name == names.LOCAL_VARIABLE) |
2880 else if (target == names.LOCAL_VARIABLE) |
2864 { if (s.kind == VAR && s.owner.kind == MTH && |
2881 { if (s.kind == VAR && s.owner.kind == MTH && |
2865 (s.flags() & PARAMETER) == 0) |
2882 (s.flags() & PARAMETER) == 0) |
2866 return true; |
2883 return true; |
2867 } |
2884 } |
2868 else if (e.value.name == names.ANNOTATION_TYPE) |
2885 else if (target == names.ANNOTATION_TYPE) |
2869 { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) |
2886 { if (s.kind == TYP && (s.flags() & ANNOTATION) != 0) |
2870 return true; |
2887 return true; |
2871 } |
2888 } |
2872 else if (e.value.name == names.PACKAGE) |
2889 else if (target == names.PACKAGE) |
2873 { if (s.kind == PCK) return true; } |
2890 { if (s.kind == PCK) return true; } |
2874 else if (e.value.name == names.TYPE_USE) |
2891 else if (target == names.TYPE_USE) |
2875 { if (s.kind == TYP || |
2892 { if (s.kind == TYP || |
2876 s.kind == VAR || |
2893 s.kind == VAR || |
2877 (s.kind == MTH && !s.isConstructor() && |
2894 (s.kind == MTH && !s.isConstructor() && |
2878 !s.type.getReturnType().hasTag(VOID))) |
2895 !s.type.getReturnType().hasTag(VOID)) || |
|
2896 (s.kind == MTH && s.isConstructor())) |
|
2897 return true; |
|
2898 } |
|
2899 else if (target == names.TYPE_PARAMETER) |
|
2900 { if (s.kind == TYP && s.type.hasTag(TYPEVAR)) |
2879 return true; |
2901 return true; |
2880 } |
2902 } |
2881 else |
2903 else |
2882 return true; // recovery |
2904 return true; // recovery |
2883 } |
2905 } |