mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
8032230: Enhance javax.a.p.RoundEnvironment after repeating annotations
Reviewed-by: jjg
This commit is contained in:
parent
de6399c1a3
commit
fff165ddd1
@ -27,6 +27,8 @@ package javax.annotation.processing;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
@ -91,6 +93,38 @@ public interface RoundEnvironment {
|
||||
*/
|
||||
Set<? extends Element> getElementsAnnotatedWith(TypeElement a);
|
||||
|
||||
/**
|
||||
* Returns the elements annotated with one or more of the given
|
||||
* annotation types.
|
||||
*
|
||||
* @apiNote This method may be useful when processing repeating
|
||||
* annotations by looking for an annotation type and its
|
||||
* containing annotation type at the same time.
|
||||
*
|
||||
* @implSpec The default implementation of this method creates an
|
||||
* empty result set, iterates over the annotations in the argument
|
||||
* set calling {@link #getElementsAnnotatedWith(TypeElement)} on
|
||||
* each annotation and adding those results to the result
|
||||
* set. Finally, the contents of the result set are returned as an
|
||||
* unmodifiable set.
|
||||
*
|
||||
* @param annotations annotation types being requested
|
||||
* @return the elements annotated with one or more of the given
|
||||
* annotation types, or an empty set if there are none
|
||||
* @throws IllegalArgumentException if the any elements of the
|
||||
* argument set do not represent an annotation type
|
||||
* @jls 9.6.3 Repeatable Annotation Types
|
||||
* @since 9
|
||||
*/
|
||||
default Set<? extends Element> getElementsAnnotatedWithAny(TypeElement... annotations){
|
||||
// Use LinkedHashSet rather than HashSet for predictability
|
||||
Set<Element> result = new LinkedHashSet<>();
|
||||
for (TypeElement annotation : annotations) {
|
||||
result.addAll(getElementsAnnotatedWith(annotation));
|
||||
}
|
||||
return Collections.unmodifiableSet(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the elements annotated with the given annotation type.
|
||||
* The annotation may appear directly or be inherited. Only
|
||||
@ -110,4 +144,36 @@ public interface RoundEnvironment {
|
||||
* represent an annotation type
|
||||
*/
|
||||
Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a);
|
||||
|
||||
/**
|
||||
* Returns the elements annotated with one or more of the given
|
||||
* annotation types.
|
||||
*
|
||||
* @apiNote This method may be useful when processing repeating
|
||||
* annotations by looking for an annotation type and its
|
||||
* containing annotation type at the same time.
|
||||
*
|
||||
* @implSpec The default implementation of this method creates an
|
||||
* empty result set, iterates over the annotations in the argument
|
||||
* set calling {@link #getElementsAnnotatedWith(Class)} on
|
||||
* each annotation and adding those results to the result
|
||||
* set. Finally, the contents of the result set are returned as an
|
||||
* unmodifiable set.
|
||||
*
|
||||
* @param annotations annotation types being requested
|
||||
* @return the elements annotated with one or more of the given
|
||||
* annotation types, or an empty set if there are none
|
||||
* @throws IllegalArgumentException if the any elements of the
|
||||
* argument set do not represent an annotation type
|
||||
* @jls 9.6.3 Repeatable Annotation Types
|
||||
* @since 9
|
||||
*/
|
||||
default Set<? extends Element> getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> annotations){
|
||||
// Use LinkedHashSet rather than HashSet for predictability
|
||||
Set<Element> result = new LinkedHashSet<>();
|
||||
for (Class<? extends Annotation> annotation : annotations) {
|
||||
result.addAll(getElementsAnnotatedWith(annotation));
|
||||
}
|
||||
return Collections.unmodifiableSet(result);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2016, 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
|
||||
@ -51,6 +51,7 @@ public class JavacRoundEnvironment implements RoundEnvironment {
|
||||
private final boolean processingOver;
|
||||
private final boolean errorRaised;
|
||||
private final ProcessingEnvironment processingEnv;
|
||||
private final Elements eltUtils;
|
||||
|
||||
// Caller must pass in an immutable set
|
||||
private final Set<? extends Element> rootElements;
|
||||
@ -63,6 +64,7 @@ public class JavacRoundEnvironment implements RoundEnvironment {
|
||||
this.errorRaised = errorRaised;
|
||||
this.rootElements = rootElements;
|
||||
this.processingEnv = processingEnv;
|
||||
this.eltUtils = processingEnv.getElementUtils();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@ -100,9 +102,6 @@ public class JavacRoundEnvironment implements RoundEnvironment {
|
||||
return rootElements;
|
||||
}
|
||||
|
||||
private static final String NOT_AN_ANNOTATION_TYPE =
|
||||
"The argument does not represent an annotation type: ";
|
||||
|
||||
/**
|
||||
* Returns the elements annotated with the given annotation type.
|
||||
* Only type elements <i>included</i> in this round of annotation
|
||||
@ -117,10 +116,9 @@ public class JavacRoundEnvironment implements RoundEnvironment {
|
||||
*/
|
||||
@DefinedBy(Api.ANNOTATION_PROCESSING)
|
||||
public Set<? extends Element> getElementsAnnotatedWith(TypeElement a) {
|
||||
Set<Element> result = Collections.emptySet();
|
||||
if (a.getKind() != ElementKind.ANNOTATION_TYPE)
|
||||
throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
|
||||
throwIfNotAnnotation(a);
|
||||
|
||||
Set<Element> result = Collections.emptySet();
|
||||
ElementScanner9<Set<Element>, TypeElement> scanner =
|
||||
new AnnotationSetScanner(result);
|
||||
|
||||
@ -130,41 +128,93 @@ public class JavacRoundEnvironment implements RoundEnvironment {
|
||||
return result;
|
||||
}
|
||||
|
||||
@DefinedBy(Api.ANNOTATION_PROCESSING)
|
||||
public Set<? extends Element> getElementsAnnotatedWithAny(TypeElement... annotations) {
|
||||
// Don't bother to special-case annotations.length == 1 as
|
||||
// return getElementsAnnotatedWith(annotations[0]);
|
||||
|
||||
Set<TypeElement> annotationSet = new LinkedHashSet<>(annotations.length);
|
||||
for (TypeElement annotation : annotations) {
|
||||
throwIfNotAnnotation(annotation);
|
||||
annotationSet.add(annotation);
|
||||
}
|
||||
|
||||
Set<Element> result = Collections.emptySet();
|
||||
ElementScanner9<Set<Element>, Set<TypeElement>> scanner =
|
||||
new AnnotationSetMultiScanner(result);
|
||||
|
||||
for (Element element : rootElements)
|
||||
result = scanner.scan(element, annotationSet);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Could be written as a local class inside getElementsAnnotatedWith
|
||||
private class AnnotationSetScanner extends
|
||||
ElementScanner9<Set<Element>, TypeElement> {
|
||||
ElementScanningIncludingTypeParameters<Set<Element>, TypeElement> {
|
||||
// Insertion-order preserving set
|
||||
Set<Element> annotatedElements = new LinkedHashSet<>();
|
||||
private Set<Element> annotatedElements = new LinkedHashSet<>();
|
||||
|
||||
AnnotationSetScanner(Set<Element> defaultSet) {
|
||||
super(defaultSet);
|
||||
}
|
||||
|
||||
@Override @DefinedBy(Api.LANGUAGE_MODEL)
|
||||
public Set<Element> visitType(TypeElement e, TypeElement p) {
|
||||
public Set<Element> scan(Element e, TypeElement annotation) {
|
||||
for (AnnotationMirror annotMirror : eltUtils.getAllAnnotationMirrors(e)) {
|
||||
if (annotation.equals(mirrorAsElement(annotMirror))) {
|
||||
annotatedElements.add(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
e.accept(this, annotation);
|
||||
return annotatedElements;
|
||||
}
|
||||
}
|
||||
|
||||
// Could be written as a local class inside getElementsAnnotatedWithAny
|
||||
private class AnnotationSetMultiScanner extends
|
||||
ElementScanningIncludingTypeParameters<Set<Element>, Set<TypeElement>> {
|
||||
// Insertion-order preserving set
|
||||
private Set<Element> annotatedElements = new LinkedHashSet<>();
|
||||
|
||||
AnnotationSetMultiScanner(Set<Element> defaultSet) {
|
||||
super(defaultSet);
|
||||
}
|
||||
|
||||
@Override @DefinedBy(Api.LANGUAGE_MODEL)
|
||||
public Set<Element> scan(Element e, Set<TypeElement> annotations) {
|
||||
for (AnnotationMirror annotMirror : eltUtils.getAllAnnotationMirrors(e)) {
|
||||
if (annotations.contains(mirrorAsElement(annotMirror))) {
|
||||
annotatedElements.add(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
e.accept(this, annotations);
|
||||
return annotatedElements;
|
||||
}
|
||||
}
|
||||
|
||||
private static abstract class ElementScanningIncludingTypeParameters<R, P>
|
||||
extends ElementScanner9<R, P> {
|
||||
|
||||
protected ElementScanningIncludingTypeParameters(R defaultValue) {
|
||||
super(defaultValue);
|
||||
}
|
||||
|
||||
@Override @DefinedBy(Api.LANGUAGE_MODEL)
|
||||
public R visitType(TypeElement e, P p) {
|
||||
// Type parameters are not considered to be enclosed by a type
|
||||
scan(e.getTypeParameters(), p);
|
||||
return super.visitType(e, p);
|
||||
}
|
||||
|
||||
@Override @DefinedBy(Api.LANGUAGE_MODEL)
|
||||
public Set<Element> visitExecutable(ExecutableElement e, TypeElement p) {
|
||||
public R visitExecutable(ExecutableElement e, P p) {
|
||||
// Type parameters are not considered to be enclosed by an executable
|
||||
scan(e.getTypeParameters(), p);
|
||||
return super.visitExecutable(e, p);
|
||||
}
|
||||
|
||||
@Override @DefinedBy(Api.LANGUAGE_MODEL)
|
||||
public Set<Element> scan(Element e, TypeElement p) {
|
||||
java.util.List<? extends AnnotationMirror> annotationMirrors =
|
||||
processingEnv.getElementUtils().getAllAnnotationMirrors(e);
|
||||
for (AnnotationMirror annotationMirror : annotationMirrors) {
|
||||
if (p.equals(annotationMirror.getAnnotationType().asElement()))
|
||||
annotatedElements.add(e);
|
||||
}
|
||||
e.accept(this, p);
|
||||
return annotatedElements;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,17 +222,48 @@ public class JavacRoundEnvironment implements RoundEnvironment {
|
||||
*/
|
||||
@DefinedBy(Api.ANNOTATION_PROCESSING)
|
||||
public Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a) {
|
||||
if (!a.isAnnotation())
|
||||
throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
|
||||
throwIfNotAnnotation(a);
|
||||
String name = a.getCanonicalName();
|
||||
if (name == null)
|
||||
return Collections.emptySet();
|
||||
else {
|
||||
TypeElement annotationType = processingEnv.getElementUtils().getTypeElement(name);
|
||||
TypeElement annotationType = eltUtils.getTypeElement(name);
|
||||
if (annotationType == null)
|
||||
return Collections.emptySet();
|
||||
else
|
||||
return getElementsAnnotatedWith(annotationType);
|
||||
}
|
||||
}
|
||||
|
||||
@DefinedBy(Api.ANNOTATION_PROCESSING)
|
||||
public Set<? extends Element> getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> annotations) {
|
||||
List<TypeElement> annotationsAsElements = new ArrayList<>(annotations.size());
|
||||
|
||||
for (Class<? extends Annotation> annotation : annotations) {
|
||||
throwIfNotAnnotation(annotation);
|
||||
String name = annotation.getCanonicalName();
|
||||
if (name == null)
|
||||
continue;
|
||||
annotationsAsElements.add(eltUtils.getTypeElement(name));
|
||||
}
|
||||
|
||||
return getElementsAnnotatedWithAny(annotationsAsElements.toArray(new TypeElement[0]));
|
||||
}
|
||||
|
||||
private Element mirrorAsElement(AnnotationMirror annotationMirror) {
|
||||
return annotationMirror.getAnnotationType().asElement();
|
||||
}
|
||||
|
||||
private static final String NOT_AN_ANNOTATION_TYPE =
|
||||
"The argument does not represent an annotation type: ";
|
||||
|
||||
private void throwIfNotAnnotation(Class<? extends Annotation> a) {
|
||||
if (!a.isAnnotation())
|
||||
throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
|
||||
}
|
||||
|
||||
private void throwIfNotAnnotation(TypeElement a) {
|
||||
if (a.getKind() != ElementKind.ANNOTATION_TYPE)
|
||||
throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,183 @@ 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");
|
||||
Set<? extends Element> resultsMeta = Collections.emptySet();
|
||||
Set<? extends Element> resultsBase = Collections.emptySet();
|
||||
RoundEnvironment roundEnv) {
|
||||
// First check sets of annotated elements using the round
|
||||
// environment from the annotation processing tool framework.
|
||||
checkSetOfAnnotatedElements(roundEnv);
|
||||
|
||||
if (!roundEnvironment.processingOver()) {
|
||||
testNonAnnotations(roundEnvironment);
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* To allow testing of the executable code of the default methods
|
||||
* for the two overloaded getElementsAnnotatedWithAny methods
|
||||
* defined in the RoundEnvironment interface, this class delegates
|
||||
* the non-default methods of RoundEnvironment to a given
|
||||
* RoundEnvironment object and then explicitly calls the default
|
||||
* methods of the interface instead of relying on the object's
|
||||
* implementation of those methods.
|
||||
*/
|
||||
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 (!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.
|
||||
Objects.requireNonNull(annotatedElemInfo,
|
||||
"Missing AnnotatedElementInfo annotation on " + firstType);
|
||||
|
||||
Set<String> expectedNames = new HashSet<String>(Arrays.asList(annotatedElementInfo.names()));
|
||||
// Verify that the annotation information is as expected.
|
||||
Set<String> expectedNames =
|
||||
new HashSet<>(Arrays.asList(annotatedElemInfo.names()));
|
||||
|
||||
resultsMeta =
|
||||
roundEnvironment.
|
||||
getElementsAnnotatedWith(elements.getTypeElement(annotatedElementInfo.annotationName()));
|
||||
String annotationName = annotatedElemInfo.annotationName();
|
||||
TypeElement annotationTypeElem = elements.getTypeElement(annotationName);
|
||||
|
||||
if (!resultsMeta.isEmpty())
|
||||
System.err.println("Results: " + resultsMeta);
|
||||
resultsMeta = re.getElementsAnnotatedWith(annotationTypeElem);
|
||||
resultsMetaAny = re.getElementsAnnotatedWithAny(annotationTypeElem);
|
||||
resultsMetaMulti.addAll(resultsMeta);
|
||||
resultsMetaMulti.addAll(re.getElementsAnnotatedWith(annotatedElemInfoElem));
|
||||
resultsMetaAnyMulti = re.getElementsAnnotatedWithAny(annotationTypeElem, annotatedElemInfoElem);
|
||||
|
||||
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.");
|
||||
}
|
||||
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<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);
|
||||
}
|
||||
|
||||
if (!resultsBase.equals(resultsBaseAny)) {
|
||||
failed = true;
|
||||
System.err.printf("Inconsistent Base with vs withAny results");
|
||||
}
|
||||
|
||||
if (!resultsMeta.equals(resultsBase)) {
|
||||
failed = true;
|
||||
@ -121,29 +235,53 @@ public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor {
|
||||
"\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");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private Set<? extends Element> computeResultsBase(RoundEnvironment roundEnvironment, String name) {
|
||||
private void throwOnNonEmpty(Set<? extends Element> results, String message) {
|
||||
if (!results.isEmpty()) {
|
||||
throw new RuntimeException("Nonempty " + message + "\t" + results);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -152,18 +290,28 @@ public class TestElementsAnnotatedWith extends JavacTestingAbstractProcessor {
|
||||
* 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 {
|
||||
Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith((Class)Object.class );
|
||||
elements = roundEnv.getElementsAnnotatedWith(objectClass);
|
||||
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(Set.of(objectClass));
|
||||
throw new RuntimeException("Illegal argument exception not thrown");
|
||||
} catch(IllegalArgumentException iae) {}
|
||||
} catch (IllegalArgumentException iae) {}
|
||||
|
||||
TypeElement objectElement = processingEnv.getElementUtils().getTypeElement("java.lang.Object");
|
||||
try {
|
||||
elements = roundEnv.getElementsAnnotatedWith(objectElement);
|
||||
throw new RuntimeException("Illegal argument exception not thrown");
|
||||
} catch (IllegalArgumentException iae) {}
|
||||
|
||||
try {
|
||||
elements = roundEnv.getElementsAnnotatedWithAny(objectElement);
|
||||
throw new RuntimeException("Illegal argument exception not thrown");
|
||||
} catch (IllegalArgumentException iae) {}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user