001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- 002 * 003 * Copyright © 2024–2025 microBean™. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 006 * the License. You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 011 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 012 * specific language governing permissions and limitations under the License. 013 */ 014package org.microbean.construct; 015 016import java.lang.reflect.Constructor; 017import java.lang.reflect.Executable; 018import java.lang.reflect.GenericArrayType; 019import java.lang.reflect.GenericDeclaration; 020import java.lang.reflect.Method; 021import java.lang.reflect.ParameterizedType; 022import java.lang.reflect.Type; 023 024import java.util.ArrayList; 025import java.util.List; 026import java.util.Objects; 027 028import javax.lang.model.element.AnnotationMirror; 029import javax.lang.model.element.Element; 030import javax.lang.model.element.ElementKind; 031import javax.lang.model.element.ExecutableElement; 032import javax.lang.model.element.ModuleElement; 033import javax.lang.model.element.Name; 034import javax.lang.model.element.PackageElement; 035import javax.lang.model.element.Parameterizable; 036import javax.lang.model.element.QualifiedNameable; 037import javax.lang.model.element.RecordComponentElement; 038import javax.lang.model.element.TypeElement; 039import javax.lang.model.element.TypeParameterElement; 040import javax.lang.model.element.VariableElement; 041 042import javax.lang.model.type.ArrayType; 043import javax.lang.model.type.DeclaredType; 044import javax.lang.model.type.ExecutableType; 045import javax.lang.model.type.NoType; 046import javax.lang.model.type.NullType; 047import javax.lang.model.type.PrimitiveType; 048import javax.lang.model.type.TypeKind; 049import javax.lang.model.type.TypeMirror; 050import javax.lang.model.type.TypeVariable; 051import javax.lang.model.type.WildcardType; 052 053import javax.lang.model.util.Elements; 054import javax.lang.model.util.Elements.Origin; 055 056import org.microbean.construct.element.UniversalElement; 057 058import org.microbean.construct.type.UniversalType; 059 060import static java.util.Collections.unmodifiableList; 061 062import static javax.lang.model.type.TypeKind.DECLARED; 063 064/** 065 * A representation of a domain of valid Java constructs. 066 * 067 * <p>A <dfn id="domain">domain</dfn> is a set of valid Java <a href="#construct">constructs</a>. A {@link Domain} 068 * provides access to a domain and its members.</p> 069 * 070 * <p>A Java <dfn id="construct">construct</dfn> is either a <a href="#type">type</a> or an <a 071 * href="#element">element</a>.</p> 072 * 073 * <p>A <dfn id="type">type</dfn> is a usage of a Java type, most commonly represented as a {@link TypeMirror}.</p> 074 * 075 * <p>An <dfn id="element">element</dfn> ia a declaration of a Java program element, most commonly represented as an 076 * {@link Element}.</p> 077 * 078 * <p>Domains impose constraints on the <a href="#type">types</a> and <a href="#element">elements</a> they contain, and 079 * on the kinds and semantics of operations that can be performed on them.</p> 080 * 081 * <p>This interface is modeled on a deliberately restricted combination of the {@link javax.lang.model.util.Elements} 082 * and {@link javax.lang.model.util.Types} interfaces.</p> 083 * 084 * <p>{@link Domain} implementations must be thread-safe.</p> 085 * 086 * @author <a href="https://about.me/lairdnelson" target="_top">Laird Nelson</a> 087 * 088 * @see PrimordialDomain 089 * 090 * @see <a href="https://bugs.openjdk.org/browse/JDK-8055219">JDK-8055219</a> 091 */ 092@SuppressWarnings("try") 093public interface Domain extends PrimordialDomain { 094 095 /** 096 * Returns an immutable, determinate, non-{@code null} {@link List} of {@link AnnotationMirror} instances representing 097 * all annotations <dfn>present</dfn> on an element, whether <dfn>directly present</dfn> or present via inheritance. 098 * 099 * @param element the {@link Element} whose present annotations should be returned; must not be {@code null} 100 * 101 * @return an immutable, determinate, non-{@code null} {@link List} of {@link AnnotationMirror} instances representing 102 * all annotations <dfn>present</dfn> on an element, whether <dfn>directly present</dfn> or present via inheritance 103 * 104 * @exception NullPointerException if {@code element} is {@code null} 105 * 106 * @see javax.lang.model.util.Elements#getAllAnnotationMirrors(Element) 107 */ 108 public default List<? extends AnnotationMirror> allAnnotationMirrors(Element element) { 109 element = UniversalElement.of(element, this); // handles locking, symbol completion, etc. 110 final List<AnnotationMirror> annotations = new ArrayList<>(8); 111 annotations.addAll(element.getAnnotationMirrors().reversed()); 112 TypeMirror sc = ((TypeElement)element).getSuperclass(); 113 if (sc.getKind() == DECLARED) { 114 element = ((DeclaredType)sc).asElement(); 115 WHILE_LOOP: 116 while (element != null && element.getKind().isDeclaredType()) { 117 for (final AnnotationMirror a : element.getAnnotationMirrors().reversed()) { 118 // See if it's inherited 119 final TypeElement annotationTypeElement = (TypeElement)a.getAnnotationType().asElement(); 120 for (final AnnotationMirror metaAnnotation : annotationTypeElement.getAnnotationMirrors()) { 121 if (((TypeElement)metaAnnotation.getAnnotationType().asElement()).getQualifiedName().contentEquals("java.lang.annotation.Inherited")) { 122 for (final AnnotationMirror existingAnnotation : annotations) { 123 if (existingAnnotation.getAnnotationType().asElement().equals(annotationTypeElement)) { 124 continue WHILE_LOOP; 125 } 126 } 127 annotations.add(a); 128 break; 129 } 130 } 131 } 132 sc = ((TypeElement)element).getSuperclass(); 133 element = sc.getKind() == DECLARED ? ((DeclaredType)sc).asElement() : null; 134 } 135 } 136 return annotations.isEmpty() ? List.of() : unmodifiableList(annotations.reversed()); 137 } 138 139 /** 140 * Returns an {@link ArrayType} whose {@linkplain ArrayType#getComponentType() component type} is {@linkplain 141 * #sameType(TypeMirror, TypeMirror) the same as} the supplied {@code componentType}. 142 * 143 * @param componentType the component type; must not be {@code null} 144 * 145 * @return a non-{@code null} {@link ArrayType} whose {@linkplain ArrayType#getComponentType() component type} is 146 * {@linkplain #sameType(TypeMirror, TypeMirror) the same as} the supplied {@code componentType} 147 * 148 * @exception NullPointerException if {@code componentType} is {@code null} 149 * 150 * @exception IllegalArgumentException if {@code componentType} is not a valid component type 151 * 152 * @see javax.lang.model.util.Types#getArrayType(TypeMirror) 153 */ 154 // Type factory method 155 public ArrayType arrayTypeOf(final TypeMirror componentType); 156 157 /** 158 * Returns a non-{@code null} {@link TypeMirror} representing the type of the supplied {@link Element} when that 159 * {@link Element} is viewed as a member of, or otherwise directly contained by, the supplied {@code containingType}. 160 * 161 * <p>For example, when viewed as a member of the parameterized type {@link java.util.Set Set<String>}, the 162 * {@link java.util.Set#add(Object)} method (represented as an {@link ExecutableElement}) {@linkplain 163 * ExecutableElement#asType() has} a {@linkplain ExecutableType type} whose {@linkplain 164 * ExecutableType#getParameterTypes() method parameter is of type} {@link String} (not {@link String}'s erasure).</p> 165 * 166 * @param containingType the containing {@link DeclaredType}; must not be {@code null} 167 * 168 * @param e the member {@link Element}; must not be {@code null} 169 * 170 * @return a non-{@code null} {@linkplain TypeMirror type} representing the {@linkplain Element#asType() type of} the 171 * supplied {@link Element} when viewed as a member of the supplied {@code containingType}; never {@code null} 172 * 173 * @exception NullPointerException if either {@code containingType} or {@code e} is {@code null} 174 * 175 * @exception IllegalArgumentException if {@code e} cannot be viewed as a member of the supplied {@code 176 * containingType} (because it is the wrong {@linkplain Element#getKind() kind}, for example) 177 * 178 * @see javax.lang.model.util.Types#asMemberOf(DeclaredType, Element) 179 */ 180 public TypeMirror asMemberOf(final DeclaredType containingType, final Element e); 181 182 /** 183 * Returns {@code true} if and only if the supplied {@code payload} (the first argument) is considered assignable to 184 * the supplied {@code receiver} (the second argument) according to <a 185 * href="https://docs.oracle.com/javase/specs/jls/se21/html/jls-5.html#jls-5.2">the rules of the Java Language 186 * Specification</a>; <strong>note the counterintuitive order of the parameters</strong>. 187 * 188 * <p>Perhaps surprisingly, the "left hand side" of the putative assignment is represented by the second parameter 189 * ({@code receiver}). The "right hand side" of the putative assignment is represented by the first parameter 190 * ({@code payload}). This follows the contract of the {@link javax.lang.model.util.Types#isAssignable(TypeMirror, 191 * TypeMirror)} method, on which this method is modeled.</p> 192 * 193 * @param payload the {@link TypeMirror} being assigned; must not be {@code null} 194 * 195 * @param receiver the {@link TypeMirror} receiving the assignment; must not be {@code null} 196 * 197 * @return {@code true} if and only if {@code payload} is assignable to {@code receiver} according to <a 198 * href="https://docs.oracle.com/javase/specs/jls/se21/html/jls-5.html#jls-5.2">the rules of the Java Language 199 * Specification</a> 200 * 201 * @exception NullPointerException if either {@code payload} or {@code receiver} is {@code null} 202 * 203 * @exception IllegalArgumentException if either {@link TypeMirror} is not one that can take part in an assignment 204 * 205 * @see javax.lang.model.util.Types#isAssignable(TypeMirror, TypeMirror) 206 * 207 * @spec https://docs.oracle.com/javase/specs/jls/se21/html/jls-5.html#jls-5.2 Java Language Specification, section 208 * 5.2 209 */ 210 // Note the strange positioning of payload and receiver. 211 public boolean assignable(final TypeMirror payload, final TypeMirror receiver); 212 213 /** 214 * Returns the (non-{@code null}) <a 215 * href="https://docs.oracle.com/javase/specs/jls/se21/html/jls-13.html#jls-13.1"><dfn>binary name</dfn></a> of the 216 * supplied {@link TypeElement}. 217 * 218 * @param e a {@link TypeElement}; must not be {@code null} 219 * 220 * @return a non-{@code null} {@link Name} 221 * 222 * @exception NullPointerException if {@code e} is {@code null} 223 * 224 * @see javax.lang.model.util.Elements#getBinaryName(TypeElement) 225 * 226 * @spec https://docs.oracle.com/javase/specs/jls/se21/html/jls-13.html#jls-13.1 Java Language Specification, section 227 * 13.1 228 */ 229 public Name binaryName(final TypeElement e); 230 231 /** 232 * Returns {@code true} if and only if the supplied {@link ExecutableElement} represents a <dfn>bridge method</dfn>. 233 * 234 * @param e an {@link ExecutableElement}; must not be {@code null} 235 * 236 * @return {@code true} if and only if the supplied {@link ExecutableElement} represents a bridge method 237 * 238 * @exception NullPointerException if {@code e} is {@code null} 239 * 240 * @see javax.lang.model.util.Elements#isBridge(ExecutableElement) 241 * 242 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-8.html#jls-8.4.8.3 Java Language Specification, 243 * section 8.4.8.3 244 * 245 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-15.html#jls-15.12.4.5 Java Language Specification, 246 * section 15.12.4.5 247 */ 248 public boolean bridge(final ExecutableElement e); 249 250 /** 251 * Applies <a href="https://docs.oracle.com/javase/specs/jls/se23/html/jls-5.html#jls-5.1.10"><dfn>capture 252 * conversion</dfn></a> to the supplied {@link TypeMirror}, which is normally a {@linkplain TypeKind#WILDCARD wildcard 253 * type}. 254 * 255 * @param wildcard a {@link TypeMirror}; must not be {@code null}; if not a {@linkplain TypeKind#WILDCARD wildcard 256 * type}, then it will be returned unchanged 257 * 258 * @return a non-{@code null} {@link TypeMirror} representing the result of <a 259 * href="https://docs.oracle.com/javase/specs/jls/se23/html/jls-5.html#jls-5.1.10">capture conversion</a> applied to 260 * the supplied {@link TypeMirror} 261 * 262 * @exception NullPointerException if {@code wildcard} is {@code null} 263 * 264 * @see javax.lang.model.util.Types#capture(TypeMirror) 265 * 266 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-5.html#jls-5.1.10 Java Language Specification, section 267 * 5.1.10 268 */ 269 public TypeMirror capture(final TypeMirror wildcard); 270 271 /** 272 * Returns {@code true} if and only if {@code candidateContainer} <dfn>contains</dfn> {@code candidate}, according to 273 * the <a href="https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.5.1">Java Language Specification, 274 * section 4.5.1</a>. 275 * 276 * @param candidateContainer the putative containing type; normally a {@linkplain TypeKind#WILDCARD wildcard type}; 277 * must not be {@code null} 278 * 279 * @param candidate the putative contained type; must not be {@code null} 280 * 281 * @return {@code true} if and only if {@code candidateContainer} <dfn>contains</dfn> {@code candidate}, according to 282 * the <a href="https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.5.1">Java Language Specification, 283 * section 4.5.1</a>; {@code false} otherwise 284 * 285 * @exception NullPointerException if either argument is {@code null} 286 * 287 * @exception IllegalArgumentException if either argument is either an {@linkplain TypeKind#EXECUTABLE executable 288 * type}, a {@linkplain TypeKind#MODULE module type}, or a {@linkplain TypeKind#PACKAGE package type} 289 * 290 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.5.1 Java Language Specification, section 291 * 4.5.1 292 */ 293 public boolean contains(final TypeMirror candidateContainer, final TypeMirror candidate); 294 295 /** 296 * A convenience method that returns the {@link DeclaredType} {@linkplain TypeElement#asType() of} a {@link 297 * TypeElement} that bears the supplied {@code canonicalName}, <strong>or {@code null} if there is no such {@link 298 * TypeElement} (and therefore no such {@link DeclaredType})</strong>. 299 * 300 * @param canonicalName a valid canonical name; must not be {@code null} 301 * 302 * @return a {@link DeclaredType} with a {@link TypeKind} of {@link TypeKind#DECLARED}, or {@code null} 303 * 304 * @see #typeElement(CharSequence) 305 * 306 * @see #declaredType(TypeElement, TypeMirror...) 307 * 308 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-6.html#jls-6.7 Java Language Specification, section 309 * 6.7 310 */ 311 // (Convenience.) 312 public default DeclaredType declaredType(final CharSequence canonicalName) { 313 final TypeElement e = this.typeElement(canonicalName); 314 return e == null ? null : this.declaredType(e); 315 } 316 317 /** 318 * Returns the {@link DeclaredType} {@linkplain TypeElement#asType() of} the supplied {@link TypeElement} with the 319 * supplied {@link TypeMirror} arguments (if any), yielding a parameterized type. 320 * 321 * <p>Given a {@link TypeElement} representing the class named {@link java.util.Set java.util.Set} and a {@link 322 * TypeMirror} representing the type declared by {@link String java.lang.String}, for example, this method will return 323 * a {@link DeclaredType} representing the parameterized type corresponding to {@link java.util.Set 324 * java.util.Set<java.lang.String>}.</p> 325 * 326 * <p>The number of supplied type arguments must either equal the number of the supplied {@link TypeElement}'s 327 * {@linkplain TypeElement#getTypeParameters() formal type parameters}, or must be zero. If it is zero, and if the 328 * supplied {@link TypeElement} {@linkplain #generic(Element) is generic}, then the supplied {@link TypeElement}'s raw 329 * type is returned.</p> 330 * 331 * <p>If a parameterized type is returned, {@linkplain DeclaredType#asElement() its <code>TypeElement</code>} must not 332 * be contained within a {@linkplain #generic(Element) generic} outer class. The parameterized type {@code 333 * Outer<String>.Inner<Number>}, for example, may be constructed by first using this method to get the type {@code 334 * Outer<String>}, and then invoking {@link #declaredType(DeclaredType, TypeElement, TypeMirror...)}.</p> 335 * 336 * @param typeElement a {@link TypeElement}; must not be {@code null} 337 * 338 * @param typeArguments any type arguments (represented by {@link TypeMirror}s); must not be {@code null} 339 * 340 * @return a non-{@code null} {@link DeclaredType} with a {@link TypeKind} of {@link TypeKind#DECLARED} 341 * 342 * @exception NullPointerException if {@code typeElement} or {@code typeArguments} is {@code null} 343 * 344 * @see javax.lang.model.util.Types#getDeclaredType(TypeElement, TypeMirror...) 345 * 346 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.5 Java Language Specification, section 4.5 347 */ 348 // Type factory method. 349 public DeclaredType declaredType(final TypeElement typeElement, 350 final TypeMirror... typeArguments); 351 352 /** 353 * Returns the {@link DeclaredType} {@linkplain TypeElement#asType() of} the supplied {@link TypeElement} with the 354 * supplied {@link TypeMirror} arguments (if any), given a containing {@link DeclaredType} of which it is a member, 355 * yielding a parameterized type. 356 * 357 * <p>Given a {@link DeclaredType} representing the parameterized type corresponding to {@code Outer<}{@link 358 * String}{@code >} (see the {@link #declaredType(TypeElement, TypeMirror...)} method), a {@link TypeElement} 359 * representing the class named {@code Outer.Inner} and a {@link DeclaredType} representing the non-generic class 360 * corresponding to {@link Number}, for example, this method will return a {@link DeclaredType} representing the 361 * parameterized type corresponding to {@code Outer<}{@link String}{@code >}{@code .Inner<}{@link Number}{@code >}.</p> 362 * 363 * <p>The number of supplied type arguments must either equal the number of the supplied {@link TypeElement}'s 364 * {@linkplain TypeElement#getTypeParameters() formal type parameters}, or must be zero. If it is zero, and if the 365 * supplied {@link TypeElement} {@link #generic(Element) is generic}, then the supplied {@link TypeElement}'s raw type 366 * is returned.</p> 367 * 368 * @param enclosingType a {@link DeclaredType} representing the containing type; must not be {@code null} 369 * 370 * @param typeElement a {@link TypeElement}; must not be {@code null} 371 * 372 * @param typeArguments any type arguments (represented by {@link TypeMirror}s); must not be {@code null} 373 * 374 * @return a non-{@code null} {@link DeclaredType} with a {@link TypeKind} of {@link TypeKind#DECLARED} 375 * 376 * @exception NullPointerException if {@code enclosingType}, {@code typeElement}, or {@code typeArguments} is {@code 377 * null} 378 * 379 * @see #declaredType(TypeElement, TypeMirror...) 380 * 381 * @see javax.lang.model.util.Types#getDeclaredType(DeclaredType, TypeElement, TypeMirror...) 382 * 383 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.5 Java Language Specification, section 4.5 384 */ 385 // Type factory method. 386 public DeclaredType declaredType(final DeclaredType enclosingType, 387 final TypeElement typeElement, 388 final TypeMirror... typeArguments); 389 390 /** 391 * Returns a non-{@code null} {@link List} of the <dfn>direct supertypes</dfn> of the supplied {@link TypeMirror}, 392 * which is normally a {@linkplain TypeKind#DECLARED declared type}. 393 * 394 * <p>The direct supertypes returned by this method are actually a subset of the direct supertypes of a type as 395 * defined in the <a href="https://docs.oracle.com/javase/specs/jls/se25/html/jls-4.html#jls-4.10">Java Language 396 * Specification, section 4.10</a>. Specifically, the subset contains only those types that can be expressed in the 397 * {@code extends} or {@code implements} clauses of the Java language. For example, a type {@code Baz} can declare 398 * only that it {@code extends Foo<Bar>}, not {@code Foo<?>}, even though {@code Foo<?>} is a specification-described 399 * direct supertype of {@code Baz}.</p> 400 * 401 * @param t a {@link TypeMirror}; must not be {@code null}; must not be an {@linkplain TypeKind#EXECUTABLE executable 402 * type}, a {@linkplain TypeKind#MODULE module type}, or a {@linkplain TypeKind#PACKAGE package type} 403 * 404 * @return a non-{@code null}, immutable {@link List} of {@link TypeMirror}s representing the direct supertypes 405 * 406 * @exception NullPointerException if {@code t} is {@code null} 407 * 408 * @exception IllegalArgumentException if either argument is either an {@linkplain TypeKind#EXECUTABLE executable 409 * type}, a {@linkplain TypeKind#MODULE module type}, or a {@linkplain TypeKind#PACKAGE package type} 410 * 411 * @see javax.lang.model.util.Types#directSupertypes(TypeMirror) 412 * 413 * @see <a href="https://bugs.openjdk.org/browse/JDK-8055219">JDK-8055219</a> 414 * 415 * @spec https://docs.oracle.com/javase/specs/jls/se25/html/jls-4.html#jls-4.10 Java Language Specification, section 416 * 4.10 417 */ 418 public List<? extends TypeMirror> directSupertypes(final TypeMirror t); 419 420 /** 421 * Returns the {@link Element} responsible for declaring the supplied {@link TypeMirror}, which is most commonly a 422 * {@link DeclaredType}, a {@link TypeVariable}, a {@link NoType} with a {@link TypeKind} of {@link TypeKind#MODULE}, 423 * or a {@link NoType} with a {@link TypeKind} of {@link TypeKind#PACKAGE}, <strong>or {@code null} if there is no 424 * such {@link Element}</strong>. 425 * 426 * @param t a {@link TypeMirror}; must not be {@code null} 427 * 428 * @return an {@link Element}, or {@code null} 429 * 430 * @exception NullPointerException if {@code t} is {@code null} 431 * 432 * @see javax.lang.model.util.Types#asElement(TypeMirror) 433 */ 434 public Element element(final TypeMirror t); 435 436 /** 437 * A convenience method that returns the <dfn>element type</dfn> of the supplied {@link TypeMirror}. 438 * 439 * <p>The element type of an {@linkplain TypeKind#ARRAY array type} is the element type of its {@linkplain 440 * ArrayType#getComponentType() component type}.</p>. 441 * 442 * <p>The element type of every other kind of type is the type itself. Note that the semantics of the prior sentence 443 * diverge deliberately, primarily for convenience, from those of the relevant section in the Java Language 444 * Specification.</p> 445 * 446 * @param t a {@link TypeMirror}; must not be {@code null} 447 * 448 * @return the <dfn>element type</dfn> of the supplied {@link TypeMirror}; never {@code null} 449 * 450 * @exception NullPointerException if {@code t} is {@code null} 451 * 452 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-10.html#jls-10.1 Java Language Specification, section 453 * 10.1 454 */ 455 // (Convenience.) 456 public default TypeMirror elementType(final TypeMirror t) { 457 return switch (t) { 458 case null -> throw new NullPointerException("t"); 459 case UniversalType ut -> ut.elementType(); 460 default -> { 461 try (var lock = lock()) { 462 yield t.getKind() == TypeKind.ARRAY ? this.elementType(((ArrayType)t).getComponentType()) : t; 463 } 464 } 465 }; 466 } 467 468 /** 469 * Returns the <dfn>erasure</dfn> of the supplied {@link TypeMirror}. 470 * 471 * @param <T> a {@link TypeMirror} specialization 472 * 473 * @param t the {@link TypeMirror} representing the type whose erasure should be returned; must not be {@code null} 474 * 475 * @return the erasure of the supplied {@link TypeMirror}; never {@code null} 476 * 477 * @exception NullPointerException if {@code t} is {@code null} 478 * 479 * @exception IllegalArgumentException if {@code t} is a {@link NoType} with a {@link TypeKind} of {@link 480 * TypeKind#MODULE}, or a {@link NoType} with a {@link TypeKind} of {@link TypeKind#PACKAGE} 481 * 482 * @see javax.lang.model.util.Types#erasure(TypeMirror) 483 * 484 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.6 Java Language Specification, section 485 * 4.6 486 */ 487 public <T extends TypeMirror> T erasure(final T t); 488 489 /** 490 * Returns an {@link ExecutableElement} corresponding to the supplied {@link Executable}. 491 * 492 * @param e an {@link Executable}; must not be {@code null} 493 * 494 * @return an {@link ExecutableElement} corresponding to the supplied {@link Executable}; never {@code null} 495 * 496 * @exception NullPointerException if {@code e} is {@code null} 497 * 498 * @exception IllegalArgumentException if somehow {@code e} is neither a {@link Constructor} nor a {@link Method} 499 */ 500 // (Convenience.) 501 public default ExecutableElement executableElement(final Executable e) { 502 return switch (e) { 503 case null -> throw new NullPointerException("e"); 504 case Constructor<?> c -> 505 this.executableElement(this.typeElement(c.getDeclaringClass().getCanonicalName()), 506 this.noType(TypeKind.VOID), 507 "<init>", 508 this.types(c.getParameterTypes())); 509 case Method m -> 510 this.executableElement(this.typeElement(m.getDeclaringClass().getCanonicalName()), 511 this.type(m.getReturnType()), 512 m.getName(), 513 this.types(m.getParameterTypes())); 514 default -> throw new IllegalArgumentException("e: " + e); 515 }; 516 } 517 518 519 /** 520 * A convenience method that returns an {@link ExecutableElement} representing the static initializer, constructor or 521 * method described by the supplied arguments, <strong>or {@code null} if no such {@link ExecutableElement} 522 * exists</strong>. 523 * 524 * @param declaringElement a {@link TypeElement} representing the class that declares the executable; must not be 525 * {@code null} 526 * 527 * @param returnType the {@linkplain ExecutableElement#getReturnType() return type} of the executable; must not be 528 * {@code null} 529 * 530 * @param name the {@linkplain ExecutableElement#getSimpleName() name} of the executable; must not be {@code null} 531 * 532 * @param parameterTypes {@link TypeMirror}s that represent the executable's {@linkplain 533 * ExecutableElement#getParameters() parameter types} 534 * 535 * @return an {@link ExecutableElement} with an {@link ElementKind} of {@link ElementKind#CONSTRUCTOR}, {@link 536 * ElementKind#METHOD}, or {@link ElementKind#STATIC_INIT}, or {@code null} 537 * 538 * @exception NullPointerException if any argument is {@code null} 539 */ 540 // (Convenience.) 541 public default ExecutableElement executableElement(final TypeElement declaringElement, 542 final TypeMirror returnType, 543 final CharSequence name, 544 final TypeMirror... parameterTypes) { 545 return switch (declaringElement) { 546 case null -> throw new NullPointerException("declaringElement"); 547 case UniversalElement ue -> { 548 final List<? extends UniversalElement> ees = ue.getEnclosedElements(); 549 yield ees.stream() 550 .sequential() 551 .filter(e -> e.getKind().isExecutable() && e.getSimpleName().contentEquals(name)) 552 .map(UniversalElement.class::cast) 553 .filter(ee -> { 554 if (!this.sameType(returnType, ee.getReturnType())) { 555 return false; 556 } 557 final List<? extends UniversalElement> ps = ee.getParameters(); 558 if (ps.size() != parameterTypes.length) { 559 return false; 560 } 561 for (int i = 0; i < parameterTypes.length; i++) { 562 if (!this.sameType(ps.get(i).asType(), parameterTypes[i])) { 563 return false; 564 } 565 } 566 return true; 567 }) 568 .findFirst() 569 .orElse(null); 570 } 571 default -> { 572 try (var lock = this.lock()) { 573 final List<? extends Element> ees = declaringElement.getEnclosedElements(); 574 yield ees.stream() 575 .sequential() 576 .filter(e -> e.getKind().isExecutable() && e.getSimpleName().contentEquals(name)) 577 .map(ExecutableElement.class::cast) 578 .filter(ee -> { 579 if (!this.sameType(returnType, ee.getReturnType())) { 580 return false; 581 } 582 final List<? extends VariableElement> ps = ee.getParameters(); 583 if (ps.size() != parameterTypes.length) { 584 return false; 585 } 586 for (int i = 0; i < parameterTypes.length; i++) { 587 if (!this.sameType(ps.get(i).asType(), parameterTypes[i])) { 588 return false; 589 } 590 } 591 return true; 592 }) 593 .findFirst() 594 .orElse(null); 595 } 596 } 597 }; 598 } 599 600 /** 601 * A convenience method that returns {@code true} if and only if the supplied {@link Element} is <dfn>generic</dfn>. 602 * 603 * @param e an {@link Element}; must not be {@code null} 604 * 605 * @return {@code true} if and only if the supplied {@link Element} is <dfn>generic</dfn>; {@code false} otherwise 606 * 607 * @exception NullPointerException if {@code e} is {@code null} 608 * 609 * @see Parameterizable 610 * 611 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-8.html#jls-8.1.2 Java Language Specification, section 612 * 8.1.2 613 * 614 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-8.html#jls-8.4.4 Java Language Specification, section 615 * 8.4.4 616 * 617 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-8.html#jls-8.8.4 Java Language Specification, section 618 * 8.8.4 619 * 620 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-9.html#jls-9.1.2 Java Language Specification, section 621 * 9.1.2 622 */ 623 // (Convenience.) 624 public default boolean generic(final Element e) { 625 return switch (e) { 626 case null -> throw new NullPointerException("e"); 627 case UniversalElement ue -> ue.generic(); 628 case Parameterizable p -> { 629 try (var lock = this.lock()) { 630 yield switch (e.getKind()) { 631 case CLASS, CONSTRUCTOR, ENUM, INTERFACE, METHOD, RECORD -> !p.getTypeParameters().isEmpty(); 632 default -> false; 633 }; 634 } 635 } 636 default -> false; 637 }; 638 } 639 640 /** 641 * A convenience method that returns {@code true} if and only if the supplied {@link TypeMirror} is declared by an 642 * {@link Element} that {@linkplain #generic(Element) is generic}. 643 * 644 * @param t a {@link TypeMirror}; must not be {@code null} 645 * 646 * @return {@code true} if and only if the supplied {@link TypeMirror} is declared by an {@link Element} that 647 * {@linkplain #generic(Element) is generic} 648 * 649 * @exception NullPointerException if {@code t} is {@code null} 650 * 651 * @see #generic(Element) 652 * 653 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-8.html#jls-8.1.2 Java Language Specification, section 654 * 8.1.2 655 * 656 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-8.html#jls-8.4.4 Java Language Specification, section 657 * 8.4.4 658 * 659 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-8.html#jls-8.8.4 Java Language Specification, section 660 * 8.8.4 661 * 662 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-9.html#jls-9.1.2 Java Language Specification, section 663 * 9.1.2 664 */ 665 // (Convenience.) 666 public default boolean generic(final TypeMirror t) { 667 return switch (t) { 668 case null -> throw new NullPointerException("t"); 669 case UniversalType ut -> ut.generic(); 670 default -> { 671 try (var lock = this.lock()) { 672 final Element e = this.element(t); 673 yield e != null && this.generic(e); 674 } 675 } 676 }; 677 } 678 679 /** 680 * A convenience method that returns {@code true} if and only if the supplied {@link Element} represents the (essentially 681 * primordial) {@code java.lang.Object} {@link Element}. 682 * 683 * @param e an {@link Element}; must not be {@code null} 684 * 685 * @return {@code true} if and only if the supplied {@link Element} represents the (essentially 686 * primordial) {@code java.lang.Object} {@link Element}; {@code false} otherwise 687 * 688 * @exception NullPointerException if {@code e} is {@code null} 689 */ 690 // (Convenience.) 691 public default boolean javaLangObject(final Element e) { 692 return switch (e) { 693 case null -> throw new NullPointerException("e"); 694 case UniversalElement ue -> ue.javaLangObject(); 695 default -> { 696 try (var lock = this.lock()) { 697 yield 698 e.getKind() == ElementKind.CLASS && 699 ((QualifiedNameable)e).getQualifiedName().contentEquals("java.lang.Object"); 700 } 701 } 702 }; 703 } 704 705 /** 706 * A convenience method that returns {@code true} if and only if the supplied {@link TypeMirror} represents the {@link 707 * DeclaredType} declared by the (essentially primordial) {@code java.lang.Object} element. 708 * 709 * @param t a {@link TypeMirror}; must not be {@code null} 710 * 711 * @return {@code true} represents the {@link 712 * DeclaredType} declared by the (essentially primordial) {@code java.lang.Object} element; {@code false} otherwise 713 * 714 * @exception NullPointerException if {@code t} is {@code null} 715 * 716 * @see #javaLangObject(Element) 717 */ 718 // (Convenience.) 719 public default boolean javaLangObject(final TypeMirror t) { 720 return switch (t) { 721 case null -> throw new NullPointerException("t"); 722 case UniversalType ut -> ut.javaLangObject(); 723 default -> { 724 try (var lock = this.lock()) { 725 yield 726 t.getKind() == DECLARED && 727 javaLangObject(((DeclaredType)t).asElement()); 728 } 729 } 730 }; 731 } 732 733 /** 734 * A convenience method that returns the {@link TypeElement} representing the class named {@link Object 735 * java.lang.Object}. 736 * 737 * @return a non-{@code null} {@link TypeElement} whose {@linkplain TypeElement#getQualifiedName() qualified name} is 738 * {@linkplain Name#contentEquals(CharSequence) equal to} {@code java.lang.Object} 739 * 740 * @see #typeElement(CharSequence) 741 */ 742 // (Convenience.) 743 public default TypeElement javaLangObject() { 744 return this.typeElement("java.lang.Object"); 745 } 746 747 // (Convenience.) 748 @Override // PrimordialDomain 749 public default DeclaredType javaLangObjectType() { 750 return (DeclaredType)this.javaLangObject().asType(); 751 } 752 753 /** 754 * Returns a {@link ModuleElement} representing the module {@linkplain ModuleElement#getQualifiedName() named} by the 755 * supplied {@code qualifiedName}, <strong>or {@code null} if there is no such {@link ModuleElement}</strong>. 756 * 757 * @param qualifiedName a name suitable for naming a module; must not be {@code null}; may be {@linkplain 758 * CharSequence#isEmpty() empty}, in which case a {@link ModuleElement} representing an <dfn>unnamed module</dfn> will 759 * be returned 760 * 761 * @return a {@link ModuleElement}, or {@code null} 762 * 763 * @exception NullPointerException if {@code qualifiedName} is {@code null} 764 * 765 * @see javax.lang.model.util.Elements#getModuleElement(CharSequence) 766 * 767 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-7.html#jls-7.7 Java Language Specification, section 768 * 7.7 769 */ 770 // Element factory method. 771 public ModuleElement moduleElement(final CharSequence qualifiedName); 772 773 /** 774 * Returns a {@link Name} representing the supplied {@link CharSequence}. 775 * 776 * @param name a {@link CharSequence}; must not be {@code null} 777 * 778 * @return a non-{@code null} {@link Name} representing the supplied {@link name} 779 * 780 * @exception NullPointerException if {@code name} is {@code null} 781 * 782 * @see #lock() 783 * 784 * @see javax.lang.model.util.Elements#getName(CharSequence) 785 */ 786 // Element factory method. 787 public Name name(final CharSequence name); 788 789 /** 790 * Returns a {@link NoType} {@linkplain TypeMirror#getKind() bearing} the supplied {@link TypeKind}, if the supplied 791 * {@link TypeKind} is either {@link TypeKind#NONE} or {@link TypeKind#VOID}. 792 * 793 * @param kind a {@link TypeKind}; must be either {@link TypeKind#NONE} or {@link TypeKind#VOID} 794 * 795 * @return a non-{@code null} {@link NoType} {@linkplain TypeMirror#getKind() bearing} the supplied {@link TypeKind} 796 * 797 * @exception NullPointerException if {@code kind} is {@code null} 798 * 799 * @exception IllegalArgumentException if {@code kind} is non-{@code null} and neither {@link TypeKind#NONE} nor 800 * {@link TypeKind#VOID} 801 * 802 * @see TypeKind#NONE 803 * 804 * @see TypeKind#VOID 805 * 806 * @see javax.lang.model.util.Types#getNoType(TypeKind) 807 * 808 * @see NoType 809 * 810 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-8.html#jls-8.4.5 Java Language Specification, section 811 * 8.4.5 812 */ 813 // Type factory method. 814 @Override // PrimordialDomain 815 public NoType noType(final TypeKind kind); 816 817 /** 818 * Returns a {@link NullType} implementation {@linkplain TypeMirror#getKind() whose <code>TypeKind</code>} is {@link 819 * TypeKind#NULL}. 820 * 821 * @return a non-{@code null} {@link NullType} 822 * 823 * @see javax.lang.model.util.Types#getNullType() 824 * 825 * @see NullType 826 * 827 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.1 Java Language Specification, section 4.1 828 */ 829 // Type factory method. 830 @Override // PrimordialDomain 831 public NullType nullType(); 832 833 /** 834 * Returns the {@linkplain Origin origin} of the supplied {@link Element}. 835 * 836 * @param e a non-{@code null} {@link Element} 837 * 838 * @return a non-{@code null} {@link Origin} 839 * 840 * @see Elements#getOrigin(Element) 841 * 842 * @see Origin 843 */ 844 public Origin origin(final Element e); 845 846 /** 847 * Returns a {@link PackageElement} representing the package bearing the supplied {@code canonicalName}, <strong>or 848 * {@code null} if there is no such {@link PackageElement}</strong>. 849 * 850 * @param canonicalName a canonical name suitable for naming a package; must not be {@code null}; may be {@linkplain 851 * CharSequence#isEmpty() empty}, in which case a {@link ModuleElement} representing an <dfn>unnamed package</dfn> will 852 * be returned 853 * 854 * @return a {@link PackageElement}, or {@code null} 855 * 856 * @exception NullPointerException if {@code canonicalName} is {@code null} 857 * 858 * @see javax.lang.model.util.Elements#getPackageElement(CharSequence) 859 * 860 * @see PackageElement 861 * 862 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-6.html#jls-6.7 Java Language Specification, section 863 * 6.7 864 */ 865 // Element factory method. 866 public PackageElement packageElement(final CharSequence canonicalName); 867 868 /** 869 * Returns a {@link PackageElement} representing the package bearing the supplied {@code canonicalName} as seen from 870 * the module represented by the supplied {@link ModuleElement}, <strong>or {@code null} if there is no such {@link 871 * PackageElement}</strong>. 872 * 873 * @param asSeenFrom a {@link ModuleElement}; must not be {@code null} 874 * 875 * @param canonicalName a canonical name suitable for naming a package; must not be {@code null}; may be {@linkplain 876 * CharSequence#isEmpty() empty}, in which case a {@link ModuleElement} representing an <dfn>unnamed package</dfn> will 877 * be returned 878 * 879 * @return a {@link PackageElement}, or {@code null} 880 * 881 * @exception NullPointerException if either {@code asSeenFrom} or {@code canonicalName} is {@code null} 882 * 883 * @see javax.lang.model.util.Elements#getPackageElement(ModuleElement, CharSequence) 884 * 885 * @see PackageElement 886 * 887 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-6.html#jls-6.7 Java Language Specification, section 888 * 6.7 889 */ 890 // Element factory method. 891 public PackageElement packageElement(final ModuleElement asSeenFrom, final CharSequence canonicalName); 892 893 /** 894 * Returns a {@link Parameterizable} corresponding to the supplied (reflective) {@link GenericDeclaration}. 895 * 896 * @param gd a {@link GenericDeclaration}; must not be {@code null} 897 * 898 * @return a {@link Parameterizable} corresponding to the supplied {@link GenericDeclaration}; never {@code null} 899 * 900 * @exception NullPointerException if {@code gd} is {@code null} 901 * 902 * @exception IllegalArgumentException if {@code gd} is neither a {@link Class} nor an {@link Executable} 903 * 904 * @see Parameterizable 905 */ 906 // (Convenience.) 907 public default Parameterizable parameterizable(final GenericDeclaration gd) { 908 return switch (gd) { 909 case null -> throw new NullPointerException("gd"); 910 case Class<?> c -> this.typeElement(c.getCanonicalName()); 911 case Executable e -> this.executableElement(e); 912 default -> throw new IllegalArgumentException("gd: " + gd); 913 }; 914 } 915 916 /** 917 * A convenience method that returns {@code true} if and only if {@code t} is a {@link DeclaredType}, {@linkplain 918 * TypeMirror#getKind() has a <code>TypeKind</code>} of {@link TypeKind#DECLARED DECLARED}, and {@linkplain 919 * DeclaredType#getTypeArguments() has a non-empty type arguments list}. 920 * 921 * @param t a {@link TypeMirror}; must not be {@code null} 922 * 923 * @return {@code true} if and only if {@code t} is a {@link DeclaredType}, {@linkplain 924 * TypeMirror#getKind() has a <code>TypeKind</code>} of {@link TypeKind#DECLARED DECLARED}, and {@linkplain 925 * DeclaredType#getTypeArguments() has a non-empty type arguments list}; {@code false} otherwise 926 * 927 * @exception NullPointerException if {@code t} is {@code null} 928 */ 929 // (Convenience.) 930 public default boolean parameterized(final TypeMirror t) { 931 return switch (t) { 932 case null -> throw new NullPointerException("t"); 933 case UniversalType ut -> ut.parameterized(); 934 default -> { 935 try (var lock = this.lock()) { 936 yield t.getKind() == DECLARED && !((DeclaredType)t).getTypeArguments().isEmpty(); 937 } 938 } 939 }; 940 } 941 942 /** 943 * Returns the result of applying <dfn>unboxing conversion</dfn> to the (logical) {@link TypeElement} bearing the 944 * supplied {@code canonicalName}. 945 * 946 * @param canonicalName a canonical name of either a primitive type or a so-called "wrapper" type; must not be {@code 947 * null} 948 * 949 * @return a non-{@code null} {@link PrimitiveType} with a {@linkplain TypeKind#isPrimitive() primitive} {@link 950 * TypeKind} 951 * 952 * @exception NullPointerException if {@code canonicalName} is {@code null} 953 * 954 * @exception IllegalArgumentException if {@code canonicalName} {@linkplain #toString(CharSequence) converted to a 955 * <code>String</code>} {@linkplain String#equals(Object) is not equal to} {@code boolean}, {@code byte}, {@code 956 * char}, {@code double}, {@code float}, {@code int}, {@code long}, {@code short}, {@link Boolean java.lang.Boolean}, 957 * {@link Byte java.lang.Byte}, {@link Character java.lang.Character}, {@link Double java.lang.Double}, {@link Float 958 * java.lang.Float}, {@link Integer java.lang.Integer}, {@link Long java.lang.Long}, or {@link Short java.lang.Short} 959 * 960 * @see #primitiveType(TypeKind) 961 * 962 * @see PrimitiveType 963 * 964 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-5.html#jls-5.1.8 Java Language Specification, section 965 * 5.1.8 966 * 967 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-6.html#jls-6.7 Java Language Specification, section 968 * 6.7 969 */ 970 // (Convenience.) 971 // (Unboxing.) 972 public default PrimitiveType primitiveType(final CharSequence canonicalName) { 973 final String s = this.toString(Objects.requireNonNull(canonicalName, "canonicalName")); 974 return switch (s) { 975 case "boolean", "java.lang.Boolean" -> this.primitiveType(TypeKind.BOOLEAN); 976 case "byte", "java.lang.Byte" -> this.primitiveType(TypeKind.BYTE); 977 case "char", "java.lang.Character" -> this.primitiveType(TypeKind.CHAR); 978 case "double", "java.lang.Double" -> this.primitiveType(TypeKind.DOUBLE); 979 case "float", "java.lang.Float" -> this.primitiveType(TypeKind.FLOAT); 980 case "int", "java.lang.Integer" -> this.primitiveType(TypeKind.INT); 981 case "long", "java.lang.Long" -> this.primitiveType(TypeKind.LONG); 982 case "short", "java.lang.Short" -> this.primitiveType(TypeKind.SHORT); 983 default -> throw new IllegalArgumentException("canonicalName: " + s); 984 }; 985 } 986 987 /** 988 * Returns the result of applying <dfn>unboxing conversion</dfn> to the {@linkplain Element#asType() type declared by 989 * the supplied <code>TypeElement</code>}. 990 * 991 * @param e a {@link TypeElement}; must not be {@code null} 992 * 993 * @return a non-{@code null} {@link PrimitiveType} with a {@linkplain TypeKind#isPrimitive() primitive} {@link 994 * TypeKind} 995 * 996 * @exception NullPointerException if {@code e} is {@code null} 997 * 998 * @exception IllegalArgumentException if there is no unboxing conversion that can be applied to the {@linkplain 999 * Element#asType() type declared by <code>e</code>} 1000 * 1001 * @see javax.lang.model.util.Types#unboxedType(TypeMirror) 1002 * 1003 * @see #primitiveType(TypeMirror) 1004 * 1005 * @see PrimitiveType 1006 * 1007 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-5.html#jls-5.1.8 Java Language Specification, section 1008 * 5.1.8 1009 */ 1010 // (Convenience.) 1011 // (Unboxing.) 1012 public default PrimitiveType primitiveType(final TypeElement e) { 1013 return this.primitiveType(e.asType()); 1014 } 1015 1016 /** 1017 * Returns the {@link PrimitiveType} corresponding to the supplied {@link TypeKind} (if it {@linkplain 1018 * TypeKind#isPrimitive() is primitive}). 1019 * 1020 * @param kind a {@linkplain TypeKind#isPrimitive() primitive} {@link TypeKind}; must not be {@code null} 1021 * 1022 * @return a non-{@code null} {@link PrimitiveType} {@linkplain TypeMirror#getKind() with} a {@linkplain 1023 * TypeKind#isPrimitive() primitive} {@link TypeKind} 1024 * 1025 * @exception NullPointerException if {@code kind} is {@code null} 1026 * 1027 * @exception IllegalArgumentException if {@code kind} {@linkplain TypeKind#isPrimitive() is not primitive} 1028 * 1029 * @see javax.lang.model.util.Types#getPrimitiveType(TypeKind) 1030 * 1031 * @see PrimitiveType 1032 * 1033 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.2 Java Language Specification, section 1034 * 4.2 1035 */ 1036 // (Canonical.) 1037 // Type factory method. 1038 public PrimitiveType primitiveType(final TypeKind kind); 1039 1040 /** 1041 * Returns the result of applying <dfn>unboxing conversion</dfn> to the supplied {@link TypeMirror}. 1042 * 1043 * @param t a {@link TypeMirror}; must not be {@code null} 1044 * 1045 * @return a non-{@code null} {@link PrimitiveType} with a {@linkplain TypeKind#isPrimitive() primitive} {@link 1046 * TypeKind} 1047 * 1048 * @exception NullPointerException if {@code t} is {@code null} 1049 * 1050 * @exception IllegalArgumentException if there is no unboxing conversion that can be applied to {@code t} 1051 * 1052 * @see javax.lang.model.util.Types#unboxedType(TypeMirror) 1053 * 1054 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-5.html#jls-5.1.8 Java Language Specification, section 1055 * 5.1.8 1056 */ 1057 // (Canonical.) 1058 // (Unboxing.) 1059 // Type factory method. 1060 public PrimitiveType primitiveType(final TypeMirror t); 1061 1062 /** 1063 * A convenience method that returns {@code true} if and only if the supplied {@link TypeMirror} represents a 1064 * <dfn>prototypical type</dfn>. 1065 * 1066 * <p>Prototypical types are not defined by the Java Language Specification. They are partially defined by the 1067 * {@linkplain TypeElement#asType() specification of the <code>TypeElement#asType()</code> 1068 * method}.</p> 1069 * 1070 * @param t a {@link TypeMirror}; must not be {@code null} 1071 * 1072 * @return {@code true} if and only if {@code t} represents a <dfn>prototypical type</dfn> 1073 * 1074 * @exception NullPointerException if {@code t} is {@code null} 1075 * 1076 * @see TypeElement#asType() 1077 */ 1078 // (Convenience.) 1079 public default boolean prototypical(final TypeMirror t) { 1080 return switch (t) { 1081 case null -> throw new NullPointerException("t"); 1082 case UniversalType ut -> ut.prototypical(); 1083 default -> { 1084 try (var lock = this.lock()) { 1085 yield t.getKind() == DECLARED && t.equals(((DeclaredType)t).asElement().asType()); 1086 } 1087 } 1088 }; 1089 } 1090 1091 /** 1092 * A convenience method that returns {@code true} if and only if the supplied {@link TypeMirror} is a <dfn>raw 1093 * type</dfn> according to <a href="https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8">the rules 1094 * of the Java Language Specification</a> 1095 * 1096 * @param t a {@link TypeMirror}; must not be {@code null} 1097 * 1098 * @return {@code true} if and only if the supplied {@link TypeMirror} is a <dfn>raw type</dfn> according to <a 1099 * href="https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8">the rules of the Java Language 1100 * Specification</a> 1101 * 1102 * @exception NullPointerException if {@code t} is {@code null} 1103 * 1104 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8 Java Language Specification, section 4.8 1105 */ 1106 // (Convenience.) 1107 public default boolean raw(final TypeMirror t) { 1108 return switch (t) { 1109 case null -> throw new NullPointerException("t"); 1110 case UniversalType ut -> ut.raw(); 1111 default -> { 1112 try (var lock = this.lock()) { 1113 yield switch (t.getKind()) { 1114 case ARRAY -> raw(elementType((ArrayType)t)); 1115 case DECLARED -> { 1116 final DeclaredType dt = (DeclaredType)t; 1117 yield generic(dt.asElement()) && dt.getTypeArguments().isEmpty(); 1118 } 1119 default -> false; 1120 }; 1121 } 1122 } 1123 }; 1124 } 1125 1126 /** 1127 * A convenience method that returns the <dfn>raw type</dfn> corresponding to {@code t}, <strong>or {@code null} if 1128 * {@code t} is <a href="https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8">incapable of yielding 1129 * a raw type</a></strong>. 1130 * 1131 * <p>Overrides of this method must conform to the requirements imposed by the relevant section of the relevant 1132 * version of the Java Language Specification concerning raw types.</p> 1133 * 1134 * @param t a {@link TypeMirror}; must not be {@code null} 1135 * 1136 * @return the raw type corresponding to the supplied {@link TypeMirror}, or {@code null} if {@code t} is <a 1137 * href="https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8">incapable of yielding a raw type</a> 1138 * 1139 * @exception NullPointerException if {@code t} is {@code null} 1140 * 1141 * @see #parameterized(TypeMirror) 1142 * 1143 * @see #elementType(TypeMirror) 1144 * 1145 * @see #erasure(TypeMirror) 1146 * 1147 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8 Java Language Specification, section 1148 * 4.8 1149 */ 1150 // (Convenience.) 1151 public default TypeMirror rawType(TypeMirror t) { 1152 return switch (t) { 1153 case null -> throw new NullPointerException("t"); 1154 case UniversalType ut -> ut.elementType().parameterized() ? this.erasure(ut) : null; 1155 default -> this.parameterized(this.elementType(t)) ? this.erasure(t) : null; 1156 }; 1157 } 1158 1159 /** 1160 * Returns a {@link RecordComponentElement} corresponding to the supplied {@link ExecutableElement}, <strong>or {@code 1161 * null} if there is no such {@link RecordComponentElement}</strong>. 1162 * 1163 * @param e an {@link ExecutableElement} {@linkplain ExecutableElement#getEnclosingElement() enclosed by} a record 1164 * representing an <dfn>accessor method</dfn>; must not be {@code null} 1165 * 1166 * @return a {@link RecordComponentElement} corresponding to the supplied {@link ExecutableElement}, or {@code null} 1167 * 1168 * @exception NullPointerException if {@code e} is {@code null} 1169 * 1170 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-8.html#jls-8.10.3 Java Language Specification, section 1171 * 8.10.3 1172 */ 1173 public RecordComponentElement recordComponentElement(final ExecutableElement e); 1174 1175 /** 1176 * Returns {@code true} if and only if the two arguments represent the <dfn>same type</dfn>. 1177 * 1178 * <p>This method differs from the {@link javax.lang.model.util.Types#isSameType(TypeMirror, TypeMirror)} method in 1179 * two ways:</p> 1180 * 1181 * <ul> 1182 * 1183 * <li>Its arguments may be {@code null}. If both arguments are {@code null}, {@code true} is returned. If only one 1184 * argument is {@code null}, {@code false} is returned.</li> 1185 * 1186 * <li>If the same Java object reference is passed as both arguments, {@code true} is returned (even if it {@linkplain 1187 * TypeMirror#getKind() has a <code>TypeKind</code>} of {@link TypeKind#WILDCARD}).</li> 1188 * 1189 * </ul> 1190 * 1191 * @param t0 the first {@link TypeMirror}; may be {@code null} 1192 * 1193 * @param t1 the second {@link TypeMirror}; may be {@code null} 1194 * 1195 * @return {@code true} if and only if the two arguments represent the <dfn>same type</dfn>; {@code false} otherwise 1196 * 1197 * @see javax.lang.model.util.Types#isSameType(TypeMirror, TypeMirror) 1198 * 1199 * @see <a href="https://bugs.openjdk.org/browse/JDK-8055219">JDK-8055219</a> 1200 * 1201 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.3.4 Java Language Specification, section 1202 * 4.3.4 1203 * 1204 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.5.1 Java Language Specification, section 1205 * 4.5.1 1206 */ 1207 public boolean sameType(final TypeMirror t0, final TypeMirror t1); 1208 1209 /** 1210 * Returns {@code true} if and only if {@code et0} is a <dfn>subsignature</dfn> of {@code et1}. 1211 * 1212 * @param et0 the first {@link ExecutableType}; must not be {@code null} 1213 * 1214 * @param et1 the second {@link ExecutableType}; must not be {@code null} 1215 * 1216 * @return {@code true} if and only if {@code et0} is a <dfn>subsignature</dfn> of {@code et1} 1217 * 1218 * @exception NullPointerException if either argument is {@code null} 1219 * 1220 * @exception ClassCastException if this method is implemented in terms of the {@link 1221 * javax.lang.model.util.Types#isSubsignature(ExecutableType, ExecutableType)} method, and if each of the supplied 1222 * {@link ExecutableType} arguments does not have an {@linkplain TypeKind#EXECUTABLE <code>EXECUTABLE</code> 1223 * <code>TypeKind</code>}; this exception type is undocumented by the {@link 1224 * javax.lang.model.util.Types#isSubsignature(ExecutableType, ExecutableType)} method and so is subject to change 1225 * without prior notice 1226 * 1227 * @see javax.lang.model.util.Types#isSubsignature(ExecutableType, ExecutableType) 1228 * 1229 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-8.html#jls-8.4.2 Java Language Specification, section 1230 * 8.4.2 1231 */ 1232 public boolean subsignature(final ExecutableType et0, final ExecutableType et1); 1233 1234 /** 1235 * Returns {@code true} if and only if {@code candidateSubtype} is a <dfn>subtype</dfn> of {@code supertype}. 1236 * 1237 * @param candidateSubtype the first {@link TypeMirror}; must not be {@code null} 1238 * 1239 * @param supertype the second {@link TypeMirror}; must not be {@code null} 1240 * 1241 * @return {@code true} if and only if {@code candidateSubtype} is a <dfn>subtype</dfn> of {@code supertype} 1242 * 1243 * @exception NullPointerException if either argument is {@code null} 1244 * 1245 * @see javax.lang.model.util.Types#isSubtype(TypeMirror, TypeMirror) 1246 * 1247 * @spec https://docs.oracle.com/javase/specs/jls/se25/html/jls-4.html#jls-4.10 Java Language Specification, section 1248 * 4.10 1249 */ 1250 public boolean subtype(TypeMirror candidateSubtype, TypeMirror supertype); 1251 1252 /** 1253 * A convenience method that returns the {@link TypeMirror} corresponding to the supplied (reflective) {@link Type}. 1254 * 1255 * @param t a {@link Type}; must not be {@code null} 1256 * 1257 * @return the {@link TypeMirror} corresponding to the supplied {@link Type}; never {@code null} 1258 * 1259 * @exception NullPointerException if {@code t} is {@code null} 1260 * 1261 * @exception IllegalArgumentException if {@code t} is not a {@link Class}, {@link GenericArrayType}, {@link 1262 * ParameterizedType}, {@link java.lang.reflect.TypeVariable} or {@link java.lang.reflect.WildcardType} 1263 */ 1264 // (Convenience.) 1265 public default TypeMirror type(final Type t) { 1266 // TODO: anywhere there is domain.declaredType(), consider passing 1267 // domain.moduleElement(this.getClass().getModule().getName()) as the first argument. Not sure how this works 1268 // exactly but I think it might be necessary. 1269 return switch (t) { 1270 case null -> throw new NullPointerException("t"); 1271 case Class<?> c when t == boolean.class -> this.primitiveType(TypeKind.BOOLEAN); 1272 case Class<?> c when t == byte.class -> this.primitiveType(TypeKind.BYTE); 1273 case Class<?> c when t == char.class -> this.primitiveType(TypeKind.CHAR); 1274 case Class<?> c when t == double.class -> this.primitiveType(TypeKind.DOUBLE); 1275 case Class<?> c when t == float.class -> this.primitiveType(TypeKind.FLOAT); 1276 case Class<?> c when t == int.class -> this.primitiveType(TypeKind.INT); 1277 case Class<?> c when t == long.class -> this.primitiveType(TypeKind.LONG); 1278 case Class<?> c when t == short.class -> this.primitiveType(TypeKind.SHORT); 1279 case Class<?> c when t == void.class -> this.noType(TypeKind.VOID); 1280 case Class<?> c when t == Object.class -> this.javaLangObject().asType(); // cheap and easy optimization 1281 case Class<?> c when c.isArray() -> this.arrayTypeOf(this.type(c.getComponentType())); 1282 case Class<?> c -> this.declaredType(c.getCanonicalName()); 1283 case GenericArrayType g -> this.arrayTypeOf(this.type(g.getGenericComponentType())); 1284 case ParameterizedType pt when pt.getOwnerType() == null -> 1285 this.declaredType(this.typeElement(((Class<?>)pt.getRawType()).getCanonicalName()), 1286 this.types(pt.getActualTypeArguments())); 1287 case ParameterizedType pt -> 1288 this.declaredType((DeclaredType)this.type(pt.getOwnerType()), 1289 this.typeElement(((Class<?>)pt.getRawType()).getCanonicalName()), 1290 this.types(pt.getActualTypeArguments())); 1291 case java.lang.reflect.TypeVariable<?> tv -> this.typeVariable(this.parameterizable(tv.getGenericDeclaration()), tv.getName()); 1292 case java.lang.reflect.WildcardType w when w.getLowerBounds().length <= 0 -> this.wildcardType(this.type(w.getUpperBounds()[0]), null); 1293 case java.lang.reflect.WildcardType w -> this.wildcardType(null, this.type(w.getLowerBounds()[0])); 1294 default -> throw new IllegalArgumentException("t: " + t); 1295 }; 1296 } 1297 1298 /** 1299 * A convenience method that returns an array of {@link TypeMirror}s whose elements correspond, in order, to the 1300 * elements in the supplied {@link Type} array. 1301 * 1302 * @param ts an array of {@link Type}s; must not be {@code null} 1303 * 1304 * @return an array of {@link TypeMirror}s whose elements correspond, in order, to the elements in the supplied {@link 1305 * Type} array; never {@code null} 1306 * 1307 * @exception NullPointerException if {@code ts} is {@code null} or contains {@code null} elements 1308 * 1309 * @exception IllegalArgumentException if any element of {@code ts} is deemed illegal by the {@link #type(Type)} 1310 * method 1311 * 1312 * @see #type(Type) 1313 */ 1314 // (Convenience.) 1315 public default TypeMirror[] types(final Type[] ts) { 1316 return switch (ts.length) { 1317 case 0 -> new TypeMirror[0]; 1318 case 1 -> new TypeMirror[] { this.type(ts[0]) }; 1319 default -> { 1320 final TypeMirror[] rv = new TypeMirror[ts.length]; 1321 for (int i = 0; i < ts.length; i++) { 1322 rv[i] = this.type(ts[i]); 1323 } 1324 yield rv; 1325 } 1326 }; 1327 } 1328 1329 /** 1330 * Returns a {@link TypeElement} representing the element bearing the supplied <dfn>canonical name</dfn>, <strong>or 1331 * {@code null} if there is no such {@link TypeElement}</strong>. 1332 * 1333 * @param canonicalName a valid canonical name; must not be {@code null} 1334 * 1335 * @return a {@link TypeElement}, or {@code null} 1336 * 1337 * @exception NullPointerException if {@code canonicalName} is {@code null} 1338 * 1339 * @see javax.lang.model.util.Elements#getTypeElement(CharSequence) 1340 * 1341 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-6.html#jls-6.7 Java Language Specification, section 1342 * 6.7 1343 */ 1344 // Element factory method. 1345 public TypeElement typeElement(final CharSequence canonicalName); 1346 1347 /** 1348 * Returns a {@link TypeElement} representing the element bearing the supplied <dfn>canonical name</dfn>, as read or 1349 * seen from the module represented by the supplied {@link ModuleElement}, <strong>or {@code null} if there is no such 1350 * {@link TypeElement}</strong>. 1351 * 1352 * @param asSeenFrom a {@link ModuleElement}; must not be {@code null} 1353 * 1354 * @param canonicalName a valid canonical name; must not be {@code null} 1355 * 1356 * @return a {@link TypeElement}, or {@code null} 1357 * 1358 * @exception NullPointerException if either {@code asSeenFrom} or {@code canonicalName} is {@code null} 1359 * 1360 * @see javax.lang.model.util.Elements#getTypeElement(ModuleElement, CharSequence) 1361 * 1362 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-6.html#jls-6.7 Java Language Specification, section 1363 * 6.7 1364 */ 1365 // Element factory method. 1366 public TypeElement typeElement(final ModuleElement asSeenFrom, final CharSequence canonicalName); 1367 1368 /** 1369 * Returns a {@link TypeElement} representing the result of applying <dfn>boxing conversion</dfn> to the primitive 1370 * type represented by the supplied {@link PrimitiveType} argument. 1371 * 1372 * <p>The default implementation of this method calls the {@link #typeElement(TypeKind)} method with the supplied 1373 * {@link PrimitiveType}'s {@linkplain TypeMirror#getKind() affiliated <code>TypeKind</code>} and returns its 1374 * result.</p> 1375 * 1376 * @param t a {@link PrimitiveType} with a {@link TypeKind} that {@linkplain TypeKind#isPrimitive() is primitive}; 1377 * must not be {@code null} 1378 * 1379 * @return a non-{@code null} {@link TypeElement} representing the result of applying boxing conversion to the 1380 * supplied argument 1381 * 1382 * @exception NullPointerException if {@code t} is {@code null} 1383 * 1384 * @exception ClassCastException if this method is implemented in terms of the {@link 1385 * javax.lang.model.util.Types#boxedClass(PrimitiveType)} method, and if the supplied {@link PrimitiveType} does not 1386 * have a {@linkplain TypeKind#isPrimitive() primitive <code>TypeKind</code>}; this exception type is undocumented by 1387 * the {@link javax.lang.model.util.Types#boxedClass(PrimitiveType)} method and so is subject to change without prior 1388 * notice 1389 * 1390 * @exception IllegalArgumentException if {@code primitiveTypeKind} {@linkplain TypeKind#isPrimitive() is not 1391 * primitive} 1392 * 1393 * @see #typeElement(TypeKind) 1394 * 1395 * @see javax.lang.model.util.Types#boxedClass(PrimitiveType) 1396 * 1397 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-5.html#jls-5.1.7 Java Language Specification, section 1398 * 5.1.7 1399 */ 1400 // Element factory method. 1401 // (Canonical.) 1402 // (Boxing.) 1403 public default TypeElement typeElement(final PrimitiveType t) { 1404 return switch (t) { 1405 case null -> throw new NullPointerException("t"); 1406 case UniversalType ut -> this.typeElement(ut.getKind()); 1407 default -> { 1408 try (var lock = this.lock()) { 1409 yield this.typeElement(t.getKind()); 1410 } 1411 } 1412 }; 1413 } 1414 1415 /** 1416 * Returns a {@link TypeElement} representing the result of applying <dfn>boxing conversion</dfn> to the primitive 1417 * type represented by the supplied {@link TypeKind} argument, if it {@linkplain TypeKind#isPrimitive() is primitive}. 1418 * 1419 * @param primitiveTypeKind a {@link TypeKind} that {@linkplain TypeKind#isPrimitive() is primitive}; must not be 1420 * {@code null} 1421 * 1422 * @return a non-{@code null} {@link TypeElement} representing the result of applying boxing conversion to the 1423 * supplied argument 1424 * 1425 * @exception IllegalArgumentException if {@code primitiveTypeKind} {@linkplain TypeKind#isPrimitive() is not 1426 * primitive} 1427 * 1428 * @see #typeElement(PrimitiveType) 1429 * 1430 * @see javax.lang.model.util.Types#boxedClass(PrimitiveType) 1431 * 1432 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-5.html#jls-5.1.7 Java Language Specification, section 1433 * 5.1.7 1434 */ 1435 // (Convenience.) 1436 // (Boxing.) 1437 public default TypeElement typeElement(final TypeKind primitiveTypeKind) { 1438 return switch (primitiveTypeKind) { 1439 case BOOLEAN -> this.typeElement("java.lang.Boolean"); 1440 case BYTE -> this.typeElement("java.lang.Byte"); 1441 case CHAR -> this.typeElement("java.lang.Character"); 1442 case DOUBLE -> this.typeElement("java.lang.Double"); 1443 case FLOAT -> this.typeElement("java.lang.Float"); 1444 case INT -> this.typeElement("java.lang.Integer"); 1445 case LONG -> this.typeElement("java.lang.Long"); 1446 case SHORT -> this.typeElement("java.lang.Short"); 1447 default -> throw new IllegalArgumentException("primitiveTypeKind: " + primitiveTypeKind); 1448 }; 1449 } 1450 1451 /** 1452 * Returns the {@link TypeParameterElement} {@linkplain Parameterizable#getTypeParameters() contained} by the supplied 1453 * {@link Parameterizable} whose {@linkplain TypeParameterElement#getSimpleName() name} {@linkplain 1454 * Name#contentEquals(CharSequence) is equal to} the supplied {@code name}, <strong>or {@code null} if there is no 1455 * such {@link TypeParameterElement}</strong>. 1456 * 1457 * @param p a {@link Parameterizable}; must not be {@code null} 1458 * 1459 * @param name a name valid for a type parameter; must not be {@code null} 1460 * 1461 * @return a {@link TypeParameterElement}, or {@code null} 1462 */ 1463 // (Convenience.) 1464 public default TypeParameterElement typeParameterElement(Parameterizable p, final CharSequence name) { 1465 Objects.requireNonNull(p, "p"); 1466 Objects.requireNonNull(name, "name"); 1467 while (p != null) { 1468 switch (p) { 1469 case UniversalElement ue: 1470 for (final UniversalElement tpe : ue.getTypeParameters()) { 1471 if (tpe.getSimpleName().contentEquals(name)) { 1472 return tpe; 1473 } 1474 } 1475 p = ue.getEnclosingElement(); 1476 break; 1477 default: 1478 try (var lock = this.lock()) { 1479 for (final TypeParameterElement tpe : p.getTypeParameters()) { 1480 if (tpe.getSimpleName().contentEquals(name)) { 1481 return tpe; 1482 } 1483 } 1484 p = (Parameterizable)((Element)p).getEnclosingElement(); 1485 } 1486 break; 1487 } 1488 } 1489 return null; 1490 } 1491 1492 /** 1493 * A convenience method that returns the {@link TypeVariable} {@linkplain TypeParameterElement#asType() declared by} 1494 * the {@link TypeParameterElement} {@linkplain Parameterizable#getTypeParameters() contained} by the supplied {@link 1495 * Parameterizable} whose {@linkplain TypeParameterElement#getSimpleName() name} {@linkplain 1496 * Name#contentEquals(CharSequence) is equal to} the supplied {@code name}, <strong>or {@code null} if there is no 1497 * such {@link TypeParameterElement} or {@link TypeVariable}</strong>. 1498 * 1499 * @param p a {@link Parameterizable}; must not be {@code null} 1500 * 1501 * @param name a name valid for a type parameter; must not be {@code null} 1502 * 1503 * @return a {@link TypeVariable}, or {@code null} 1504 * 1505 * @see #typeParameterElement(Parameterizable, CharSequence) 1506 */ 1507 // (Convenience.) 1508 public default TypeVariable typeVariable(Parameterizable p, final CharSequence name) { 1509 final TypeParameterElement e = this.typeParameterElement(p, name); 1510 return e == null ? null : (TypeVariable)e.asType(); 1511 } 1512 1513 /** 1514 * A convenience method that returns the first {@link VariableElement} with a {@linkplain ElementKind#isVariable() 1515 * variable <code>ElementKind</code>} and {@linkplain Element#getSimpleName() bearing} the supplied {@code simpleName} 1516 * that the supplied {@code enclosingElement} {@linkplain Element#getEnclosedElements() encloses}, <strong>or {@code 1517 * null} if there is no such {@link VariableElement}</strong>. 1518 * 1519 * @param enclosingElement an {@link Element}; must not be {@code null} 1520 * 1521 * @param simpleName a {@link CharSequence}; must not be {@code null} 1522 * 1523 * @return a {@link VariableElement}, or {@code null} 1524 * 1525 * @exception NullPointerException if either argument is {@code null} 1526 * 1527 * @see Element#getEnclosedElements() 1528 * 1529 * @see ElementKind#isVariable() 1530 * 1531 * @see Element#getSimpleName() 1532 * 1533 * @see VariableElement 1534 */ 1535 // (Convenience.) 1536 public default VariableElement variableElement(final Element enclosingElement, final CharSequence simpleName) { 1537 Objects.requireNonNull(simpleName, "simpleName"); 1538 return switch (enclosingElement) { 1539 case null -> throw new NullPointerException("enclosingElement"); 1540 case UniversalElement ue -> { 1541 for (final UniversalElement ee : ue.getEnclosedElements()) { 1542 if (ee.getKind().isVariable() && ee.getSimpleName().contentEquals(simpleName)) { 1543 yield ee; 1544 } 1545 } 1546 yield null; 1547 } 1548 default -> { 1549 try (var lock = lock()) { 1550 for (final Element ee : enclosingElement.getEnclosedElements()) { 1551 if (ee.getKind().isVariable() && ee.getSimpleName().contentEquals(simpleName)) { 1552 yield (VariableElement)ee; 1553 } 1554 } 1555 } 1556 yield null; 1557 } 1558 }; 1559 } 1560 1561 /** 1562 * A convenience method that returns a new {@link WildcardType} {@linkplain TypeMirror#getKind() with a 1563 * <code>TypeKind</code>} of {@link TypeKind#WILDCARD}, an {@linkplain WildcardType#getExtendsBound() extends bound} 1564 * of {@code null}, and a {@linkplain WildcardType#getSuperBound() super bound} of {@code null}. 1565 * 1566 * @return a new, non-{@code null} {@link WildcardType} 1567 * 1568 * @see #wildcardType(TypeMirror, TypeMirror) 1569 * 1570 * @see javax.lang.model.util.Types#getWildcardType(TypeMirror, TypeMirror) 1571 * 1572 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.5.1 Java Language Specification, section 1573 * 4.5.1 1574 */ 1575 // (Convenience.) 1576 public default WildcardType wildcardType() { 1577 return this.wildcardType(null, null); 1578 } 1579 1580 /** 1581 * Returns a new {@link WildcardType} {@linkplain TypeMirror#getKind() with a <code>TypeKind</code>} of {@link 1582 * TypeKind#WILDCARD}, an {@linkplain WildcardType#getExtendsBound() extends bound} of the supplied {@code 1583 * extendsBound}, and a {@linkplain WildcardType#getSuperBound() super bound} of the supplied {@code superBound}. 1584 * 1585 * <p>Any argument may be {@code null}. Both arguments may not be non-{@code null}.</p> 1586 * 1587 * @param extendsBound the upper bound of the new {@link WildcardType}; may be {@code null} 1588 * 1589 * @param superBound the lower bound of the new {@link WildcardType}; may be {@code null} 1590 * 1591 * @return a new, non-{@code null} {@link WildcardType} 1592 * 1593 * @exception IllegalArgumentException if both arguments are non-{@code null} or otherwise unsuitable for being the 1594 * bounds of a {@link WildcardType} 1595 * 1596 * @see javax.lang.model.util.Types#getWildcardType(TypeMirror, TypeMirror) 1597 * 1598 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.5.1 Java Language Specification, section 1599 * 4.5.1 1600 */ 1601 // Type factory method. 1602 public WildcardType wildcardType(TypeMirror extendsBound, TypeMirror superBound); 1603 1604}