< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java

Print this page

        

@@ -49,10 +49,11 @@
     // Default equals and hashCode methods are okay.
 
     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;
 
     JavacRoundEnvironment(boolean processingOver,

@@ -61,10 +62,11 @@
                           ProcessingEnvironment processingEnv) {
         this.processingOver = processingOver;
         this.errorRaised = errorRaised;
         this.rootElements = rootElements;
         this.processingEnv = processingEnv;
+        this.eltUtils = processingEnv.getElementUtils();
     }
 
     public String toString() {
         return String.format("[errorRaised=%b, rootElements=%s, processingOver=%b]",
                              errorRaised,

@@ -115,74 +117,145 @@
      * @return the elements annotated with the given annotation type,
      * or an empty set if there are none
      */
     @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);
 
         for (Element element : rootElements)
             result = scanner.scan(element, a);
 
         return result;
     }
 
-    // Could be written as a local class inside getElementsAnnotatedWith
-    private class AnnotationSetScanner extends
-        ElementScanner9<Set<Element>, TypeElement> {
-        // Insertion-order preserving set
-        Set<Element> annotatedElements = new LinkedHashSet<>();
+    @DefinedBy(Api.ANNOTATION_PROCESSING)
+    public Set<? extends Element> getElementsAnnotatedWithAny(TypeElement... annotations) {
+        Set<TypeElement> annotationSet = new LinkedHashSet<>(annotations.length);
+        for (TypeElement annotation : annotations) {
+            throwIfNotAnnotation(annotation);
+            annotationSet.add(annotation);
+        }
 
-        AnnotationSetScanner(Set<Element> defaultSet) {
-            super(defaultSet);
+        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;
+    }
+
+    private static abstract class ElementScanningIncludingTypeParameters<R, P>
+        extends ElementScanner9<R, P> {
+
+        protected ElementScanningIncludingTypeParameters(R defaultValue) {
+            super(defaultValue);
         }
 
         @Override @DefinedBy(Api.LANGUAGE_MODEL)
-        public Set<Element> 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<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);
         }
+    }
+
+    // Could be written as a local class inside getElementsAnnotatedWith
+    private class AnnotationSetScanner extends
+        ElementScanningIncludingTypeParameters<Set<Element>, TypeElement> {
+        // Insertion-order preserving set
+        Set<Element> annotatedElements = new LinkedHashSet<>();
+
+        AnnotationSetScanner(Set<Element> defaultSet) {
+            super(defaultSet);
+        }
 
         @Override @DefinedBy(Api.LANGUAGE_MODEL)
         public Set<Element> scan(Element e, TypeElement p) {
             java.util.List<? extends AnnotationMirror> annotationMirrors =
-                processingEnv.getElementUtils().getAllAnnotationMirrors(e);
+                eltUtils.getAllAnnotationMirrors(e);
             for (AnnotationMirror annotationMirror : annotationMirrors) {
                 if (p.equals(annotationMirror.getAnnotationType().asElement()))
                     annotatedElements.add(e);
             }
             e.accept(this, p);
             return annotatedElements;
         }
     }
 
+    private class AnnotationSetMultiScanner extends
+        ElementScanningIncludingTypeParameters<Set<Element>, Set<TypeElement>> {
+        // Insertion-order preserving set
+        Set<Element> annotatedElements = new LinkedHashSet<>();
+
+        AnnotationSetMultiScanner(Set<Element> defaultSet) {
+            super(defaultSet);
+        }
+
+        @Override @DefinedBy(Api.LANGUAGE_MODEL)
+        public Set<Element> scan(Element e, Set<TypeElement> p) {
+            java.util.List<? extends AnnotationMirror> 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<? 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 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);
+    }
 }
< prev index next >