8006547: Repeating annotations: No Target on container annotation with all targets on base annotation gives compiler error
Reviewed-by: jjg
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Mar 12 17:39:34 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Wed Mar 13 22:03:09 2013 +0100
@@ -2779,25 +2779,17 @@
}
private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) {
- Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
-
- // If contained has no Target, we are done
- if (containedTarget == null) {
- return;
- }
-
- // If contained has Target m1, container must have a Target
- // annotation, m2, and m2 must be a subset of m1. (This is
- // trivially true if contained has no target as per above).
-
- // contained has target, but container has not, error
+ // The set of targets the container is applicable to must be a subset
+ // (with respect to annotation target semantics) of the set of targets
+ // the contained is applicable to. The target sets may be implicit or
+ // explicit.
+
+ Set<Name> containerTargets;
Attribute.Array containerTarget = getAttributeTargetAttribute(container);
if (containerTarget == null) {
- log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
- return;
- }
-
- Set<Name> containerTargets = new HashSet<Name>();
+ containerTargets = getDefaultTargetSet();
+ } else {
+ containerTargets = new HashSet<Name>();
for (Attribute app : containerTarget.values) {
if (!(app instanceof Attribute.Enum)) {
continue; // recovery
@@ -2805,8 +2797,14 @@
Attribute.Enum e = (Attribute.Enum)app;
containerTargets.add(e.value.name);
}
-
- Set<Name> containedTargets = new HashSet<Name>();
+ }
+
+ Set<Name> containedTargets;
+ Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
+ if (containedTarget == null) {
+ containedTargets = getDefaultTargetSet();
+ } else {
+ containedTargets = new HashSet<Name>();
for (Attribute app : containedTarget.values) {
if (!(app instanceof Attribute.Enum)) {
continue; // recovery
@@ -2814,20 +2812,42 @@
Attribute.Enum e = (Attribute.Enum)app;
containedTargets.add(e.value.name);
}
-
- if (!isTargetSubset(containedTargets, containerTargets)) {
+ }
+
+ if (!isTargetSubsetOf(containerTargets, containedTargets)) {
log.error(pos, "invalid.repeatable.annotation.incompatible.target", container, contained);
}
}
- /** Checks that t is a subset of s, with respect to ElementType
+ /* get a set of names for the default target */
+ private Set<Name> getDefaultTargetSet() {
+ if (defaultTargets == null) {
+ Set<Name> targets = new HashSet<Name>();
+ targets.add(names.ANNOTATION_TYPE);
+ targets.add(names.CONSTRUCTOR);
+ targets.add(names.FIELD);
+ targets.add(names.LOCAL_VARIABLE);
+ targets.add(names.METHOD);
+ targets.add(names.PACKAGE);
+ targets.add(names.PARAMETER);
+ targets.add(names.TYPE);
+
+ defaultTargets = java.util.Collections.unmodifiableSet(targets);
+ }
+
+ return defaultTargets;
+ }
+ private Set<Name> defaultTargets;
+
+
+ /** Checks that s is a subset of t, with respect to ElementType
* semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE}
*/
- private boolean isTargetSubset(Set<Name> s, Set<Name> t) {
- // Check that all elements in t are present in s
- for (Name n2 : t) {
+ private boolean isTargetSubsetOf(Set<Name> s, Set<Name> t) {
+ // Check that all elements in s are present in t
+ for (Name n2 : s) {
boolean currentElementOk = false;
- for (Name n1 : s) {
+ for (Name n1 : t) {
if (n1 == n2) {
currentElementOk = true;
break;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultTarget.java Wed Mar 13 22:03:09 2013 +0100
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+
+/**
+ * @test
+ * @bug 8006547
+ * @compile DefaultTarget.java
+ */
+
+@Target({
+ ElementType.CONSTRUCTOR,
+ ElementType.PARAMETER,
+ ElementType.TYPE,
+ ElementType.METHOD,
+ ElementType.LOCAL_VARIABLE,
+ ElementType.PACKAGE,
+ ElementType.ANNOTATION_TYPE,
+ ElementType.FIELD,
+})
+@interface Container {
+ DefaultTarget[] value();
+}
+
+@Repeatable(Container.class)
+public @interface DefaultTarget {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultTargetTypeParameter.java Wed Mar 13 22:03:09 2013 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+
+/**
+ * @test
+ * @bug 8006547
+ * @compile/fail/ref=DefaultTargetTypeParameter.out -XDrawDiagnostics DefaultTargetTypeParameter.java
+ */
+
+@Target({
+ ElementType.TYPE_PARAMETER,
+})
+@interface Container {
+ DefaultTargetTypeParameter[] value();
+}
+
+@Repeatable(Container.class)
+public @interface DefaultTargetTypeParameter {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultTargetTypeParameter.out Wed Mar 13 22:03:09 2013 +0100
@@ -0,0 +1,2 @@
+DefaultTargetTypeParameter.java:39:1: compiler.err.invalid.repeatable.annotation.incompatible.target: Container, DefaultTargetTypeParameter
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultTargetTypeUse.java Wed Mar 13 22:03:09 2013 +0100
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+
+/**
+ * @test
+ * @bug 8006547
+ * @compile/fail/ref=DefaultTargetTypeUse.out -XDrawDiagnostics DefaultTargetTypeUse.java
+ */
+
+@Target({
+ ElementType.TYPE_USE,
+})
+@interface Container {
+ DefaultTargetTypeUse[] value();
+}
+
+@Repeatable(Container.class)
+public @interface DefaultTargetTypeUse {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DefaultTargetTypeUse.out Wed Mar 13 22:03:09 2013 +0100
@@ -0,0 +1,2 @@
+DefaultTargetTypeUse.java:39:1: compiler.err.invalid.repeatable.annotation.incompatible.target: Container, DefaultTargetTypeUse
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NoTargetOnContainer.java Wed Mar 13 22:03:09 2013 +0100
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+
+/**
+ * @test
+ * @bug 8006547
+ * @compile NoTargetOnContainer.java
+ */
+
+@interface FooContainer {
+ Foo[] value();
+}
+
+@Target({
+ ElementType.CONSTRUCTOR,
+ ElementType.PARAMETER,
+ ElementType.TYPE,
+ ElementType.METHOD,
+ ElementType.LOCAL_VARIABLE,
+ ElementType.PACKAGE,
+ ElementType.ANNOTATION_TYPE,
+ ElementType.FIELD,
+})
+@Repeatable(FooContainer.class)
+@interface Foo {}
+
+class NoTargetOnContainer {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NoTargetOnContainer2.java Wed Mar 13 22:03:09 2013 +0100
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.*;
+
+/**
+ * @test
+ * @bug 8006547
+ * @compile NoTargetOnContainer2.java
+ */
+
+@interface FooContainer {
+ Foo[] value();
+}
+
+@Target({
+ ElementType.CONSTRUCTOR,
+ ElementType.PARAMETER,
+ ElementType.TYPE,
+ ElementType.METHOD,
+ ElementType.LOCAL_VARIABLE,
+ ElementType.PACKAGE,
+ ElementType.ANNOTATION_TYPE,
+ ElementType.FIELD,
+ ElementType.TYPE_USE,
+ ElementType.TYPE_PARAMETER})
+@Repeatable(FooContainer.class)
+@interface Foo {}
+
+class NoTargetOnContainer2 {}