< prev index next >
src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java
Print this page
*** 1,7 ****
/*
! * Copyright (c) 2005, 2014, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 49,58 ****
--- 49,59 ----
// 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,70 ****
--- 62,72 ----
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,
*** 98,110 ****
@DefinedBy(Api.ANNOTATION_PROCESSING)
public Set<? extends Element> getRootElements() {
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
* processing, or declarations of members, parameters, or type
* parameters declared within those, are returned. Included type
--- 100,109 ----
*** 115,188 ****
* @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);
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<>();
AnnotationSetScanner(Set<Element> defaultSet) {
super(defaultSet);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
! public Set<Element> visitType(TypeElement e, TypeElement 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) {
// 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;
- }
}
/**
* {@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);
String name = a.getCanonicalName();
if (name == null)
return Collections.emptySet();
else {
! TypeElement annotationType = processingEnv.getElementUtils().getTypeElement(name);
if (annotationType == null)
return Collections.emptySet();
else
return getElementsAnnotatedWith(annotationType);
}
}
}
--- 114,269 ----
* @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) {
! 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;
}
+ @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
! ElementScanningIncludingTypeParameters<Set<Element>, TypeElement> {
// Insertion-order preserving set
! private Set<Element> annotatedElements = new LinkedHashSet<>();
AnnotationSetScanner(Set<Element> defaultSet) {
super(defaultSet);
}
@Override @DefinedBy(Api.LANGUAGE_MODEL)
! 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 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);
}
}
/**
* {@inheritDoc}
*/
@DefinedBy(Api.ANNOTATION_PROCESSING)
public Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a) {
! throwIfNotAnnotation(a);
String name = a.getCanonicalName();
if (name == null)
return Collections.emptySet();
else {
! 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);
+ }
}
< prev index next >