--- old/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java 2016-05-24 00:15:21.553929585 -0700 +++ new/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java 2016-05-24 00:15:21.465929586 -0700 @@ -51,6 +51,7 @@ 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 rootElements; @@ -63,6 +64,7 @@ this.errorRaised = errorRaised; this.rootElements = rootElements; this.processingEnv = processingEnv; + this.eltUtils = processingEnv.getElementUtils(); } public String toString() { @@ -117,10 +119,9 @@ */ @DefinedBy(Api.ANNOTATION_PROCESSING) public Set getElementsAnnotatedWith(TypeElement a) { - Set result = Collections.emptySet(); - if (a.getKind() != ElementKind.ANNOTATION_TYPE) - throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a); + throwIfNotAnnotation(a); + Set result = Collections.emptySet(); ElementScanner9, TypeElement> scanner = new AnnotationSetScanner(result); @@ -130,34 +131,60 @@ return result; } - // Could be written as a local class inside getElementsAnnotatedWith - private class AnnotationSetScanner extends - ElementScanner9, TypeElement> { - // Insertion-order preserving set - Set annotatedElements = new LinkedHashSet<>(); + @DefinedBy(Api.ANNOTATION_PROCESSING) + public Set getElementsAnnotatedWithAny(TypeElement... annotations) { + Set annotationSet = new LinkedHashSet<>(annotations.length); + for (TypeElement annotation : annotations) { + throwIfNotAnnotation(annotation); + annotationSet.add(annotation); + } - AnnotationSetScanner(Set defaultSet) { - super(defaultSet); + Set result = Collections.emptySet(); + ElementScanner9, Set> scanner = + new AnnotationSetMultiScanner(result); + + for (Element element : rootElements) + result = scanner.scan(element, annotationSet); + + return result; + } + + private static abstract class ElementScanningIncludingTypeParameters + extends ElementScanner9 { + + protected ElementScanningIncludingTypeParameters(R defaultValue) { + super(defaultValue); } @Override @DefinedBy(Api.LANGUAGE_MODEL) - public Set visitType(TypeElement e, TypeElement p) { + 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 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); } + } + + // Could be written as a local class inside getElementsAnnotatedWith + private class AnnotationSetScanner extends + ElementScanningIncludingTypeParameters, TypeElement> { + // Insertion-order preserving set + Set annotatedElements = new LinkedHashSet<>(); + + AnnotationSetScanner(Set defaultSet) { + super(defaultSet); + } @Override @DefinedBy(Api.LANGUAGE_MODEL) public Set scan(Element e, TypeElement p) { java.util.List annotationMirrors = - processingEnv.getElementUtils().getAllAnnotationMirrors(e); + eltUtils.getAllAnnotationMirrors(e); for (AnnotationMirror annotationMirror : annotationMirrors) { if (p.equals(annotationMirror.getAnnotationType().asElement())) annotatedElements.add(e); @@ -167,22 +194,68 @@ } } + private class AnnotationSetMultiScanner extends + ElementScanningIncludingTypeParameters, Set> { + // Insertion-order preserving set + Set annotatedElements = new LinkedHashSet<>(); + + AnnotationSetMultiScanner(Set defaultSet) { + super(defaultSet); + } + + @Override @DefinedBy(Api.LANGUAGE_MODEL) + public Set scan(Element e, Set p) { + java.util.List annotationMirrors = + eltUtils.getAllAnnotationMirrors(e); + for (AnnotationMirror annotationMirror : annotationMirrors) { + if (p.contains(annotationMirror.getAnnotationType().asElement())) + annotatedElements.add(e); + } + e.accept(this, p); + return annotatedElements; + } + } + /** * {@inheritDoc} */ @DefinedBy(Api.ANNOTATION_PROCESSING) public Set getElementsAnnotatedWith(Class 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 getElementsAnnotatedWithAny(Set> annotations) { + List annotationsAsElements = new ArrayList<>(annotations.size()); + + for (Class 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 void throwIfNotAnnotation(Class 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); + } }