< 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 >