1 /* 2 * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.annotation.processing; 27 28 import javax.lang.model.element.Element; 29 import javax.lang.model.element.TypeElement; 30 import java.util.LinkedHashSet; 31 import java.util.Collections; 32 import java.util.Set; 33 import java.lang.annotation.Annotation; 34 35 /** 36 * An annotation processing tool framework will {@linkplain 37 * Processor#process provide an annotation processor with an object 38 * implementing this interface} so that the processor can query for 39 * information about a round of annotation processing. 40 * 41 * @author Joseph D. Darcy 42 * @author Scott Seligman 43 * @author Peter von der Ahé 44 * @since 1.6 45 */ 46 public interface RoundEnvironment { 47 /** 48 * {@return {@code true} if types generated by this round will not 49 * be subject to a subsequent round of annotation processing; 50 * returns {@code false} otherwise} 51 */ processingOver()52 boolean processingOver(); 53 54 /** 55 * {@return {@code true} if an error was raised in the prior round 56 * of processing; returns {@code false} otherwise} 57 */ errorRaised()58 boolean errorRaised(); 59 60 /** 61 * Returns the {@linkplain Processor root elements} for annotation processing generated 62 * by the prior round. 63 * 64 * @return the root elements for annotation processing generated 65 * by the prior round, or an empty set if there were none 66 */ getRootElements()67 Set<? extends Element> getRootElements(); 68 69 /** 70 * Returns the elements annotated with the given annotation type. 71 * The annotation may appear directly or be inherited. Only 72 * package elements, module elements, and type elements <i>included</i> in this 73 * round of annotation processing, or declarations of members, 74 * constructors, parameters, type parameters, or record components 75 * declared within those, are returned. Included type elements are {@linkplain 76 * #getRootElements root types} and any member types nested within 77 * them. Elements of a package are not considered included simply 78 * because a {@code package-info} file for that package was 79 * created. 80 * Likewise, elements of a module are not considered included 81 * simply because a {@code module-info} file for that module was 82 * created. 83 * 84 * @param a annotation type being requested 85 * @return the elements annotated with the given annotation type, 86 * or an empty set if there are none 87 * @throws IllegalArgumentException if the argument does not 88 * represent an annotation type 89 */ getElementsAnnotatedWith(TypeElement a)90 Set<? extends Element> getElementsAnnotatedWith(TypeElement a); 91 92 /** 93 * Returns the elements annotated with one or more of the given 94 * annotation types. 95 * 96 * @apiNote This method may be useful when processing repeating 97 * annotations by looking for an annotation type and its 98 * containing annotation type at the same time. 99 * 100 * @implSpec The default implementation of this method creates an 101 * empty result set, iterates over the annotations in the argument 102 * array calling {@link #getElementsAnnotatedWith(TypeElement)} on 103 * each annotation and adding those results to the result 104 * set. Finally, the contents of the result set are returned as an 105 * unmodifiable set. 106 * 107 * @param annotations annotation types being requested 108 * @return the elements annotated with one or more of the given 109 * annotation types, or an empty set if there are none 110 * @throws IllegalArgumentException if the any elements of the 111 * argument set do not represent an annotation type 112 * @jls 9.6.3 Repeatable Annotation Interfaces 113 * @since 9 114 */ getElementsAnnotatedWithAny(TypeElement... annotations)115 default Set<? extends Element> getElementsAnnotatedWithAny(TypeElement... annotations){ 116 // Use LinkedHashSet rather than HashSet for predictability 117 Set<Element> result = new LinkedHashSet<>(); 118 for (TypeElement annotation : annotations) { 119 result.addAll(getElementsAnnotatedWith(annotation)); 120 } 121 return Collections.unmodifiableSet(result); 122 } 123 124 /** 125 * Returns the elements annotated with the given annotation type. 126 * The annotation may appear directly or be inherited. Only 127 * package elements, module elements, and type elements <i>included</i> in this 128 * round of annotation processing, or declarations of members, 129 * constructors, parameters, type parameters, or record components 130 * declared within those, are returned. Included type elements are {@linkplain 131 * #getRootElements root types} and any member types nested within 132 * them. Elements in a package are not considered included simply 133 * because a {@code package-info} file for that package was 134 * created. 135 * Likewise, elements of a module are not considered included 136 * simply because a {@code module-info} file for that module was 137 * created. 138 * 139 * <p> Note: An implementation of this method typically performs 140 * an internal conversion from the runtime reflective 141 * representation of an annotation type as a {@code Class} object 142 * to a different representation used for annotation 143 * processing. The set of annotation types present in the runtime 144 * context may differ from the set of annotation types present in 145 * the context of annotation processing in a particular 146 * environmental configuration. If an runtime annotation type is 147 * not present in the annotation processing context, the situation 148 * is not treated as an error and no elements are found for that 149 * annotation type. 150 * 151 * @param a annotation type being requested 152 * @return the elements annotated with the given annotation type, 153 * or an empty set if there are none 154 * @throws IllegalArgumentException if the argument does not 155 * represent an annotation type 156 * 157 * @see javax.lang.model.AnnotatedConstruct#getAnnotation(Class) 158 * @see javax.lang.model.AnnotatedConstruct#getAnnotationsByType(Class) 159 */ getElementsAnnotatedWith(Class<? extends Annotation> a)160 Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> a); 161 162 /** 163 * Returns the elements annotated with one or more of the given 164 * annotation types. 165 * 166 * <p> Note: An implementation of this method typically performs 167 * an internal conversion from the runtime reflective 168 * representation of an annotation type as a {@code Class} object 169 * to a different representation used for annotation 170 * processing. The set of annotation types present in the runtime 171 * context may differ from the set of annotation types present in 172 * the context of annotation processing in a particular 173 * environmental configuration. If an runtime annotation type is 174 * not present in the annotation processing context, the situation 175 * is not treated as an error and no elements are found for that 176 * annotation type. 177 * 178 * @apiNote This method may be useful when processing repeating 179 * annotations by looking for an annotation type and its 180 * containing annotation type at the same time. 181 * 182 * @implSpec The default implementation of this method creates an 183 * empty result set, iterates over the annotations in the argument 184 * set calling {@link #getElementsAnnotatedWith(Class)} on 185 * each annotation and adding those results to the result 186 * set. Finally, the contents of the result set are returned as an 187 * unmodifiable set. 188 * 189 * @param annotations annotation types being requested 190 * @return the elements annotated with one or more of the given 191 * annotation types, or an empty set if there are none 192 * @throws IllegalArgumentException if the any elements of the 193 * argument set do not represent an annotation type 194 * @jls 9.6.3 Repeatable Annotation Interfaces 195 * 196 * @see javax.lang.model.AnnotatedConstruct#getAnnotation(Class) 197 * @see javax.lang.model.AnnotatedConstruct#getAnnotationsByType(Class) 198 * 199 * @since 9 200 */ getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> annotations)201 default Set<? extends Element> getElementsAnnotatedWithAny(Set<Class<? extends Annotation>> annotations){ 202 // Use LinkedHashSet rather than HashSet for predictability 203 Set<Element> result = new LinkedHashSet<>(); 204 for (Class<? extends Annotation> annotation : annotations) { 205 result.addAll(getElementsAnnotatedWith(annotation)); 206 } 207 return Collections.unmodifiableSet(result); 208 } 209 } 210