1717import java .util .Objects ;
1818
1919import javax .lang .model .element .Element ;
20+ import javax .lang .model .element .ElementKind ;
2021import javax .lang .model .element .ExecutableElement ;
2122import javax .lang .model .element .ModuleElement ;
2223import javax .lang .model .element .Name ;
@@ -87,8 +88,8 @@ public interface Domain {
8788 public ArrayType arrayTypeOf (final TypeMirror componentType );
8889
8990 /**
90- * Returns the {@link Element} declaring the supplied {@link TypeMirror}, or {@code null} if there is no such {@link
91- * Element}.
91+ * Returns the {@link Element} declaring the supplied {@link TypeMirror}, <strong> or {@code null} if there is no such
92+ * {@link Element}</strong> .
9293 *
9394 * @param t a {@link TypeMirror}; must not be {@code null}
9495 *
@@ -210,8 +211,8 @@ public interface Domain {
210211
211212 /**
212213 * A convenience method that returns the {@link DeclaredType} {@linkplain TypeElement#asType() of} a {@link
213- * TypeElement} that bears the supplied {@code canonicalName}, or {@code null} if there is no such {@link TypeElement}
214- * (and therefore no such {@link DeclaredType}).
214+ * TypeElement} that bears the supplied {@code canonicalName}, <strong> or {@code null} if there is no such {@link
215+ * TypeElement} (and therefore no such {@link DeclaredType})</strong> .
215216 *
216217 * @param canonicalName a valid canonical name; must not be {@code null}
217218 *
@@ -324,8 +325,8 @@ public DeclaredType declaredType(final DeclaredType enclosingType,
324325 /**
325326 * Returns the {@link Element} responsible for declaring the supplied {@link TypeMirror}, which is most commonly a
326327 * {@link DeclaredType}, a {@link TypeVariable}, a {@link NoType} with a {@link TypeKind} of {@link TypeKind#MODULE},
327- * or a {@link NoType} with a {@link TypeKind} of {@link TypeKind#PACKAGE}, or {@code null} if there is no such {@link
328- * Element}.
328+ * or a {@link NoType} with a {@link TypeKind} of {@link TypeKind#PACKAGE}, <strong> or {@code null} if there is no
329+ * such {@link Element}</strong> .
329330 *
330331 * @param t a {@link TypeMirror}; must not be {@code null}
331332 *
@@ -337,6 +338,29 @@ public DeclaredType declaredType(final DeclaredType enclosingType,
337338 */
338339 public Element element (final TypeMirror t );
339340
341+ /**
342+ * A convenience method that returns the <dfn>element type</dfn> of the supplied {@link TypeMirror}.
343+ *
344+ * <p>The element type of an {@linkplain TypeKind#ARRAY array type} is the element type of its {@linkplain
345+ * ArrayType#getComponentType() component type}.</p>.
346+ *
347+ * <p>The element type of every other kind of type is the type itself. Note that the semantics of the prior sentence
348+ * diverge deliberately, primarily for convenience, from those of the relevant section in the Java Language
349+ * Specification.</p>
350+ *
351+ * @param t a {@link TypeMirror}; must not be {@code null}
352+ *
353+ * @return the <dfn>element type</dfn> of the supplied {@link TypeMirror}; never {@code null}
354+ *
355+ * @exception NullPointerException if {@code t} is {@code null}
356+ *
357+ * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-10.html#jls-10.1 Java Language Specification, section
358+ * 10.1
359+ */
360+ public default TypeMirror elementType (final TypeMirror t ) {
361+ return t .getKind () == TypeKind .ARRAY ? this .elementType (((ArrayType )t ).getComponentType ()) : t ;
362+ }
363+
340364 /**
341365 * Returns the <dfn>erasure</dfn> of the supplied {@link TypeMirror}.
342366 *
@@ -360,7 +384,8 @@ public DeclaredType declaredType(final DeclaredType enclosingType,
360384
361385 /**
362386 * A convenience method that returns an {@link ExecutableElement} representing the static initializer, constructor or
363- * method described by the supplied arguments, or {@code null} if no such {@link ExecutableElement} exists.
387+ * method described by the supplied arguments, <strong>or {@code null} if no such {@link ExecutableElement}
388+ * exists</strong>.
364389 *
365390 * @param declaringElement a {@link TypeElement} representing the class that declares the executable; must not be
366391 * {@code null}
@@ -373,9 +398,8 @@ public DeclaredType declaredType(final DeclaredType enclosingType,
373398 * @param parameterTypes {@link TypeMirror}s that represent the executable's {@linkplain
374399 * ExecutableElement#getParameters() parameter types}
375400 *
376- * @return an {@link ExecutableElement} with an {@link javax.lang.model.element.ElementKind} of {@link
377- * javax.lang.model.element.ElementKind#CONSTRUCTOR}, {@link javax.lang.model.element.ElementKind#METHOD}, or {@link
378- * javax.lang.model.element.ElementKind#STATIC_INIT}, or {@code null}
401+ * @return an {@link ExecutableElement} with an {@link ElementKind} of {@link ElementKind#CONSTRUCTOR}, {@link
402+ * ElementKind#METHOD}, or {@link ElementKind#STATIC_INIT}, or {@code null}
379403 *
380404 * @exception NullPointerException if any argument is {@code null}
381405 */
@@ -444,6 +468,42 @@ public default boolean generic(final Element e) {
444468 return false ;
445469 }
446470
471+ /**
472+ * A convenience method that returns {@code true} if and only if the supplied {@link Element} represents the (essentially
473+ * primordial) {@code java.lang.Object} {@link Element}.
474+ *
475+ * @param e an {@link Element}; must not be {@code null}
476+ *
477+ * @return {@code true} if and only if the supplied {@link Element} represents the (essentially
478+ * primordial) {@code java.lang.Object} {@link Element}; {@code false} otherwise
479+ *
480+ * @exception NullPointerException if {@code e} is {@code null}
481+ */
482+ public default boolean javaLangObject (final Element e ) {
483+ return
484+ e .getKind () == ElementKind .CLASS &&
485+ ((QualifiedNameable )e ).getQualifiedName ().contentEquals ("java.lang.Object" );
486+ }
487+
488+ /**
489+ * A convenience method that returns {@code true} if and only if the supplied {@link TypeMirror} represents the {@link
490+ * DeclaredType} declared by the (essentially primordial) {@code java.lang.Object} element.
491+ *
492+ * @param t a {@link TypeMirror}; must not be {@code null}
493+ *
494+ * @return {@code true} represents the {@link
495+ * DeclaredType} declared by the (essentially primordial) {@code java.lang.Object} element; {@code false} otherwise
496+ *
497+ * @exception NullPointerException if {@code t} is {@code null}
498+ *
499+ * @see #javaLangObject(Element)
500+ */
501+ public default boolean javaLangObject (final TypeMirror t ) {
502+ return
503+ t .getKind () == TypeKind .DECLARED &&
504+ javaLangObject (((DeclaredType )t ).asElement ());
505+ }
506+
447507 /**
448508 * A convenience method that returns the {@link TypeElement} representing the class named {@link Object
449509 * java.lang.Object}.
@@ -471,7 +531,7 @@ public default TypeElement javaLangObject() {
471531
472532 /**
473533 * Returns a {@link ModuleElement} representing the module {@linkplain ModuleElement#getQualifiedName() named} by the
474- * supplied {@code qualifiedName}, or {@code null} if there is no such {@link ModuleElement}.
534+ * supplied {@code qualifiedName}, <strong> or {@code null} if there is no such {@link ModuleElement}</strong> .
475535 *
476536 * @param qualifiedName a name suitable for naming a module; must not be {@code null}; may be {@linkplain
477537 * CharSequence#isEmpty() empty}, in which case a {@link ModuleElement} representing an <dfn>unnamed module</dfn> will
@@ -540,8 +600,8 @@ public default TypeElement javaLangObject() {
540600 public NullType nullType ();
541601
542602 /**
543- * Returns a {@link PackageElement} representing the package bearing the supplied {@code canonicalName}, or {@code null}
544- * if there is no such {@link PackageElement}.
603+ * Returns a {@link PackageElement} representing the package bearing the supplied {@code canonicalName}, <strong>or
604+ * {@code null} if there is no such {@link PackageElement}</strong> .
545605 *
546606 * @param canonicalName a canonical name suitable for naming a package; must not be {@code null}; may be {@linkplain
547607 * CharSequence#isEmpty() empty}, in which case a {@link ModuleElement} representing an <dfn>unnamed package</dfn> will
@@ -560,8 +620,8 @@ public default TypeElement javaLangObject() {
560620
561621 /**
562622 * Returns a {@link PackageElement} representing the package bearing the supplied {@code canonicalName} as seen from
563- * the module represented by the supplied {@link ModuleElement}, or {@code null} if there is no such {@link
564- * PackageElement}.
623+ * the module represented by the supplied {@link ModuleElement}, <strong> or {@code null} if there is no such {@link
624+ * PackageElement}</strong> .
565625 *
566626 * @param asSeenFrom a {@link ModuleElement}; must not be {@code null}
567627 *
@@ -580,6 +640,25 @@ public default TypeElement javaLangObject() {
580640 */
581641 public PackageElement packageElement (final ModuleElement asSeenFrom , final CharSequence canonicalName );
582642
643+ /**
644+ * A convenience method that returns {@code true} if and only if {@code t} is a {@link DeclaredType}, {@linkplain
645+ * TypeMirror#getKind() has a <code>TypeKind</code>} of {@link TypeKind#DECLARED DECLARED}, and {@linkplain
646+ * DeclaredType#getTypeArguments() has an empty type arguments list}.
647+ *
648+ * @param t a {@link TypeMirror}; must not be {@code null}
649+ *
650+ * @return {@code true} if and only if {@code t} is a {@link DeclaredType}, {@linkplain
651+ * TypeMirror#getKind() has a <code>TypeKind</code>} of {@link TypeKind#DECLARED DECLARED}, and {@linkplain
652+ * DeclaredType#getTypeArguments() has an empty type arguments list}; {@code false} otherwise
653+ *
654+ * @exception NullPointerException if {@code t} is {@code null}
655+ */
656+ public default boolean parameterized (final TypeMirror t ) {
657+ return
658+ t .getKind () == TypeKind .DECLARED &&
659+ !((DeclaredType )t ).getTypeArguments ().isEmpty ();
660+ }
661+
583662 /**
584663 * Returns the result of applying <dfn>unboxing conversion</dfn> to the (logical) {@link TypeElement} bearing the
585664 * supplied {@code canonicalName}.
@@ -693,8 +772,32 @@ public default PrimitiveType primitiveType(final TypeElement e) {
693772 public PrimitiveType primitiveType (final TypeMirror t );
694773
695774 /**
696- * Returns a {@link RecordComponentElement} corresponding to the supplied {@link ExecutableElement}, or {@code null}
697- * if there is no such {@link RecordComponentElement}.
775+ * A convenience method that returns the <dfn>raw type</dfn> corresponding to {@code t}, <strong>or {@code null} if
776+ * {@code t} is <a href="https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8">incapable of yielding
777+ * a raw type</a></strong>.
778+ *
779+ * <p>Overrides of this method must conform to the requirements imposed by the relevant section of the relevant
780+ * version of the Java Language Specification concerning raw types.</p>
781+ *
782+ * @param t a {@link TypeMirror}; must not be {@code null}
783+ *
784+ * @return the raw type corresponding to the supplied {@link TypeMirror}, or {@code null} if {@code t} is <a
785+ * href="https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8">incapable of yielding a raw type</a>
786+ *
787+ * @exception NullPointerException if {@code t} is {@code null}
788+ *
789+ * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8 Java Language Specification, section 4.8
790+ */
791+ public default TypeMirror rawType (final TypeMirror t ) {
792+ return switch (t .getKind ()) {
793+ case ARRAY -> this .rawType (this .elementType (t )); // recursive
794+ default -> this .parameterized (t ) ? this .erasure (t ) : null ;
795+ };
796+ }
797+
798+ /**
799+ * Returns a {@link RecordComponentElement} corresponding to the supplied {@link ExecutableElement}, <strong>or {@code
800+ * null} if there is no such {@link RecordComponentElement}</strong>.
698801 *
699802 * @param e an {@link ExecutableElement} {@linkplain ExecutableElement#getEnclosingElement() enclosed by} a record
700803 * representing an <dfn>accessor method</dfn>; must not be {@code null}
@@ -807,8 +910,8 @@ public default String toString(final CharSequence name) {
807910 }
808911
809912 /**
810- * Returns a {@link TypeElement} representing the element bearing the supplied <dfn>canonical name</dfn>, or {@code
811- * null} if there is no such {@link TypeElement}.
913+ * Returns a {@link TypeElement} representing the element bearing the supplied <dfn>canonical name</dfn>, <strong>or
914+ * {@code null} if there is no such {@link TypeElement}</strong> .
812915 *
813916 * @param canonicalName a valid canonical name; must not be {@code null}
814917 *
@@ -825,8 +928,8 @@ public default String toString(final CharSequence name) {
825928
826929 /**
827930 * Returns a {@link TypeElement} representing the element bearing the supplied <dfn>canonical name</dfn>, as read or
828- * seen from the module represented by the supplied {@link ModuleElement}, or {@code null} if there is no such {@link
829- * TypeElement}.
931+ * seen from the module represented by the supplied {@link ModuleElement}, <strong> or {@code null} if there is no such
932+ * {@link TypeElement}</strong> .
830933 *
831934 * @param asSeenFrom a {@link ModuleElement}; must not be {@code null}
832935 *
@@ -922,8 +1025,8 @@ public default TypeElement typeElement(final TypeKind primitiveTypeKind) {
9221025 /**
9231026 * Returns the {@link TypeParameterElement} {@linkplain Parameterizable#getTypeParameters() contained} by the supplied
9241027 * {@link Parameterizable} whose {@linkplain TypeParameterElement#getSimpleName() name} {@linkplain
925- * Name#contentEquals(CharSequence) is equal to} the supplied {@code name}, or {@code null} if there is no such {@link
926- * TypeParameterElement}.
1028+ * Name#contentEquals(CharSequence) is equal to} the supplied {@code name}, <strong> or {@code null} if there is no
1029+ * such {@link TypeParameterElement}</strong> .
9271030 *
9281031 * @param p a {@link Parameterizable}; must not be {@code null}
9291032 *
@@ -957,8 +1060,8 @@ public default TypeParameterElement typeParameterElement(Parameterizable p, fina
9571060 * A convenience method that returns the {@link TypeVariable} {@linkplain TypeParameterElement#asType() declared by}
9581061 * the {@link TypeParameterElement} {@linkplain Parameterizable#getTypeParameters() contained} by the supplied {@link
9591062 * Parameterizable} whose {@linkplain TypeParameterElement#getSimpleName() name} {@linkplain
960- * Name#contentEquals(CharSequence) is equal to} the supplied {@code name}, or {@code null} if there is no such {@link
961- * TypeParameterElement} or {@link TypeVariable}.
1063+ * Name#contentEquals(CharSequence) is equal to} the supplied {@code name}, <strong> or {@code null} if there is no
1064+ * such {@link TypeParameterElement} or {@link TypeVariable}</strong> .
9621065 *
9631066 * @param p a {@link Parameterizable}; must not be {@code null}
9641067 *
@@ -974,10 +1077,10 @@ public default TypeVariable typeVariable(Parameterizable p, final CharSequence n
9741077 }
9751078
9761079 /**
977- * A convenience method that returns the first {@link VariableElement} with a {@linkplain
978- * javax.lang.model.element.ElementKind#isVariable() variable <code>ElementKind</code>} and {@linkplain
979- * Element#getSimpleName() bearing} the supplied {@code simpleName} that the supplied {@code enclosingElement}
980- * {@linkplain Element#getEnclosedElements() encloses}, or {@code null} if there is no such {@link VariableElement}.
1080+ * A convenience method that returns the first {@link VariableElement} with a {@linkplain ElementKind#isVariable()
1081+ * variable <code>ElementKind</code>} and {@linkplain Element#getSimpleName() bearing} the supplied {@code simpleName}
1082+ * that the supplied {@code enclosingElement} {@linkplain Element#getEnclosedElements() encloses}, <strong>or {@code
1083+ * null} if there is no such {@link VariableElement}</strong> .
9811084 *
9821085 * @param enclosingElement an {@link Element}; must not be {@code null}
9831086 *
@@ -989,7 +1092,7 @@ public default TypeVariable typeVariable(Parameterizable p, final CharSequence n
9891092 *
9901093 * @see Element#getEnclosedElements()
9911094 *
992- * @see javax.lang.model.element. ElementKind#isVariable()
1095+ * @see ElementKind#isVariable()
9931096 *
9941097 * @see Element#getSimpleName()
9951098 *
0 commit comments