JavacRoundEnvironment.java revision 3434:487e6d33c635
1122580Sanholt/* 2145132Sanholt * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 3122580Sanholt * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4145132Sanholt * 5122580Sanholt * This code is free software; you can redistribute it and/or modify it 695584Sanholt * under the terms of the GNU General Public License version 2 only, as 7122580Sanholt * published by the Free Software Foundation. Oracle designates this 8122580Sanholt * particular file as subject to the "Classpath" exception as provided 9122580Sanholt * by Oracle in the LICENSE file that accompanied this code. 10122580Sanholt * 11139749Simp * This code is distributed in the hope that it will be useful, but WITHOUT 1295584Sanholt * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1395584Sanholt * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1495584Sanholt * version 2 for more details (a copy is included in the LICENSE file that 1595584Sanholt * accompanied this code). 1695584Sanholt * 1795584Sanholt * You should have received a copy of the GNU General Public License version 1895584Sanholt * 2 along with this work; if not, write to the Free Software Foundation, 1995584Sanholt * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2095584Sanholt * 2195584Sanholt * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2295584Sanholt * or visit www.oracle.com if you need additional information or have any 2395584Sanholt * questions. 2495584Sanholt */ 2595584Sanholt 2695584Sanholtpackage com.sun.tools.javac.processing; 2795584Sanholt 2895584Sanholtimport java.lang.annotation.Annotation; 2995584Sanholtimport javax.annotation.processing.*; 3095584Sanholtimport javax.lang.model.element.*; 3195584Sanholtimport javax.lang.model.util.*; 3295584Sanholtimport java.util.*; 3395584Sanholt 3495584Sanholtimport com.sun.tools.javac.util.DefinedBy; 3595584Sanholtimport com.sun.tools.javac.util.DefinedBy.Api; 36152909Sanholt 37152909Sanholt/** 38152909Sanholt * Object providing state about a prior round of annotation processing. 39145132Sanholt * 40145132Sanholt * <p>The methods in this class do not take type annotations into account, 41145132Sanholt * as target types, not java elements. 42145132Sanholt * 43145132Sanholt * <p><b>This is NOT part of any supported API. 44145132Sanholt * If you write code that depends on this, you do so at your own risk. 45145132Sanholt * This code and its internal interfaces are subject to change or 46145132Sanholt * deletion without notice.</b> 47145132Sanholt */ 48145132Sanholtpublic class JavacRoundEnvironment implements RoundEnvironment { 49145132Sanholt // Default equals and hashCode methods are okay. 50145132Sanholt 51145132Sanholt private final boolean processingOver; 52145132Sanholt private final boolean errorRaised; 53145132Sanholt private final ProcessingEnvironment processingEnv; 54145132Sanholt private final Elements eltUtils; 55145132Sanholt 56145132Sanholt // Caller must pass in an immutable set 57145132Sanholt private final Set<? extends Element> rootElements; 58145132Sanholt 59145132Sanholt JavacRoundEnvironment(boolean processingOver, 60122580Sanholt boolean errorRaised, 6195584Sanholt Set<? extends Element> rootElements, 6295584Sanholt ProcessingEnvironment processingEnv) { 6395584Sanholt this.processingOver = processingOver; 64145132Sanholt this.errorRaised = errorRaised; 65145132Sanholt this.rootElements = rootElements; 66145132Sanholt this.processingEnv = processingEnv; 67182080Srnoland this.eltUtils = processingEnv.getElementUtils(); 68182080Srnoland } 69182080Srnoland 70145132Sanholt public String toString() { 71152909Sanholt return String.format("[errorRaised=%b, rootElements=%s, processingOver=%b]", 72152909Sanholt errorRaised, 73152909Sanholt rootElements, 74152909Sanholt processingOver); 75152909Sanholt } 76152909Sanholt 77112015Sanholt @DefinedBy(Api.ANNOTATION_PROCESSING) 7895584Sanholt public boolean processingOver() { 79112015Sanholt return processingOver; 80112015Sanholt } 81112015Sanholt 82112015Sanholt /** 83112015Sanholt * Returns {@code true} if an error was raised in the prior round 84112015Sanholt * of processing; returns {@code false} otherwise. 85158683Sanholt * 8695584Sanholt * @return {@code true} if an error was raised in the prior round 87112015Sanholt * of processing; returns {@code false} otherwise. 88112015Sanholt */ 89112015Sanholt @DefinedBy(Api.ANNOTATION_PROCESSING) 90112015Sanholt public boolean errorRaised() { 91112015Sanholt return errorRaised; 92112015Sanholt } 93112015Sanholt 9495584Sanholt /** 95122580Sanholt * Returns the type elements specified by the prior round. 96122580Sanholt * 97122580Sanholt * @return the types elements specified by the prior round, or an 98122580Sanholt * empty set if there were none 99122580Sanholt */ 100122580Sanholt @DefinedBy(Api.ANNOTATION_PROCESSING) 101157617Sanholt public Set<? extends Element> getRootElements() { 102182080Srnoland return rootElements; 103122580Sanholt } 104122580Sanholt 105122580Sanholt /** 106122580Sanholt * Returns the elements annotated with the given annotation type. 10795584Sanholt * Only type elements <i>included</i> in this round of annotation 108145132Sanholt * processing, or declarations of members, parameters, or type 109145132Sanholt * parameters declared within those, are returned. Included type 11095584Sanholt * elements are {@linkplain #getRootElements specified 11195584Sanholt * types} and any types nested within them. 11295584Sanholt * 11395584Sanholt * @param a annotation type being requested 114152909Sanholt * @return the elements annotated with the given annotation type, 115152909Sanholt * or an empty set if there are none 116152909Sanholt */ 117182080Srnoland @DefinedBy(Api.ANNOTATION_PROCESSING) 118145132Sanholt public Set<? extends Element> getElementsAnnotatedWith(TypeElement a) { 119152909Sanholt throwIfNotAnnotation(a); 120145132Sanholt 121145132Sanholt Set<Element> result = Collections.emptySet(); 122145132Sanholt ElementScanner9<Set<Element>, TypeElement> scanner = 123122580Sanholt new AnnotationSetScanner(result); 124122580Sanholt 125122580Sanholt for (Element element : rootElements) 126145132Sanholt result = scanner.scan(element, a); 127145132Sanholt 128122580Sanholt return result; 129122580Sanholt } 130122580Sanholt 131112015Sanholt @DefinedBy(Api.ANNOTATION_PROCESSING) 132112015Sanholt public Set<? extends Element> getElementsAnnotatedWithAny(TypeElement... annotations) { 133182080Srnoland // Don't bother to special-case annotations.length == 1 as 134145132Sanholt // return getElementsAnnotatedWith(annotations[0]); 135145132Sanholt 136145132Sanholt Set<TypeElement> annotationSet = new LinkedHashSet<>(annotations.length); 137145132Sanholt for (TypeElement annotation : annotations) { 138182080Srnoland throwIfNotAnnotation(annotation); 13995584Sanholt annotationSet.add(annotation); 140122580Sanholt } 141122580Sanholt 142122580Sanholt Set<Element> result = Collections.emptySet(); 143182080Srnoland ElementScanner9<Set<Element>, Set<TypeElement>> scanner = 144145132Sanholt new AnnotationSetMultiScanner(result); 145145132Sanholt 146145132Sanholt for (Element element : rootElements) 147145132Sanholt result = scanner.scan(element, annotationSet); 148145132Sanholt 149182080Srnoland return result; 15095584Sanholt } 151130331Sanholt 152130331Sanholt // Could be written as a local class inside getElementsAnnotatedWith 153130331Sanholt private class AnnotationSetScanner extends 154130331Sanholt ElementScanningIncludingTypeParameters<Set<Element>, TypeElement> { 155130331Sanholt // Insertion-order preserving set 156130331Sanholt private Set<Element> annotatedElements = new LinkedHashSet<>(); 157130331Sanholt 158182080Srnoland AnnotationSetScanner(Set<Element> defaultSet) { 159130331Sanholt super(defaultSet); 160145132Sanholt } 161182080Srnoland 162122580Sanholt @Override @DefinedBy(Api.LANGUAGE_MODEL) 163145132Sanholt public Set<Element> scan(Element e, TypeElement annotation) { 164145132Sanholt for (AnnotationMirror annotMirror : eltUtils.getAllAnnotationMirrors(e)) { 165145132Sanholt if (annotation.equals(mirrorAsElement(annotMirror))) { 166145132Sanholt annotatedElements.add(e); 167145132Sanholt break; 168145132Sanholt } 169145132Sanholt } 170145132Sanholt e.accept(this, annotation); 171130331Sanholt return annotatedElements; 172145132Sanholt } 173145132Sanholt } 174145132Sanholt 175145132Sanholt // Could be written as a local class inside getElementsAnnotatedWithAny 176145132Sanholt private class AnnotationSetMultiScanner extends 177145132Sanholt ElementScanningIncludingTypeParameters<Set<Element>, Set<TypeElement>> { 178145132Sanholt // Insertion-order preserving set 179122580Sanholt private Set<Element> annotatedElements = new LinkedHashSet<>(); 180122580Sanholt 181145132Sanholt AnnotationSetMultiScanner(Set<Element> defaultSet) { 182122580Sanholt super(defaultSet); 183122580Sanholt } 184182080Srnoland 185145132Sanholt @Override @DefinedBy(Api.LANGUAGE_MODEL) 186145132Sanholt public Set<Element> scan(Element e, Set<TypeElement> annotations) { 187145132Sanholt for (AnnotationMirror annotMirror : eltUtils.getAllAnnotationMirrors(e)) { 188145132Sanholt if (annotations.contains(mirrorAsElement(annotMirror))) { 189145132Sanholt annotatedElements.add(e); 190145132Sanholt break; 191145132Sanholt } 192145132Sanholt } 193145132Sanholt e.accept(this, annotations); 194182080Srnoland return annotatedElements; 19595584Sanholt } 196122580Sanholt } 197122580Sanholt 198122580Sanholt private static abstract class ElementScanningIncludingTypeParameters<R, P> 199122580Sanholt extends ElementScanner9<R, P> { 200122580Sanholt 201182080Srnoland protected ElementScanningIncludingTypeParameters(R defaultValue) { 202145132Sanholt super(defaultValue); 203145132Sanholt } 204182080Srnoland 20595584Sanholt @Override @DefinedBy(Api.LANGUAGE_MODEL) 206145132Sanholt public R visitType(TypeElement e, P p) { 207122580Sanholt // Type parameters are not considered to be enclosed by a type 208182080Srnoland scan(e.getTypeParameters(), p); 209145132Sanholt return super.visitType(e, p); 210182080Srnoland } 211182080Srnoland 21295584Sanholt @Override @DefinedBy(Api.LANGUAGE_MODEL) 213182080Srnoland public R visitExecutable(ExecutableElement e, P p) { 214145132Sanholt // Type parameters are not considered to be enclosed by an executable 215182080Srnoland scan(e.getTypeParameters(), p); 21695584Sanholt return super.visitExecutable(e, p); 217122580Sanholt } 218122580Sanholt } 219122580Sanholt 220122580Sanholt /** 221122580Sanholt * {@inheritDoc} 222182080Srnoland */ 22395584Sanholt @DefinedBy(Api.ANNOTATION_PROCESSING) 22495584Sanholt public Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a) { 22595584Sanholt throwIfNotAnnotation(a); 22695584Sanholt String name = a.getCanonicalName(); 22795584Sanholt if (name == null) 228145132Sanholt return Collections.emptySet(); 229145132Sanholt else { 230182080Srnoland TypeElement annotationType = eltUtils.getTypeElement(name); 23195584Sanholt if (annotationType == null) 232122580Sanholt return Collections.emptySet(); 233122580Sanholt else 234122580Sanholt return getElementsAnnotatedWith(annotationType); 235182080Srnoland } 236145132Sanholt } 237145132Sanholt 238145132Sanholt @DefinedBy(Api.ANNOTATION_PROCESSING) 239145132Sanholt public Set<? extends Element> getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> annotations) { 240145132Sanholt List<TypeElement> annotationsAsElements = new ArrayList<>(annotations.size()); 241182080Srnoland 242182080Srnoland for (Class<? extends Annotation> annotation : annotations) { 243182080Srnoland throwIfNotAnnotation(annotation); 24495584Sanholt String name = annotation.getCanonicalName(); 245122580Sanholt if (name == null) 246122580Sanholt continue; 247122580Sanholt annotationsAsElements.add(eltUtils.getTypeElement(name)); 248182080Srnoland } 249145132Sanholt 250145132Sanholt return getElementsAnnotatedWithAny(annotationsAsElements.toArray(new TypeElement[0])); 251145132Sanholt } 252145132Sanholt 253122580Sanholt private Element mirrorAsElement(AnnotationMirror annotationMirror) { 254145132Sanholt return annotationMirror.getAnnotationType().asElement(); 255182080Srnoland } 256182080Srnoland 257182080Srnoland private static final String NOT_AN_ANNOTATION_TYPE = 25895584Sanholt "The argument does not represent an annotation type: "; 259182080Srnoland 260145132Sanholt private void throwIfNotAnnotation(Class<? extends Annotation> a) { 261145132Sanholt if (!a.isAnnotation()) 262182080Srnoland throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a); 26395584Sanholt } 264122580Sanholt 265122580Sanholt private void throwIfNotAnnotation(TypeElement a) { 266122580Sanholt if (a.getKind() != ElementKind.ANNOTATION_TYPE) 267122580Sanholt throw new IllegalArgumentException(NOT_AN_ANNOTATION_TYPE + a); 268122580Sanholt } 269122580Sanholt} 270182080Srnoland