< prev index next >

test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java

Print this page

        

@@ -21,11 +21,11 @@
  * questions.
  */
 
 /*
  * @test
- * @bug 6397298 6400986 6425592 6449798 6453386 6508401 6498938 6911854 8030049 8038080
+ * @bug 6397298 6400986 6425592 6449798 6453386 6508401 6498938 6911854 8030049 8038080 8032230
  * @summary Tests that getElementsAnnotatedWith works properly.
  * @author  Joseph D. Darcy
  * @library /tools/javac/lib
  * @modules java.compiler
  *          jdk.compiler

@@ -49,121 +49,260 @@
 import java.lang.annotation.Annotation;
 import java.util.Collections;
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Arrays;
+import java.util.Objects;
 import javax.annotation.processing.*;
 import javax.lang.model.element.*;
 import static javax.lang.model.util.ElementFilter.*;
 
 /**
  * This processor verifies that the information returned by
- * getElementsAnnotatedWith is consistent with the expected results
- * stored in an AnnotatedElementInfo annotation.
+ * getElementsAnnotatedWith and getElementsAnnotatedWithAny is
+ * consistent with the expected results stored in an
+ * AnnotatedElementInfo annotation.
  */
 @AnnotatedElementInfo(annotationName="java.lang.SuppressWarnings", expectedSize=0, names={})
 public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor {
 
     public boolean process(Set<? extends TypeElement> annotations,
-                           RoundEnvironment roundEnvironment) {
-        TypeElement annotatedElementInfoElement =
-            elements.getTypeElement("AnnotatedElementInfo");
+                           RoundEnvironment roundEnv) {
+        // First check sets of annotated elements using the round
+        // environment from the annotation processing tool framework.
+        checkSetOfAnnotatedElements(roundEnv);
+
+        // Next check sets of annotated elements using a round
+        // environment which uses the default implementations of the
+        // getElementsAnnotatedWithAny methods from the interface.
+        checkSetOfAnnotatedElements(new TestingRoundEnvironment(roundEnv));
+        return true;
+    }
+
+    private class TestingRoundEnvironment implements RoundEnvironment {
+        private RoundEnvironment re;
+
+        public TestingRoundEnvironment(RoundEnvironment re) {
+            this.re = re;
+        }
+
+        @Override
+        public boolean errorRaised() {
+            return re.errorRaised();
+        }
+
+        @Override
+        public Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a) {
+            return re.getElementsAnnotatedWith(a);
+        }
+
+        @Override
+        public Set<? extends Element> getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> a) {
+            // Default method defined in the interface
+            return RoundEnvironment.super.getElementsAnnotatedWithAny(a);
+        }
+
+        @Override
+        public Set<? extends Element> getElementsAnnotatedWith(TypeElement a) {
+            return re.getElementsAnnotatedWith(a);
+        }
+
+        @Override
+        public Set<? extends Element> getElementsAnnotatedWithAny(TypeElement... a) {
+            // Default method defined in the interface
+            return RoundEnvironment.super.getElementsAnnotatedWithAny(a);
+        }
+
+        @Override
+        public Set<? extends Element> getRootElements() {
+            return re.getRootElements();
+        }
+
+        @Override
+        public boolean processingOver() {
+            return re.processingOver();
+        }
+        
+    }
+
+    /**
+     * The method checks the following conditions:
+     *
+     * 1) The sets of elements found are equal for the TypeElement and
+     * Class<? extends Annotation> methods on logically equivalent
+     * arguments.
+     *
+     * 2) getElementsAnnotatedWithAny(X) is equal to
+     * getElementsAnnotatedWith(X') where X is a set/var-args array
+     * with one element and X' is the element.
+     *
+     * 3) Verify the result of getElementsAnnotatedWithAny({X, Y}) is equal to
+     * getElementsAnnotatedWith(X) UNION getElementsAnnotatedWith(Y).
+     */
+    void checkSetOfAnnotatedElements(RoundEnvironment re) {
+        TypeElement annotatedElemInfoElem =  elements.getTypeElement("AnnotatedElementInfo");
+
+        // For the "Any" methods, search for both the expected
+        // annotation and AnnotatedElementInfo and verify the return
+        // set is the union of searching for AnnotatedElementInfo and
+        // the other annotation
         Set<? extends Element> resultsMeta = Collections.emptySet();
+        Set<? extends Element> resultsMetaAny      = Collections.emptySet();
+        Set<Element>           resultsMetaMulti    = new HashSet<>();
+        Set<? extends Element> resultsMetaAnyMulti = Collections.emptySet();
         Set<? extends Element> resultsBase = Collections.emptySet();
+        Set<? extends Element> resultsBaseAny      = Collections.emptySet();
+        Set<? extends Element> resultsBaseAnyMulti = Collections.emptySet();
 
-        if (!roundEnvironment.processingOver()) {
-            testNonAnnotations(roundEnvironment);
+        if (!re.processingOver()) {
+            testNonAnnotations(re);
 
             // Verify AnnotatedElementInfo is present on the first
             // specified type.
 
-            TypeElement firstType = typesIn(roundEnvironment.getRootElements()).iterator().next();
+            TypeElement firstType = typesIn(re.getRootElements()).iterator().next();
 
-            AnnotatedElementInfo annotatedElementInfo = firstType.getAnnotation(AnnotatedElementInfo.class);
+            AnnotatedElementInfo annotatedElemInfo =
+                firstType.getAnnotation(AnnotatedElementInfo.class);
 
             boolean failed = false;
 
-            if (annotatedElementInfo == null)
-                throw new IllegalArgumentException("Missing AnnotatedElementInfo annotation on " +
-                                                  firstType);
-            else {
-                // Verify that the annotation information is as
-                // expected.
-
-                Set<String> expectedNames = new HashSet<String>(Arrays.asList(annotatedElementInfo.names()));
-
-                resultsMeta =
-                    roundEnvironment.
-                    getElementsAnnotatedWith(elements.getTypeElement(annotatedElementInfo.annotationName()));
+            Objects.requireNonNull(annotatedElemInfo,
+                                   "Missing AnnotatedElementInfo annotation on " + firstType);
+
+            // Verify that the annotation information is as expected.
+            Set<String> expectedNames =
+                new HashSet<>(Arrays.asList(annotatedElemInfo.names()));
+
+            String annotationName = annotatedElemInfo.annotationName();
+            TypeElement annotationTypeElem = elements.getTypeElement(annotationName);
+
+            resultsMeta         = re.getElementsAnnotatedWith(annotationTypeElem);
+            resultsMetaAny      = re.getElementsAnnotatedWithAny(annotationTypeElem);
+            resultsMetaMulti.addAll(resultsMeta);
+            resultsMetaMulti.addAll(re.getElementsAnnotatedWith(annotatedElemInfoElem));
+            resultsMetaAnyMulti = re.getElementsAnnotatedWithAny(annotationTypeElem, annotatedElemInfoElem);
 
                 if (!resultsMeta.isEmpty())
                     System.err.println("Results: " + resultsMeta);
 
-                if (resultsMeta.size() != annotatedElementInfo.expectedSize()) {
+            if (!resultsMeta.equals(resultsMetaAny)) {
+                failed = true;
+                System.err.printf("Inconsistent Meta with vs withAny results");
+            }
+
+            if (resultsMeta.size() != annotatedElemInfo.expectedSize()) {
                     failed = true;
                     System.err.printf("Bad number of elements; expected %d, got %d%n",
-                                      annotatedElementInfo.expectedSize(), resultsMeta.size());
+                                  annotatedElemInfo.expectedSize(), resultsMeta.size());
                 } else {
                     for(Element element : resultsMeta) {
                         String simpleName = element.getSimpleName().toString();
                         if (!expectedNames.contains(simpleName) ) {
                             failed = true;
                             System.err.println("Name ``" + simpleName + "'' not expected.");
                         }
                     }
                 }
+
+            resultsBase    = computeResultsBase(re, annotationName);
+            resultsBaseAny = computeResultsBaseAny(re, annotationName);
+            try {
+                Set<Class<? extends Annotation>> tmp = new HashSet<>();
+                tmp.add(AnnotatedElementInfo.class);
+                tmp.add(Class.forName(annotationName).asSubclass(Annotation.class));
+                resultsBaseAnyMulti = re.getElementsAnnotatedWithAny(tmp);
+            } catch (ClassNotFoundException e) {
+                throw new RuntimeException(e);
             }
 
-            resultsBase = computeResultsBase(roundEnvironment, annotatedElementInfo.annotationName());
+            if (!resultsBase.equals(resultsBaseAny)) {
+                failed = true;
+                System.err.printf("Inconsistent Base with vs withAny results");
+            }
 
             if (!resultsMeta.equals(resultsBase)) {
                 failed = true;
                 System.err.println("Base and Meta sets unequal;\n meta: " + resultsMeta +
                                    "\nbase: " + resultsBase);
             }
 
+            if (!resultsMetaAnyMulti.equals(resultsMetaMulti)) {
+                failed = true;
+                System.err.println("MetaMultAny and MetaMulti sets unequal;\n meta: " + resultsMeta +
+                                   "\nbase: " + resultsBase);
+            }
+
+            if (!resultsBaseAnyMulti.equals(resultsMetaAnyMulti)) {
+                failed = true;
+                System.err.println("BaseMulti and MetaMulti sets unequal;\n meta: " + resultsMeta +
+                                   "\nbase: " + resultsBase);
+            }
+
             if (failed) {
-                System.err.println("AnnotatedElementInfo: " + annotatedElementInfo);
+                System.err.println("AnnotatedElementInfo: " + annotatedElemInfo);
                 throw new RuntimeException();
             }
         } else {
             // If processing is over without an error, the specified
-            // elements should be empty so an empty set should be returned.
-            resultsMeta = roundEnvironment.getElementsAnnotatedWith(annotatedElementInfoElement);
-            resultsBase = roundEnvironment.getElementsAnnotatedWith(AnnotatedElementInfo.class);
-            if (!resultsMeta.isEmpty())
-                throw new RuntimeException("Nonempty resultsMeta: " + resultsMeta);
-            if (!resultsBase.isEmpty())
-                throw new RuntimeException("Nonempty resultsBase: " + resultsBase);
+            // elements should be empty so an empty set should be
+            // returned.
+            throwOnNonEmpty(re.getElementsAnnotatedWith(annotatedElemInfoElem), "resultsMeta");
+            throwOnNonEmpty(re.getElementsAnnotatedWithAny(annotatedElemInfoElem), "resultsMetaAny");
+            throwOnNonEmpty(re.getElementsAnnotatedWith(AnnotatedElementInfo.class),    "resultsBase");
+            throwOnNonEmpty(re.getElementsAnnotatedWithAny(Set.of(AnnotatedElementInfo.class)), "resultsBaseAny");
+        }
+    }
 
+    private void throwOnNonEmpty(Set<? extends Element> results, String message) {
+        if (!results.isEmpty()) {
+                throw new RuntimeException("Nonempty " + message +  "\t"  + results);
         }
-        return true;
     }
 
-    private Set<? extends Element> computeResultsBase(RoundEnvironment roundEnvironment, String name) {
+    private Set<? extends Element> computeResultsBase(RoundEnvironment roundEnv, String name) {
         try {
-            return roundEnvironment.
+            return roundEnv.
                 getElementsAnnotatedWith(Class.forName(name).asSubclass(Annotation.class));
-        } catch(ClassNotFoundException cnfe) {
+        } catch (ClassNotFoundException cnfe) {
+            throw new RuntimeException(cnfe);
+        }
+    }
+
+    private Set<? extends Element> computeResultsBaseAny(RoundEnvironment roundEnv, String name) {
+        try {
+            return roundEnv.
+                getElementsAnnotatedWithAny(Set.of(Class.forName(name).asSubclass(Annotation.class)));
+        } catch (ClassNotFoundException cnfe) {
             throw new RuntimeException(cnfe);
         }
     }
 
     /**
      * Verify non-annotation types result in
      * IllegalArgumentExceptions.
      */
-    private void testNonAnnotations(RoundEnvironment roundEnvironment) {
+    private void testNonAnnotations(RoundEnvironment roundEnv) {
+        Class objectClass = (Class)Object.class;
+        Set<? extends Element> elements;
+        try {
+            elements = roundEnv.getElementsAnnotatedWith(objectClass);
+            throw new RuntimeException("Illegal argument exception not thrown");
+        } catch (IllegalArgumentException iae) {}
+
+        try {
+            elements = roundEnv.getElementsAnnotatedWithAny(Set.of(objectClass));
+            throw new RuntimeException("Illegal argument exception not thrown");
+        } catch (IllegalArgumentException iae) {}
+
+        TypeElement objectElement = processingEnv.getElementUtils().getTypeElement("java.lang.Object");
         try {
-            Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith((Class)Object.class );
+            elements = roundEnv.getElementsAnnotatedWith(objectElement);
             throw new RuntimeException("Illegal argument exception not thrown");
-        } catch(IllegalArgumentException iae) {}
+        } catch (IllegalArgumentException iae) {}
 
         try {
-            Set<? extends Element> elements =
-                roundEnvironment.getElementsAnnotatedWith(processingEnv.
-                                                          getElementUtils().
-                                                          getTypeElement("java.lang.Object") );
+            elements = roundEnv.getElementsAnnotatedWithAny(objectElement);
             throw new RuntimeException("Illegal argument exception not thrown");
-        } catch(IllegalArgumentException iae) {}
+        } catch (IllegalArgumentException iae) {}
     }
 }
< prev index next >