Path: blob/master/src/java.compiler/share/classes/javax/lang/model/util/Elements.java
41161 views
/*1* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.lang.model.util;2627import java.util.Collections;28import java.util.List;29import java.util.Map;30import java.util.Set;31import java.util.LinkedHashSet;32import java.util.Objects;3334import javax.lang.model.AnnotatedConstruct;35import javax.lang.model.element.*;363738/**39* Utility methods for operating on program elements.40*41* <p><b>Compatibility Note:</b> Methods may be added to this interface42* in future releases of the platform.43*44* @author Joseph D. Darcy45* @author Scott Seligman46* @author Peter von der Ahé47* @see javax.annotation.processing.ProcessingEnvironment#getElementUtils48* @since 1.649*/50public interface Elements {5152/**53* Returns a package given its fully qualified name if the package is uniquely54* determinable in the environment.55*56* If running with modules, packages of the given name are searched in a57* two-stage process:58* <ul>59* <li>find non-empty packages with the given name returned by60* {@link #getPackageElement(ModuleElement, CharSequence)},61* where the provided ModuleSymbol is any62* <a href="../../../../../java.base/java/lang/module/package-summary.html#root-modules">root module</a>,63* </li>64* <li>if the above yields an empty list, search65* {@link #getAllModuleElements() all modules} for observable66* packages with the given name67* </li>68* </ul>69*70* If this process leads to a list with a single element,71* the single element is returned, otherwise null is returned.72*73* @param name fully qualified package name,74* or an empty string for an unnamed package75* @return the specified package,76* or {@code null} if no package can be uniquely determined.77*/78PackageElement getPackageElement(CharSequence name);7980/**81* Returns a package given its fully qualified name, as seen from the given module.82*83* @implSpec The default implementation of this method returns84* {@code null}.85*86* @param name fully qualified package name, or an empty string for an unnamed package87* @param module module relative to which the lookup should happen88* @return the specified package, or {@code null} if it cannot be found89* @see #getAllPackageElements90* @since 991*/92default PackageElement getPackageElement(ModuleElement module, CharSequence name) {93return null;94}9596/**97* Returns all package elements with the given canonical name.98*99* There may be more than one package element with the same canonical100* name if the package elements are in different modules.101*102* @implSpec The default implementation of this method calls103* {@link #getAllModuleElements() getAllModuleElements} and stores104* the result. If the set of modules is empty, {@link105* #getPackageElement(CharSequence) getPackageElement(name)} is106* called passing through the name argument. If {@code107* getPackageElement(name)} is {@code null}, an empty set of108* package elements is returned; otherwise, a single-element set109* with the found package element is returned. If the set of110* modules is nonempty, the modules are iterated over and any111* non-{@code null} results of {@link112* #getPackageElement(ModuleElement, CharSequence)113* getPackageElement(module, name)} are accumulated into a114* set. The set is then returned.115*116* @param name the canonical name117* @return the package elements, or an empty set if no package with the name can be found118* @see #getPackageElement(ModuleElement, CharSequence)119* @since 9120*/121default Set<? extends PackageElement> getAllPackageElements(CharSequence name) {122Set<? extends ModuleElement> modules = getAllModuleElements();123if (modules.isEmpty()) {124PackageElement packageElt = getPackageElement(name);125return (packageElt != null) ?126Collections.singleton(packageElt):127Collections.emptySet();128} else {129Set<PackageElement> result = new LinkedHashSet<>(1); // Usually expect at most 1 result130for (ModuleElement module: modules) {131PackageElement packageElt = getPackageElement(module, name);132if (packageElt != null)133result.add(packageElt);134}135return Collections.unmodifiableSet(result);136}137}138139/**140* Returns a type element given its canonical name if the type element is uniquely141* determinable in the environment.142*143* If running with modules, type elements of the given name are144* searched in a two-stage process:145* <ul>146* <li>find type elements with the given name returned by147* {@link #getTypeElement(ModuleElement, CharSequence)},148* where the provided ModuleSymbol is any149* <a href="../../../../../java.base/java/lang/module/package-summary.html#root-modules">root module</a>,150* </li>151* <li>if the above yields an empty list, search152* {@link #getAllModuleElements() all modules} for observable153* type elements with the given name154* </li>155* </ul>156*157* If this process leads to a list with a single element,158* the single element is returned, otherwise null is returned.159*160* @param name the canonical name161* @return the named type element,162* or {@code null} if no type element can be uniquely determined.163*/164TypeElement getTypeElement(CharSequence name);165166/**167* Returns a type element given its canonical name, as seen from the given module.168*169* @implSpec The default implementation of this method returns170* {@code null}.171*172* @param name the canonical name173* @param module module relative to which the lookup should happen174* @return the named type element, or {@code null} if it cannot be found175* @see #getAllTypeElements176* @since 9177*/178default TypeElement getTypeElement(ModuleElement module, CharSequence name) {179return null;180}181182/**183* Returns all type elements with the given canonical name.184*185* There may be more than one type element with the same canonical186* name if the type elements are in different modules.187*188* @implSpec The default implementation of this method calls189* {@link #getAllModuleElements() getAllModuleElements} and stores190* the result. If the set of modules is empty, {@link191* #getTypeElement(CharSequence) getTypeElement(name)} is called192* passing through the name argument. If {@code193* getTypeElement(name)} is {@code null}, an empty set of type194* elements is returned; otherwise, a single-element set with the195* found type element is returned. If the set of modules is196* nonempty, the modules are iterated over and any non-{@code null}197* results of {@link #getTypeElement(ModuleElement,198* CharSequence) getTypeElement(module, name)} are accumulated199* into a set. The set is then returned.200*201* @param name the canonical name202* @return the type elements, or an empty set if no type with the name can be found203* @see #getTypeElement(ModuleElement, CharSequence)204* @since 9205*/206default Set<? extends TypeElement> getAllTypeElements(CharSequence name) {207Set<? extends ModuleElement> modules = getAllModuleElements();208if (modules.isEmpty()) {209TypeElement typeElt = getTypeElement(name);210return (typeElt != null) ?211Collections.singleton(typeElt):212Collections.emptySet();213} else {214Set<TypeElement> result = new LinkedHashSet<>(1); // Usually expect at most 1 result215for (ModuleElement module: modules) {216TypeElement typeElt = getTypeElement(module, name);217if (typeElt != null)218result.add(typeElt);219}220return Collections.unmodifiableSet(result);221}222}223224/**225* Returns a module element given its fully qualified name.226*227* If the requested module cannot be found, {@code null} is228* returned. One situation where a module cannot be found is if229* the environment does not include modules, such as an annotation230* processing environment configured for a {@linkplain231* javax.annotation.processing.ProcessingEnvironment#getSourceVersion232* source version} without modules.233*234* @implSpec The default implementation of this method returns235* {@code null}.236*237* @param name the name, or an empty string for an unnamed module238* @return the named module element, or {@code null} if it cannot be found239* @see #getAllModuleElements240* @since 9241*/242default ModuleElement getModuleElement(CharSequence name) {243return null;244}245246/**247* Returns all module elements in the current environment.248*249* If no modules are present, an empty set is returned. One250* situation where no modules are present occurs when the251* environment does not include modules, such as an annotation252* processing environment configured for a {@linkplain253* javax.annotation.processing.ProcessingEnvironment#getSourceVersion254* source version} without modules.255*256* @implSpec The default implementation of this method returns257* an empty set.258*259* @return the known module elements, or an empty set if there are no modules260* @see #getModuleElement(CharSequence)261* @since 9262*/263default Set<? extends ModuleElement> getAllModuleElements() {264return Collections.emptySet();265}266267/**268* {@return the values of an annotation's elements, including defaults}269*270* @see AnnotationMirror#getElementValues()271* @param a annotation to examine272*/273Map<? extends ExecutableElement, ? extends AnnotationValue>274getElementValuesWithDefaults(AnnotationMirror a);275276/**277* Returns the text of the documentation ("Javadoc")278* comment of an element.279*280* <p> A documentation comment of an element is a comment that281* begins with "{@code /**}", ends with a separate282* "<code>*/</code>", and immediately precedes the element,283* ignoring white space. Therefore, a documentation comment284* contains at least three "{@code *}" characters. The text285* returned for the documentation comment is a processed form of286* the comment as it appears in source code. The leading "{@code /**}"287* and trailing "<code>*/</code>" are removed. For lines288* of the comment starting after the initial "{@code /**}",289* leading white space characters are discarded as are any290* consecutive "{@code *}" characters appearing after the white291* space or starting the line. The processed lines are then292* concatenated together (including line terminators) and293* returned.294*295* @param e the element being examined296* @return the documentation comment of the element, or {@code null}297* if there is none298* @jls 3.6 White Space299*/300String getDocComment(Element e);301302/**303* {@return {@code true} if the element is deprecated, {@code false} otherwise}304*305* @param e the element being examined306*/307boolean isDeprecated(Element e);308309/**310* {@return the <em>origin</em> of the given element}311*312* <p>Note that if this method returns {@link Origin#EXPLICIT313* EXPLICIT} and the element was created from a class file, then314* the element may not, in fact, correspond to an explicitly315* declared construct in source code. This is due to limitations316* of the fidelity of the class file format in preserving317* information from source code. For example, at least some318* versions of the class file format do not preserve whether a319* constructor was explicitly declared by the programmer or was320* implicitly declared as the <em>default constructor</em>.321*322* @implSpec The default implementation of this method returns323* {@link Origin#EXPLICIT EXPLICIT}.324*325* @param e the element being examined326* @since 9327*/328default Origin getOrigin(Element e) {329return Origin.EXPLICIT;330}331332/**333* {@return the <em>origin</em> of the given annotation mirror}334*335* An annotation mirror is {@linkplain Origin#MANDATED mandated}336* if it is an implicitly declared <em>container annotation</em>337* used to hold repeated annotations of a repeatable annotation338* interface.339*340* <p>Note that if this method returns {@link Origin#EXPLICIT341* EXPLICIT} and the annotation mirror was created from a class342* file, then the element may not, in fact, correspond to an343* explicitly declared construct in source code. This is due to344* limitations of the fidelity of the class file format in345* preserving information from source code. For example, at least346* some versions of the class file format do not preserve whether347* an annotation was explicitly declared by the programmer or was348* implicitly declared as a <em>container annotation</em>.349*350* @implSpec The default implementation of this method returns351* {@link Origin#EXPLICIT EXPLICIT}.352*353* @param c the construct the annotation mirror modifies354* @param a the annotation mirror being examined355* @jls 9.6.3 Repeatable Annotation Types356* @jls 9.7.5 Multiple Annotations of the Same Interface357* @since 9358*/359default Origin getOrigin(AnnotatedConstruct c,360AnnotationMirror a) {361return Origin.EXPLICIT;362}363364/**365* {@return the <em>origin</em> of the given module directive}366*367* <p>Note that if this method returns {@link Origin#EXPLICIT368* EXPLICIT} and the module directive was created from a class369* file, then the module directive may not, in fact, correspond to370* an explicitly declared construct in source code. This is due to371* limitations of the fidelity of the class file format in372* preserving information from source code. For example, at least373* some versions of the class file format do not preserve whether374* a {@code uses} directive was explicitly declared by the375* programmer or was added as a synthetic construct.376*377* <p>Note that an implementation may not be able to reliably378* determine the origin status of the directive if the directive379* is created from a class file due to limitations of the fidelity380* of the class file format in preserving information from source381* code.382*383* @implSpec The default implementation of this method returns384* {@link Origin#EXPLICIT EXPLICIT}.385*386* @param m the module of the directive387* @param directive the module directive being examined388* @since 9389*/390default Origin getOrigin(ModuleElement m,391ModuleElement.Directive directive) {392return Origin.EXPLICIT;393}394395/**396* The <em>origin</em> of an element or other language model397* item. The origin of an element or item models how a construct398* in a program is declared in the source code, explicitly,399* implicitly, etc.400*401* <p>Note that it is possible additional kinds of origin values402* will be added in future versions of the platform.403*404* @jls 13.1 The Form of a Binary405* @since 9406*/407public enum Origin {408/**409* Describes a construct explicitly declared in source code.410*/411EXPLICIT,412413/**414* A mandated construct is one that is not explicitly declared415* in the source code, but whose presence is mandated by the416* specification. Such a construct is said to be implicitly417* declared.418*419* One example of a mandated element is a <em>default420* constructor</em> in a class that contains no explicit421* constructor declarations.422*423* Another example of a mandated construct is an implicitly424* declared <em>container annotation</em> used to hold425* multiple annotations of a repeatable annotation interface.426*427* @jls 8.8.9 Default Constructor428* @jls 8.9.3 Enum Members429* @jls 9.6.3 Repeatable Annotation Types430* @jls 9.7.5 Multiple Annotations of the Same Interface431*/432MANDATED,433434/**435* A synthetic construct is one that is neither implicitly nor436* explicitly declared in the source code. Such a construct is437* typically a translation artifact created by a compiler.438*/439SYNTHETIC;440441/**442* Returns {@code true} for values corresponding to constructs443* that are implicitly or explicitly declared, {@code false}444* otherwise.445* @return {@code true} for {@link #EXPLICIT} and {@link #MANDATED},446* {@code false} otherwise.447*/448public boolean isDeclared() {449return this != SYNTHETIC;450}451}452453/**454* {@return {@code true} if the executable element is a bridge455* method, {@code false} otherwise}456*457* @implSpec The default implementation of this method returns {@code false}.458*459* @param e the executable being examined460* @since 9461*/462default boolean isBridge(ExecutableElement e) {463return false;464}465466/**467* {@return the <i>binary name</i> of a type element}468*469* @param type the type element being examined470*471* @see TypeElement#getQualifiedName472* @jls 13.1 The Form of a Binary473*/474Name getBinaryName(TypeElement type);475476477/**478* {@return the package of an element} The package of a package is479* itself.480* The package of a module is {@code null}.481*482* The package of a top-level class or interface is its {@linkplain483* TypeElement#getEnclosingElement enclosing package}. Otherwise,484* the package of an element is equal to the package of the485* {@linkplain Element#getEnclosingElement enclosing element}.486*487* @param e the element being examined488*/489PackageElement getPackageOf(Element e);490491/**492* {@return the module of an element} The module of a module is493* itself.494*495* If a package has a module as its {@linkplain496* PackageElement#getEnclosingElement enclosing element}, that497* module is the module of the package. If the enclosing element498* of a package is {@code null}, {@code null} is returned for the499* package's module.500*501* (One situation where a package may have a {@code null} module502* is if the environment does not include modules, such as an503* annotation processing environment configured for a {@linkplain504* javax.annotation.processing.ProcessingEnvironment#getSourceVersion505* source version} without modules.)506*507* Otherwise, the module of an element is equal to the module508* {@linkplain #getPackageOf(Element) of the package} of the509* element.510*511* @implSpec The default implementation of this method returns512* {@code null}.513*514* @param e the element being examined515* @since 9516*/517default ModuleElement getModuleOf(Element e) {518return null;519}520521/**522* Returns all members of a type element, whether inherited or523* declared directly. For a class the result also includes its524* constructors, but not local or anonymous classes.525*526* @apiNote Elements of certain kinds can be isolated using527* methods in {@link ElementFilter}.528*529* @param type the type being examined530* @return all members of the type531* @see Element#getEnclosedElements532*/533List<? extends Element> getAllMembers(TypeElement type);534535/**536* Returns all annotations <i>present</i> on an element, whether537* directly present or present via inheritance.538*539* <p>Note that any annotations returned by this method are540* declaration annotations.541*542* @param e the element being examined543* @return all annotations of the element544* @see Element#getAnnotationMirrors545* @see javax.lang.model.AnnotatedConstruct546*/547List<? extends AnnotationMirror> getAllAnnotationMirrors(Element e);548549/**550* Tests whether one type, method, or field hides another.551*552* @param hider the first element553* @param hidden the second element554* @return {@code true} if and only if the first element hides555* the second556* @jls 8.4.8 Inheritance, Overriding, and Hiding557*/558boolean hides(Element hider, Element hidden);559560/**561* Tests whether one method, as a member of a given class or interface,562* overrides another method.563* When a non-abstract method overrides an abstract one, the564* former is also said to <i>implement</i> the latter.565*566* <p> In the simplest and most typical usage, the value of the567* {@code type} parameter will simply be the class or interface568* directly enclosing {@code overrider} (the possibly-overriding569* method). For example, suppose {@code m1} represents the method570* {@code String.hashCode} and {@code m2} represents {@code571* Object.hashCode}. We can then ask whether {@code m1} overrides572* {@code m2} within the class {@code String} (it does):573*574* <blockquote>575* {@code assert elements.overrides(m1, m2,576* elements.getTypeElement("java.lang.String")); }577* </blockquote>578*579* A more interesting case can be illustrated by the following example580* in which a method in class {@code A} does not override a581* like-named method in interface {@code B}:582*583* <blockquote>584* {@code class A { public void m() {} } }<br>585* {@code interface B { void m(); } }<br>586* ...<br>587* {@code m1 = ...; // A.m }<br>588* {@code m2 = ...; // B.m }<br>589* {@code assert ! elements.overrides(m1, m2,590* elements.getTypeElement("A")); }591* </blockquote>592*593* When viewed as a member of a third class {@code C}, however,594* the method in {@code A} does override the one in {@code B}:595*596* <blockquote>597* {@code class C extends A implements B {} }<br>598* ...<br>599* {@code assert elements.overrides(m1, m2,600* elements.getTypeElement("C")); }601* </blockquote>602*603* @param overrider the first method, possible overrider604* @param overridden the second method, possibly being overridden605* @param type the class or interface of which the first method is a member606* @return {@code true} if and only if the first method overrides607* the second608* @jls 8.4.8 Inheritance, Overriding, and Hiding609* @jls 9.4.1 Inheritance and Overriding610*/611boolean overrides(ExecutableElement overrider, ExecutableElement overridden,612TypeElement type);613614/**615* Returns the text of a <i>constant expression</i> representing a616* primitive value or a string.617* The text returned is in a form suitable for representing the value618* in source code.619*620* @param value a primitive value or string621* @return the text of a constant expression622* @throws IllegalArgumentException if the argument is not a primitive623* value or string624*625* @see VariableElement#getConstantValue()626*/627String getConstantExpression(Object value);628629/**630* Prints a representation of the elements to the given writer in631* the specified order. The main purpose of this method is for632* diagnostics. The exact format of the output is <em>not</em>633* specified and is subject to change.634*635* @param w the writer to print the output to636* @param elements the elements to print637*/638void printElements(java.io.Writer w, Element... elements);639640/**641* {@return a name with the same sequence of characters as the642* argument}643*644* @param cs the character sequence to return as a name645*/646Name getName(CharSequence cs);647648/**649* {@return {@code true} if the type element is a functional650* interface, {@code false} otherwise}651*652* @param type the type element being examined653* @jls 9.8 Functional Interfaces654* @since 1.8655*/656boolean isFunctionalInterface(TypeElement type);657658/**659* {@return {@code true} if the module element is an automatic660* module, {@code false} otherwise}661*662* @implSpec663* The default implementation of this method returns {@code664* false}.665*666* @param module the module element being examined667* @jls 7.7.1 Dependences668* @since 17669*/670default boolean isAutomaticModule(ModuleElement module) {671return false;672}673674/**675* Returns the record component for the given accessor. Returns null if the676* given method is not a record component accessor.677*678* @implSpec The default implementation of this method checks if the element679* enclosing the accessor has kind {@link ElementKind#RECORD RECORD} if that is680* the case, then all the record components on the accessor's enclosing element681* are retrieved by invoking {@link ElementFilter#recordComponentsIn(Iterable)}.682* If the accessor of at least one of the record components retrieved happen to683* be equal to the accessor passed as a parameter to this method, then that684* record component is returned, in any other case {@code null} is returned.685*686* @param accessor the method for which the record component should be found.687* @return the record component, or null if the given method is not an record688* component accessor689* @since 16690*/691default RecordComponentElement recordComponentFor(ExecutableElement accessor) {692if (accessor.getEnclosingElement().getKind() == ElementKind.RECORD) {693for (RecordComponentElement rec : ElementFilter.recordComponentsIn(accessor.getEnclosingElement().getEnclosedElements())) {694if (Objects.equals(rec.getAccessor(), accessor)) {695return rec;696}697}698}699return null;700}701}702703704