src/share/classes/com/sun/tools/javac/comp/Check.java

changeset 1634
eb0198033c5c
parent 1627
6db9a3b1a93f
child 1712
3c02d2f1a421
equal deleted inserted replaced
1629:f427043f8c65 1634:eb0198033c5c
2777 } 2777 }
2778 } 2778 }
2779 } 2779 }
2780 2780
2781 private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) { 2781 private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) {
2782 Attribute.Array containedTarget = getAttributeTargetAttribute(contained); 2782 // The set of targets the container is applicable to must be a subset
2783 2783 // (with respect to annotation target semantics) of the set of targets
2784 // If contained has no Target, we are done 2784 // the contained is applicable to. The target sets may be implicit or
2785 if (containedTarget == null) { 2785 // explicit.
2786 return; 2786
2787 } 2787 Set<Name> containerTargets;
2788
2789 // If contained has Target m1, container must have a Target
2790 // annotation, m2, and m2 must be a subset of m1. (This is
2791 // trivially true if contained has no target as per above).
2792
2793 // contained has target, but container has not, error
2794 Attribute.Array containerTarget = getAttributeTargetAttribute(container); 2788 Attribute.Array containerTarget = getAttributeTargetAttribute(container);
2795 if (containerTarget == null) { 2789 if (containerTarget == null) {
2796 log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained); 2790 containerTargets = getDefaultTargetSet();
2797 return; 2791 } else {
2798 } 2792 containerTargets = new HashSet<Name>();
2799
2800 Set<Name> containerTargets = new HashSet<Name>();
2801 for (Attribute app : containerTarget.values) { 2793 for (Attribute app : containerTarget.values) {
2802 if (!(app instanceof Attribute.Enum)) { 2794 if (!(app instanceof Attribute.Enum)) {
2803 continue; // recovery 2795 continue; // recovery
2804 } 2796 }
2805 Attribute.Enum e = (Attribute.Enum)app; 2797 Attribute.Enum e = (Attribute.Enum)app;
2806 containerTargets.add(e.value.name); 2798 containerTargets.add(e.value.name);
2807 } 2799 }
2808 2800 }
2809 Set<Name> containedTargets = new HashSet<Name>(); 2801
2802 Set<Name> containedTargets;
2803 Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
2804 if (containedTarget == null) {
2805 containedTargets = getDefaultTargetSet();
2806 } else {
2807 containedTargets = new HashSet<Name>();
2810 for (Attribute app : containedTarget.values) { 2808 for (Attribute app : containedTarget.values) {
2811 if (!(app instanceof Attribute.Enum)) { 2809 if (!(app instanceof Attribute.Enum)) {
2812 continue; // recovery 2810 continue; // recovery
2813 } 2811 }
2814 Attribute.Enum e = (Attribute.Enum)app; 2812 Attribute.Enum e = (Attribute.Enum)app;
2815 containedTargets.add(e.value.name); 2813 containedTargets.add(e.value.name);
2816 } 2814 }
2817 2815 }
2818 if (!isTargetSubset(containedTargets, containerTargets)) { 2816
2817 if (!isTargetSubsetOf(containerTargets, containedTargets)) {
2819 log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained); 2818 log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
2820 } 2819 }
2821 } 2820 }
2822 2821
2823 /** Checks that t is a subset of s, with respect to ElementType 2822 /* get a set of names for the default target */
2823 private Set<Name> getDefaultTargetSet() {
2824 if (defaultTargets == null) {
2825 Set<Name> targets = new HashSet<Name>();
2826 targets.add(names.ANNOTATION_TYPE);
2827 targets.add(names.CONSTRUCTOR);
2828 targets.add(names.FIELD);
2829 targets.add(names.LOCAL_VARIABLE);
2830 targets.add(names.METHOD);
2831 targets.add(names.PACKAGE);
2832 targets.add(names.PARAMETER);
2833 targets.add(names.TYPE);
2834
2835 defaultTargets = java.util.Collections.unmodifiableSet(targets);
2836 }
2837
2838 return defaultTargets;
2839 }
2840 private Set<Name> defaultTargets;
2841
2842
2843 /** Checks that s is a subset of t, with respect to ElementType
2824 * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE} 2844 * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE}
2825 */ 2845 */
2826 private boolean isTargetSubset(Set<Name> s, Set<Name> t) { 2846 private boolean isTargetSubsetOf(Set<Name> s, Set<Name> t) {
2827 // Check that all elements in t are present in s 2847 // Check that all elements in s are present in t
2828 for (Name n2 : t) { 2848 for (Name n2 : s) {
2829 boolean currentElementOk = false; 2849 boolean currentElementOk = false;
2830 for (Name n1 : s) { 2850 for (Name n1 : t) {
2831 if (n1 == n2) { 2851 if (n1 == n2) {
2832 currentElementOk = true; 2852 currentElementOk = true;
2833 break; 2853 break;
2834 } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) { 2854 } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) {
2835 currentElementOk = true; 2855 currentElementOk = true;

mercurial