--- old/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java 2016-05-24 01:12:31.090780956 -0700 +++ new/test/tools/javac/processing/environment/round/TestElementsAnnotatedWith.java 2016-05-24 01:12:31.006822958 -0700 @@ -23,7 +23,7 @@ /* * @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 @@ -51,69 +51,174 @@ 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 annotations, - RoundEnvironment roundEnvironment) { - TypeElement annotatedElementInfoElement = - elements.getTypeElement("AnnotatedElementInfo"); - Set resultsMeta = Collections.emptySet(); - Set resultsBase = Collections.emptySet(); + 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 getElementsAnnotatedWith(Class a) { + return re.getElementsAnnotatedWith(a); + } + + @Override + public Set getElementsAnnotatedWithAny(Set> a) { + // Default method defined in the interface + return RoundEnvironment.super.getElementsAnnotatedWithAny(a); + } + + @Override + public Set getElementsAnnotatedWith(TypeElement a) { + return re.getElementsAnnotatedWith(a); + } + + @Override + public Set getElementsAnnotatedWithAny(TypeElement... a) { + // Default method defined in the interface + return RoundEnvironment.super.getElementsAnnotatedWithAny(a); + } - if (!roundEnvironment.processingOver()) { - testNonAnnotations(roundEnvironment); + @Override + public Set 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 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 resultsMeta = Collections.emptySet(); + Set resultsMetaAny = Collections.emptySet(); + Set resultsMetaMulti = new HashSet<>(); + Set resultsMetaAnyMulti = Collections.emptySet(); + Set resultsBase = Collections.emptySet(); + Set resultsBaseAny = Collections.emptySet(); + Set resultsBaseAnyMulti = Collections.emptySet(); + + 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 expectedNames = new HashSet(Arrays.asList(annotatedElementInfo.names())); - - resultsMeta = - roundEnvironment. - getElementsAnnotatedWith(elements.getTypeElement(annotatedElementInfo.annotationName())); - - if (!resultsMeta.isEmpty()) - System.err.println("Results: " + resultsMeta); - - if (resultsMeta.size() != annotatedElementInfo.expectedSize()) { - failed = true; - System.err.printf("Bad number of elements; expected %d, got %d%n", - annotatedElementInfo.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."); - } + Objects.requireNonNull(annotatedElemInfo, + "Missing AnnotatedElementInfo annotation on " + firstType); + + // Verify that the annotation information is as expected. + Set 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.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", + 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(roundEnvironment, annotatedElementInfo.annotationName()); + resultsBase = computeResultsBase(re, annotationName); + resultsBaseAny = computeResultsBaseAny(re, annotationName); + try { + Set> 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); + } + + if (!resultsBase.equals(resultsBaseAny)) { + failed = true; + System.err.printf("Inconsistent Base with vs withAny results"); + } if (!resultsMeta.equals(resultsBase)) { failed = true; @@ -121,29 +226,53 @@ "\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 results, String message) { + if (!results.isEmpty()) { + throw new RuntimeException("Nonempty " + message + "\t" + results); } - return true; } - private Set computeResultsBase(RoundEnvironment roundEnvironment, String name) { + private Set 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 computeResultsBaseAny(RoundEnvironment roundEnv, String name) { + try { + return roundEnv. + getElementsAnnotatedWithAny(Set.of(Class.forName(name).asSubclass(Annotation.class))); + } catch (ClassNotFoundException cnfe) { throw new RuntimeException(cnfe); } } @@ -152,18 +281,28 @@ * Verify non-annotation types result in * IllegalArgumentExceptions. */ - private void testNonAnnotations(RoundEnvironment roundEnvironment) { + private void testNonAnnotations(RoundEnvironment roundEnv) { + Class objectClass = (Class)Object.class; + Set 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 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 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) {} } }