1 /*
   2  * Copyright (c) 2005, 2019, 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.lang.model.util;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Collections;
  30 import java.util.List;
  31 import java.util.Map;
  32 import java.util.Set;
  33 import java.util.LinkedHashSet;
  34 import java.util.Objects;
  35 
  36 import javax.lang.model.AnnotatedConstruct;
  37 import javax.lang.model.element.*;
  38 
  39 
  40 /**
  41  * Utility methods for operating on program elements.
  42  *
  43  * <p><b>Compatibility Note:</b> Methods may be added to this interface
  44  * in future releases of the platform.
  45  *
  46  * @author Joseph D. Darcy
  47  * @author Scott Seligman
  48  * @author Peter von der Ah&eacute;
  49  * @see javax.annotation.processing.ProcessingEnvironment#getElementUtils
  50  * @since 1.6
  51  */
  52 public interface Elements {
  53 
  54     /**
  55      * Returns a package given its fully qualified name if the package is unique in the environment.
  56      * If running with modules, all modules in the modules graph are searched for matching packages.
  57      *
  58      * @param name  fully qualified package name, or an empty string for an unnamed package
  59      * @return the specified package, or {@code null} if it cannot be uniquely found
  60      */
  61     PackageElement getPackageElement(CharSequence name);
  62 
  63     /**
  64      * Returns a package given its fully qualified name, as seen from the given module.
  65      *
  66      * @implSpec The default implementation of this method returns
  67      * {@code null}.
  68      *
  69      * @param name  fully qualified package name, or an empty string for an unnamed package
  70      * @param module module relative to which the lookup should happen
  71      * @return the specified package, or {@code null} if it cannot be found
  72      * @see #getAllPackageElements
  73      * @since 9
  74      */
  75     default PackageElement getPackageElement(ModuleElement module, CharSequence name) {
  76         return null;
  77     }
  78 
  79     /**
  80      * Returns all package elements with the given canonical name.
  81      *
  82      * There may be more than one package element with the same canonical
  83      * name if the package elements are in different modules.
  84      *
  85      * @implSpec The default implementation of this method calls
  86      * {@link #getAllModuleElements() getAllModuleElements} and stores
  87      * the result. If the set of modules is empty, {@link
  88      * #getPackageElement(CharSequence) getPackageElement(name)} is
  89      * called passing through the name argument. If {@code
  90      * getPackageElement(name)} is {@code null}, an empty set of
  91      * package elements is returned; otherwise, a single-element set
  92      * with the found package element is returned. If the set of
  93      * modules is nonempty, the modules are iterated over and any
  94      * non-{@code null} results of {@link
  95      * #getPackageElement(ModuleElement, CharSequence)
  96      * getPackageElement(module, name)} are accumulated into a
  97      * set. The set is then returned.
  98      *
  99      * @param name  the canonical name
 100      * @return the package elements, or an empty set if no package with the name can be found
 101      * @see #getPackageElement(ModuleElement, CharSequence)
 102      * @since 9
 103      */
 104     default Set<? extends PackageElement> getAllPackageElements(CharSequence name) {
 105         Set<? extends ModuleElement> modules = getAllModuleElements();
 106         if (modules.isEmpty()) {
 107             PackageElement packageElt = getPackageElement(name);
 108             return (packageElt != null) ?
 109                 Collections.singleton(packageElt):
 110                 Collections.emptySet();
 111         } else {
 112             Set<PackageElement> result = new LinkedHashSet<>(1); // Usually expect at most 1 result
 113             for (ModuleElement module: modules) {
 114                 PackageElement packageElt = getPackageElement(module, name);
 115                 if (packageElt != null)
 116                     result.add(packageElt);
 117             }
 118             return Collections.unmodifiableSet(result);
 119         }
 120     }
 121 
 122     /**
 123      * Returns a type element given its canonical name if the type element is unique in the environment.
 124      * If running with modules, all modules in the modules graph are searched for matching
 125      * type elements.
 126      *
 127      * @param name  the canonical name
 128      * @return the named type element, or {@code null} if it cannot be uniquely found
 129      */
 130     TypeElement getTypeElement(CharSequence name);
 131 
 132     /**
 133      * Returns a type element given its canonical name, as seen from the given module.
 134      *
 135      * @implSpec The default implementation of this method returns
 136      * {@code null}.
 137      *
 138      * @param name  the canonical name
 139      * @param module module relative to which the lookup should happen
 140      * @return the named type element, or {@code null} if it cannot be found
 141      * @see #getAllTypeElements
 142      * @since 9
 143      */
 144     default TypeElement getTypeElement(ModuleElement module, CharSequence name) {
 145         return null;
 146     }
 147 
 148     /**
 149      * Returns all type elements with the given canonical name.
 150      *
 151      * There may be more than one type element with the same canonical
 152      * name if the type elements are in different modules.
 153      *
 154      * @implSpec The default implementation of this method calls
 155      * {@link #getAllModuleElements() getAllModuleElements} and stores
 156      * the result. If the set of modules is empty, {@link
 157      * #getTypeElement(CharSequence) getTypeElement(name)} is called
 158      * passing through the name argument. If {@code
 159      * getTypeElement(name)} is {@code null}, an empty set of type
 160      * elements is returned; otherwise, a single-element set with the
 161      * found type element is returned. If the set of modules is
 162      * nonempty, the modules are iterated over and any non-{@code null}
 163      * results of {@link #getTypeElement(ModuleElement,
 164      * CharSequence) getTypeElement(module, name)} are accumulated
 165      * into a set. The set is then returned.
 166      *
 167      * @param name  the canonical name
 168      * @return the type elements, or an empty set if no type with the name can be found
 169      * @see #getTypeElement(ModuleElement, CharSequence)
 170      * @since 9
 171      */
 172     default Set<? extends TypeElement> getAllTypeElements(CharSequence name) {
 173         Set<? extends ModuleElement> modules = getAllModuleElements();
 174         if (modules.isEmpty()) {
 175             TypeElement typeElt = getTypeElement(name);
 176             return (typeElt != null) ?
 177                 Collections.singleton(typeElt):
 178                 Collections.emptySet();
 179         } else {
 180             Set<TypeElement> result = new LinkedHashSet<>(1); // Usually expect at most 1 result
 181             for (ModuleElement module: modules) {
 182                 TypeElement typeElt = getTypeElement(module, name);
 183                 if (typeElt != null)
 184                     result.add(typeElt);
 185             }
 186             return Collections.unmodifiableSet(result);
 187         }
 188     }
 189 
 190     /**
 191      * Returns a module element given its fully qualified name.
 192      *
 193      * If the requested module cannot be found, {@code null} is
 194      * returned. One situation where a module cannot be found is if
 195      * the environment does not include modules, such as an annotation
 196      * processing environment configured for a {@linkplain
 197      * javax.annotation.processing.ProcessingEnvironment#getSourceVersion
 198      * source version} without modules.
 199      *
 200      * @implSpec The default implementation of this method returns
 201      * {@code null}.
 202      *
 203      * @param name  the name, or an empty string for an unnamed module
 204      * @return the named module element, or {@code null} if it cannot be found
 205      * @see #getAllModuleElements
 206      * @since 9
 207      * @spec JPMS
 208      */
 209     default ModuleElement getModuleElement(CharSequence name) {
 210         return null;
 211     }
 212 
 213     /**
 214      * Returns all module elements in the current environment.
 215      *
 216      * If no modules are present, an empty set is returned. One
 217      * situation where no modules are present occurs when the
 218      * environment does not include modules, such as an annotation
 219      * processing environment configured for a {@linkplain
 220      * javax.annotation.processing.ProcessingEnvironment#getSourceVersion
 221      * source version} without modules.
 222      *
 223      * @implSpec The default implementation of this method returns
 224      * an empty set.
 225      *
 226      * @return the known module elements, or an empty set if there are no modules
 227      * @see #getModuleElement(CharSequence)
 228      * @since 9
 229      */
 230     default Set<? extends ModuleElement> getAllModuleElements() {
 231         return Collections.emptySet();
 232     }
 233 
 234     /**
 235      * Returns the values of an annotation's elements, including defaults.
 236      *
 237      * @see AnnotationMirror#getElementValues()
 238      * @param a  annotation to examine
 239      * @return the values of the annotation's elements, including defaults
 240      */
 241     Map<? extends ExecutableElement, ? extends AnnotationValue>
 242             getElementValuesWithDefaults(AnnotationMirror a);
 243 
 244     /**
 245      * Returns the text of the documentation (&quot;Javadoc&quot;)
 246      * comment of an element.
 247      *
 248      * <p> A documentation comment of an element is a comment that
 249      * begins with "{@code /**}" , ends with a separate
 250      * "<code>*/</code>", and immediately precedes the element,
 251      * ignoring white space.  Therefore, a documentation comment
 252      * contains at least three"{@code *}" characters.  The text
 253      * returned for the documentation comment is a processed form of
 254      * the comment as it appears in source code.  The leading "{@code
 255      * /**}" and trailing "<code>*/</code>" are removed.  For lines
 256      * of the comment starting after the initial "{@code /**}",
 257      * leading white space characters are discarded as are any
 258      * consecutive "{@code *}" characters appearing after the white
 259      * space or starting the line.  The processed lines are then
 260      * concatenated together (including line terminators) and
 261      * returned.
 262      *
 263      * @param e  the element being examined
 264      * @return the documentation comment of the element, or {@code null}
 265      *          if there is none
 266      * @jls 3.6 White Space
 267      */
 268     String getDocComment(Element e);
 269 
 270     /**
 271      * Returns {@code true} if the element is deprecated, {@code false} otherwise.
 272      *
 273      * @param e  the element being examined
 274      * @return {@code true} if the element is deprecated, {@code false} otherwise
 275      */
 276     boolean isDeprecated(Element e);
 277 
 278     /**
 279      * Returns the <em>origin</em> of the given element.
 280      *
 281      * <p>Note that if this method returns {@link Origin#EXPLICIT
 282      * EXPLICIT} and the element was created from a class file, then
 283      * the element may not, in fact, correspond to an explicitly
 284      * declared construct in source code. This is due to limitations
 285      * of the fidelity of the class file format in preserving
 286      * information from source code. For example, at least some
 287      * versions of the class file format do not preserve whether a
 288      * constructor was explicitly declared by the programmer or was
 289      * implicitly declared as the <em>default constructor</em>.
 290      *
 291      * @implSpec The default implementation of this method returns
 292      * {@link Origin#EXPLICIT EXPLICIT}.
 293      *
 294      * @param e  the element being examined
 295      * @return the origin of the given element
 296      * @since 9
 297      */
 298     default Origin getOrigin(Element e) {
 299         return Origin.EXPLICIT;
 300     }
 301 
 302     /**
 303      * Returns the <em>origin</em> of the given annotation mirror.
 304      *
 305      * An annotation mirror is {@linkplain Origin#MANDATED mandated}
 306      * if it is an implicitly declared <em>container annotation</em>
 307      * used to hold repeated annotations of a repeatable annotation
 308      * type.
 309      *
 310      * <p>Note that if this method returns {@link Origin#EXPLICIT
 311      * EXPLICIT} and the annotation mirror was created from a class
 312      * file, then the element may not, in fact, correspond to an
 313      * explicitly declared construct in source code. This is due to
 314      * limitations of the fidelity of the class file format in
 315      * preserving information from source code. For example, at least
 316      * some versions of the class file format do not preserve whether
 317      * an annotation was explicitly declared by the programmer or was
 318      * implicitly declared as a <em>container annotation</em>.
 319      *
 320      * @implSpec The default implementation of this method returns
 321      * {@link Origin#EXPLICIT EXPLICIT}.
 322      *
 323      * @param c the construct the annotation mirror modifies
 324      * @param a the annotation mirror being examined
 325      * @return the origin of the given annotation mirror
 326      * @jls 9.6.3 Repeatable Annotation Types
 327      * @jls 9.7.5 Multiple Annotations of the Same Type
 328      * @since 9
 329      */
 330     default Origin getOrigin(AnnotatedConstruct c,
 331                              AnnotationMirror a) {
 332         return Origin.EXPLICIT;
 333     }
 334 
 335     /**
 336      * Returns the <em>origin</em> of the given module directive.
 337      *
 338      * <p>Note that if this method returns {@link Origin#EXPLICIT
 339      * EXPLICIT} and the module directive was created from a class
 340      * file, then the module directive may not, in fact, correspond to
 341      * an explicitly declared construct in source code. This is due to
 342      * limitations of the fidelity of the class file format in
 343      * preserving information from source code. For example, at least
 344      * some versions of the class file format do not preserve whether
 345      * a {@code uses} directive was explicitly declared by the
 346      * programmer or was added as a synthetic construct.
 347      *
 348      * <p>Note that an implementation may not be able to reliably
 349      * determine the origin status of the directive if the directive
 350      * is created from a class file due to limitations of the fidelity
 351      * of the class file format in preserving information from source
 352      * code.
 353      *
 354      * @implSpec The default implementation of this method returns
 355      * {@link Origin#EXPLICIT EXPLICIT}.
 356      *
 357      * @param m the module of the directive
 358      * @param directive  the module directive being examined
 359      * @return the origin of the given directive
 360      * @since 9
 361      */
 362     default Origin getOrigin(ModuleElement m,
 363                              ModuleElement.Directive directive) {
 364         return Origin.EXPLICIT;
 365     }
 366 
 367     /**
 368      * The <em>origin</em> of an element or other language model
 369      * item. The origin of an element or item models how a construct
 370      * in a program is declared in the source code, explicitly,
 371      * implicitly, etc.
 372      *
 373      * <p>Note that it is possible additional kinds of origin values
 374      * will be added in future versions of the platform.
 375      *
 376      * @jls 13.1 The Form of a Binary
 377      * @since 9
 378      */
 379     public enum Origin {
 380         /**
 381          * Describes a construct explicitly declared in source code.
 382          */
 383         EXPLICIT,
 384 
 385        /**
 386          * A mandated construct is one that is not explicitly declared
 387          * in the source code, but whose presence is mandated by the
 388          * specification. Such a construct is said to be implicitly
 389          * declared.
 390          *
 391          * One example of a mandated element is a <em>default
 392          * constructor</em> in a class that contains no explicit
 393          * constructor declarations.
 394          *
 395          * Another example of a mandated construct is an implicitly
 396          * declared <em>container annotation</em> used to hold
 397          * multiple annotations of a repeatable annotation type.
 398          *
 399          * @jls 8.8.9 Default Constructor
 400          * @jls 8.9.3 Enum Members
 401          * @jls 9.6.3 Repeatable Annotation Types
 402          * @jls 9.7.5 Multiple Annotations of the Same Type
 403          */
 404         MANDATED,
 405 
 406        /**
 407          * A synthetic construct is one that is neither implicitly nor
 408          * explicitly declared in the source code. Such a construct is
 409          * typically a translation artifact created by a compiler.
 410          */
 411         SYNTHETIC;
 412 
 413         /**
 414          * Returns {@code true} for values corresponding to constructs
 415          * that are implicitly or explicitly declared, {@code false}
 416          * otherwise.
 417          * @return {@code true} for {@link EXPLICIT} and {@link
 418          * MANDATED}, {@code false} otherwise.
 419          */
 420         public boolean isDeclared() {
 421             return this != SYNTHETIC;
 422         }
 423     }
 424 
 425     /**
 426      * Returns {@code true} if the executable element is a bridge
 427      * method, {@code false} otherwise.
 428      *
 429      * @implSpec The default implementation of this method returns {@code false}.
 430      *
 431      * @param e  the executable being examined
 432      * @return {@code true} if the executable element is a bridge
 433      * method, {@code false} otherwise
 434      * @since 9
 435      */
 436     default boolean isBridge(ExecutableElement e) {
 437         return false;
 438     }
 439 
 440     /**
 441      * Returns the <i>binary name</i> of a type element.
 442      *
 443      * @param type  the type element being examined
 444      * @return the binary name
 445      *
 446      * @see TypeElement#getQualifiedName
 447      * @jls 13.1 The Form of a Binary
 448      */
 449     Name getBinaryName(TypeElement type);
 450 
 451 
 452     /**
 453      * Returns the package of an element.  The package of a package is
 454      * itself.
 455      * The package of a module is {@code null}.
 456      *
 457      * The package of a top-level type is its {@linkplain
 458      * TypeElement#getEnclosingElement enclosing package}. Otherwise,
 459      * the package of an element is equal to the package of the
 460      * {@linkplain Element#getEnclosingElement enclosing element}.
 461      *
 462      * @param e the element being examined
 463      * @return the package of an element
 464      */
 465     PackageElement getPackageOf(Element e);
 466 
 467     /**
 468      * Returns the module of an element.  The module of a module is
 469      * itself.
 470      *
 471      * If a package has a module as its {@linkplain
 472      * PackageElement#getEnclosingElement enclosing element}, that
 473      * module is the module of the package. If the enclosing element
 474      * of a package is {@code null}, {@code null} is returned for the
 475      * package's module.
 476      *
 477      * (One situation where a package may have a {@code null} module
 478      * is if the environment does not include modules, such as an
 479      * annotation processing environment configured for a {@linkplain
 480      * javax.annotation.processing.ProcessingEnvironment#getSourceVersion
 481      * source version} without modules.)
 482      *
 483      * Otherwise, the module of an element is equal to the module
 484      * {@linkplain #getPackageOf(Element) of the package} of the
 485      * element.
 486      *
 487      * @implSpec The default implementation of this method returns
 488      * {@code null}.
 489      *
 490      * @param e the element being examined
 491      * @return the module of an element
 492      * @since 9
 493      * @spec JPMS
 494      */
 495     default ModuleElement getModuleOf(Element e) {
 496         return null;
 497     }
 498 
 499     /**
 500      * Returns all members of a type element, whether inherited or
 501      * declared directly.  For a class the result also includes its
 502      * constructors, but not local or anonymous classes.
 503      *
 504      * @apiNote Elements of certain kinds can be isolated using
 505      * methods in {@link ElementFilter}.
 506      *
 507      * @param type  the type being examined
 508      * @return all members of the type
 509      * @see Element#getEnclosedElements
 510      */
 511     List<? extends Element> getAllMembers(TypeElement type);
 512 
 513     /**
 514      * Returns all annotations <i>present</i> on an element, whether
 515      * directly present or present via inheritance.
 516      *
 517      * <p>Note that any annotations returned by this method are
 518      * declaration annotations.
 519      *
 520      * @param e  the element being examined
 521      * @return all annotations of the element
 522      * @see Element#getAnnotationMirrors
 523      * @see javax.lang.model.AnnotatedConstruct
 524      */
 525     List<? extends AnnotationMirror> getAllAnnotationMirrors(Element e);
 526 
 527     /**
 528      * Tests whether one type, method, or field hides another.
 529      *
 530      * @param hider   the first element
 531      * @param hidden  the second element
 532      * @return {@code true} if and only if the first element hides
 533      *          the second
 534      * @jls 8.4.8 Inheritance, Overriding, and Hiding
 535      */
 536     boolean hides(Element hider, Element hidden);
 537 
 538     /**
 539      * Tests whether one method, as a member of a given type,
 540      * overrides another method.
 541      * When a non-abstract method overrides an abstract one, the
 542      * former is also said to <i>implement</i> the latter.
 543      *
 544      * <p> In the simplest and most typical usage, the value of the
 545      * {@code type} parameter will simply be the class or interface
 546      * directly enclosing {@code overrider} (the possibly-overriding
 547      * method).  For example, suppose {@code m1} represents the method
 548      * {@code String.hashCode} and {@code m2} represents {@code
 549      * Object.hashCode}.  We can then ask whether {@code m1} overrides
 550      * {@code m2} within the class {@code String} (it does):
 551      *
 552      * <blockquote>
 553      * {@code assert elements.overrides(m1, m2,
 554      *          elements.getTypeElement("java.lang.String")); }
 555      * </blockquote>
 556      *
 557      * A more interesting case can be illustrated by the following example
 558      * in which a method in type {@code A} does not override a
 559      * like-named method in type {@code B}:
 560      *
 561      * <blockquote>
 562      * {@code class A { public void m() {} } }<br>
 563      * {@code interface B { void m(); } }<br>
 564      * ...<br>
 565      * {@code m1 = ...;  // A.m }<br>
 566      * {@code m2 = ...;  // B.m }<br>
 567      * {@code assert ! elements.overrides(m1, m2,
 568      *          elements.getTypeElement("A")); }
 569      * </blockquote>
 570      *
 571      * When viewed as a member of a third type {@code C}, however,
 572      * the method in {@code A} does override the one in {@code B}:
 573      *
 574      * <blockquote>
 575      * {@code class C extends A implements B {} }<br>
 576      * ...<br>
 577      * {@code assert elements.overrides(m1, m2,
 578      *          elements.getTypeElement("C")); }
 579      * </blockquote>
 580      *
 581      * @param overrider  the first method, possible overrider
 582      * @param overridden  the second method, possibly being overridden
 583      * @param type   the type of which the first method is a member
 584      * @return {@code true} if and only if the first method overrides
 585      *          the second
 586      * @jls 8.4.8 Inheritance, Overriding, and Hiding
 587      * @jls 9.4.1 Inheritance and Overriding
 588      */
 589     boolean overrides(ExecutableElement overrider, ExecutableElement overridden,
 590                       TypeElement type);
 591 
 592     /**
 593      * Returns the text of a <i>constant expression</i> representing a
 594      * primitive value or a string.
 595      * The text returned is in a form suitable for representing the value
 596      * in source code.
 597      *
 598      * @param value  a primitive value or string
 599      * @return the text of a constant expression
 600      * @throws IllegalArgumentException if the argument is not a primitive
 601      *          value or string
 602      *
 603      * @see VariableElement#getConstantValue()
 604      */
 605     String getConstantExpression(Object value);
 606 
 607     /**
 608      * Prints a representation of the elements to the given writer in
 609      * the specified order.  The main purpose of this method is for
 610      * diagnostics.  The exact format of the output is <em>not</em>
 611      * specified and is subject to change.
 612      *
 613      * @param w the writer to print the output to
 614      * @param elements the elements to print
 615      */
 616     void printElements(java.io.Writer w, Element... elements);
 617 
 618     /**
 619      * Return a name with the same sequence of characters as the
 620      * argument.
 621      *
 622      * @param cs the character sequence to return as a name
 623      * @return a name with the same sequence of characters as the argument
 624      */
 625     Name getName(CharSequence cs);
 626 
 627     /**
 628      * Returns {@code true} if the type element is a functional interface, {@code false} otherwise.
 629      *
 630      * @param type the type element being examined
 631      * @return {@code true} if the element is a functional interface, {@code false} otherwise
 632      * @jls 9.8 Functional Interfaces
 633      * @since 1.8
 634      */
 635     boolean isFunctionalInterface(TypeElement type);
 636 
 637     /**
 638      * {@preview Associated with records, a preview feature of the Java language.
 639      *
 640      *           This method is associated with <i>records</i>, a preview
 641      *           feature of the Java language. Preview features
 642      *           may be removed in a future release, or upgraded to permanent
 643      *           features of the Java language.}
 644      *
 645      * Returns the record component for the given accessor. Returns null if the
 646      * given method is not a record component accessor.
 647      *
 648      * @implSpec The default implementation of this method checks if the element
 649      * enclosing the accessor has kind {@link ElementKind#RECORD RECORD} if that is
 650      * the case, then all the record components on the accessor's enclosing element
 651      * are retrieved by invoking {@link ElementFilter#recordComponentsIn(Iterable)}.
 652      * If the accessor of at least one of the record components retrieved happen to
 653      * be equal to the accessor passed as a parameter to this method, then that
 654      * record component is returned, in any other case {@code null} is returned.
 655      *
 656      * @param accessor the method for which the record component should be found.
 657      * @return the record component, or null if the given method is not an record
 658      * component accessor
 659      * @since 14
 660      */
 661     @jdk.internal.PreviewFeature(feature=jdk.internal.PreviewFeature.Feature.RECORDS,
 662                                  essentialAPI=false)
 663     @SuppressWarnings("preview")
 664     default RecordComponentElement recordComponentFor(ExecutableElement accessor) {
 665         if (accessor.getEnclosingElement().getKind() == ElementKind.RECORD) {
 666             for (RecordComponentElement rec : ElementFilter.recordComponentsIn(accessor.getEnclosingElement().getEnclosedElements())) {
 667                 if (Objects.equals(rec.getAccessor(), accessor)) {
 668                     return rec;
 669                 }
 670             }
 671         }
 672         return null;
 673     }
 674 }