4040import javax .lang .model .type .TypeVariable ;
4141import javax .lang .model .type .WildcardType ;
4242
43+ import org .microbean .construct .element .StringName ;
44+ import org .microbean .construct .element .UniversalElement ;
45+
46+ import org .microbean .construct .type .UniversalType ;
47+
4348import static javax .lang .model .element .ElementKind .CONSTRUCTOR ;
4449import static javax .lang .model .element .ElementKind .METHOD ;
4550
@@ -358,9 +363,15 @@ public DeclaredType declaredType(final DeclaredType enclosingType,
358363 * 10.1
359364 */
360365 public default TypeMirror elementType (final TypeMirror t ) {
361- try (var lock = lock ()) {
362- return t .getKind () == TypeKind .ARRAY ? this .elementType (((ArrayType )t ).getComponentType ()) : t ;
366+ return switch (t ) {
367+ case null -> throw new NullPointerException ("t" );
368+ case UniversalType ut -> ut .elementType ();
369+ default -> {
370+ try (var lock = lock ()) {
371+ yield t .getKind () == TypeKind .ARRAY ? this .elementType (((ArrayType )t ).getComponentType ()) : t ;
372+ }
363373 }
374+ };
364375 }
365376
366377 /**
@@ -409,17 +420,19 @@ public default ExecutableElement executableElement(final TypeElement declaringEl
409420 final TypeMirror returnType ,
410421 final CharSequence name ,
411422 final TypeMirror ... parameterTypes ) {
412- try (var lock = this .lock ()) {
413- final List <? extends Element > ees = declaringElement .getEnclosedElements ();
414- return ees .stream ()
423+ return switch (declaringElement ) {
424+ case null -> throw new NullPointerException ("declaringElement" );
425+ case UniversalElement ue -> {
426+ final List <? extends UniversalElement > ees = ue .getEnclosedElements ();
427+ yield ees .stream ()
415428 .sequential ()
416429 .filter (e -> e .getKind ().isExecutable () && e .getSimpleName ().contentEquals (name ))
417- .map (ExecutableElement .class ::cast )
430+ .map (UniversalElement .class ::cast )
418431 .filter (ee -> {
419432 if (!this .sameType (returnType , ee .getReturnType ())) {
420433 return false ;
421434 }
422- final List <? extends VariableElement > ps = ee .getParameters ();
435+ final List <? extends UniversalElement > ps = ee .getParameters ();
423436 if (ps .size () != parameterTypes .length ) {
424437 return false ;
425438 }
@@ -433,6 +446,33 @@ public default ExecutableElement executableElement(final TypeElement declaringEl
433446 .findFirst ()
434447 .orElse (null );
435448 }
449+ default -> {
450+ try (var lock = this .lock ()) {
451+ final List <? extends Element > ees = declaringElement .getEnclosedElements ();
452+ yield ees .stream ()
453+ .sequential ()
454+ .filter (e -> e .getKind ().isExecutable () && e .getSimpleName ().contentEquals (name ))
455+ .map (ExecutableElement .class ::cast )
456+ .filter (ee -> {
457+ if (!this .sameType (returnType , ee .getReturnType ())) {
458+ return false ;
459+ }
460+ final List <? extends VariableElement > ps = ee .getParameters ();
461+ if (ps .size () != parameterTypes .length ) {
462+ return false ;
463+ }
464+ for (int i = 0 ; i < parameterTypes .length ; i ++) {
465+ if (!this .sameType (ps .get (i ).asType (), parameterTypes [i ])) {
466+ return false ;
467+ }
468+ }
469+ return true ;
470+ })
471+ .findFirst ()
472+ .orElse (null );
473+ }
474+ }
475+ };
436476 }
437477
438478 /**
@@ -459,15 +499,19 @@ public default ExecutableElement executableElement(final TypeElement declaringEl
459499 * 9.1.2
460500 */
461501 public default boolean generic (final Element e ) {
462- if (Objects .requireNonNull (e , "e" ) instanceof Parameterizable p ) {
502+ return switch (e ) {
503+ case null -> throw new NullPointerException ("e" );
504+ case UniversalElement ue -> ue .generic ();
505+ case Parameterizable p -> {
463506 try (var lock = this .lock ()) {
464- return switch (e .getKind ()) {
507+ yield switch (e .getKind ()) {
465508 case CLASS , CONSTRUCTOR , ENUM , INTERFACE , METHOD , RECORD -> !p .getTypeParameters ().isEmpty ();
466509 default -> false ;
467510 };
468511 }
469512 }
470- return false ;
513+ default -> false ;
514+ };
471515 }
472516
473517 /**
@@ -482,11 +526,17 @@ public default boolean generic(final Element e) {
482526 * @exception NullPointerException if {@code e} is {@code null}
483527 */
484528 public default boolean javaLangObject (final Element e ) {
485- try (var lock = this .lock ()) {
486- return
487- e .getKind () == ElementKind .CLASS &&
488- ((QualifiedNameable )e ).getQualifiedName ().contentEquals ("java.lang.Object" );
529+ return switch (e ) {
530+ case null -> throw new NullPointerException ("e" );
531+ case UniversalElement ue -> ue .javaLangObject ();
532+ default -> {
533+ try (var lock = this .lock ()) {
534+ yield
535+ e .getKind () == ElementKind .CLASS &&
536+ ((QualifiedNameable )e ).getQualifiedName ().contentEquals ("java.lang.Object" );
537+ }
489538 }
539+ };
490540 }
491541
492542 /**
@@ -503,11 +553,17 @@ public default boolean javaLangObject(final Element e) {
503553 * @see #javaLangObject(Element)
504554 */
505555 public default boolean javaLangObject (final TypeMirror t ) {
506- try (var lock = this .lock ()) {
507- return
508- t .getKind () == TypeKind .DECLARED &&
509- javaLangObject (((DeclaredType )t ).asElement ());
556+ return switch (t ) {
557+ case null -> throw new NullPointerException ("t" );
558+ case UniversalType ut -> ut .javaLangObject ();
559+ default -> {
560+ try (var lock = this .lock ()) {
561+ yield
562+ t .getKind () == TypeKind .DECLARED &&
563+ javaLangObject (((DeclaredType )t ).asElement ());
564+ }
510565 }
566+ };
511567 }
512568
513569 /**
@@ -660,11 +716,15 @@ public default TypeElement javaLangObject() {
660716 * @exception NullPointerException if {@code t} is {@code null}
661717 */
662718 public default boolean parameterized (final TypeMirror t ) {
663- try (var lock = this .lock ()) {
664- return
665- t .getKind () == TypeKind .DECLARED &&
666- !((DeclaredType )t ).getTypeArguments ().isEmpty ();
719+ return switch (t ) {
720+ case null -> throw new NullPointerException ("t" );
721+ case UniversalType ut -> ut .parameterized ();
722+ default -> {
723+ try (var lock = this .lock ()) {
724+ yield t .getKind () == TypeKind .DECLARED && !((DeclaredType )t ).getTypeArguments ().isEmpty ();
725+ }
667726 }
727+ };
668728 }
669729
670730 /**
@@ -795,16 +855,22 @@ public default PrimitiveType primitiveType(final TypeElement e) {
795855 * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8 Java Language Specification, section 4.8
796856 */
797857 public default boolean raw (final TypeMirror t ) {
798- try (var lock = this .lock ()) {
799- return switch (t .getKind ()) {
800- case ARRAY -> raw (elementType ((ArrayType )t ));
801- case DECLARED -> {
802- final DeclaredType dt = (DeclaredType )t ;
803- yield generic (dt .asElement ()) && dt .getTypeArguments ().isEmpty ();
858+ return switch (t ) {
859+ case null -> throw new NullPointerException ("t" );
860+ case UniversalType ut -> ut .raw ();
861+ default -> {
862+ try (var lock = this .lock ()) {
863+ yield switch (t .getKind ()) {
864+ case ARRAY -> raw (elementType ((ArrayType )t ));
865+ case DECLARED -> {
866+ final DeclaredType dt = (DeclaredType )t ;
867+ yield generic (dt .asElement ()) && dt .getTypeArguments ().isEmpty ();
868+ }
869+ default -> false ;
870+ };
804871 }
805- default -> false ;
806- };
807872 }
873+ };
808874 }
809875
810876 /**
@@ -822,15 +888,22 @@ public default boolean raw(final TypeMirror t) {
822888 *
823889 * @exception NullPointerException if {@code t} is {@code null}
824890 *
825- * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8 Java Language Specification, section 4.8
891+ * @spec https://docs.oracle.com/javase/specs/jls/se23/html/jls-4.html#jls-4.8 Java Language Specification, section
892+ * 4.8
826893 */
827894 public default TypeMirror rawType (final TypeMirror t ) {
828- try (var lock = this .lock ()) {
829- return switch (t .getKind ()) {
830- case ARRAY -> this .rawType (this .elementType (t )); // recursive
831- default -> this .parameterized (t ) ? this .erasure (t ) : null ;
832- };
895+ return switch (t ) {
896+ case null -> throw new NullPointerException ("t" );
897+ case UniversalType ut -> ut .rawType ();
898+ default -> {
899+ try (var lock = this .lock ()) {
900+ yield switch (t .getKind ()) {
901+ case ARRAY -> this .rawType (this .elementType (t )); // recursive
902+ default -> this .parameterized (t ) ? this .erasure (t ) : null ;
903+ };
904+ }
833905 }
906+ };
834907 }
835908
836909 /**
@@ -938,6 +1011,7 @@ public default String toString(final CharSequence name) {
9381011 return switch (name ) {
9391012 case null -> null ;
9401013 case String s -> s ;
1014+ case StringName sn -> sn .value ();
9411015 case Name n -> {
9421016 try (var lock = this .lock ()) {
9431017 yield n .toString ();
@@ -1019,9 +1093,15 @@ public default String toString(final CharSequence name) {
10191093 // (Canonical.)
10201094 // (Boxing.)
10211095 public default TypeElement typeElement (final PrimitiveType t ) {
1022- try (var lock = this .lock ()) {
1023- return this .typeElement (t .getKind ());
1096+ return switch (t ) {
1097+ case null -> throw new NullPointerException ("t" );
1098+ case UniversalType ut -> this .typeElement (ut .getKind ());
1099+ default -> {
1100+ try (var lock = this .lock ()) {
1101+ yield this .typeElement (t .getKind ());
1102+ }
10241103 }
1104+ };
10251105 }
10261106
10271107 /**
@@ -1076,20 +1156,26 @@ public default TypeParameterElement typeParameterElement(Parameterizable p, fina
10761156 Objects .requireNonNull (p , "p" );
10771157 Objects .requireNonNull (name , "name" );
10781158 while (p != null ) {
1079- // A call to getTypeParameters() does not cause symbol completion, but name acquisition also needs to be
1080- // serialized globally.
1081- try (var lock = this .lock ()) {
1082- for (final TypeParameterElement tpe : p .getTypeParameters ()) {
1159+ switch (p ) {
1160+ case UniversalElement ue :
1161+ for (final UniversalElement tpe : ue .getTypeParameters ()) {
10831162 if (tpe .getSimpleName ().contentEquals (name )) {
10841163 return tpe ;
10851164 }
10861165 }
1166+ p = ue .getEnclosingElement ();
1167+ break ;
1168+ default :
1169+ try (var lock = this .lock ()) {
1170+ for (final TypeParameterElement tpe : p .getTypeParameters ()) {
1171+ if (tpe .getSimpleName ().contentEquals (name )) {
1172+ return tpe ;
1173+ }
1174+ }
1175+ p = (Parameterizable )((Element )p ).getEnclosingElement ();
1176+ }
1177+ break ;
10871178 }
1088- p = switch (p ) {
1089- case ExecutableElement ee -> (Parameterizable )ee .getEnclosingElement ();
1090- case TypeElement te -> (Parameterizable )te .getEnclosingElement ();
1091- default -> null ;
1092- };
10931179 }
10941180 return null ;
10951181 }
@@ -1138,14 +1224,27 @@ public default TypeVariable typeVariable(Parameterizable p, final CharSequence n
11381224 */
11391225 public default VariableElement variableElement (final Element enclosingElement , final CharSequence simpleName ) {
11401226 Objects .requireNonNull (simpleName , "simpleName" );
1141- try (var lock = lock ()) {
1142- for (final Element ee : enclosingElement .getEnclosedElements ()) {
1227+ return switch (enclosingElement ) {
1228+ case null -> throw new NullPointerException ("enclosingElement" );
1229+ case UniversalElement ue -> {
1230+ for (final UniversalElement ee : ue .getEnclosedElements ()) {
11431231 if (ee .getKind ().isVariable () && ee .getSimpleName ().contentEquals (simpleName )) {
1144- return ( VariableElement ) ee ;
1232+ yield ee ;
11451233 }
11461234 }
1235+ yield null ;
11471236 }
1148- return null ;
1237+ default -> {
1238+ try (var lock = lock ()) {
1239+ for (final Element ee : enclosingElement .getEnclosedElements ()) {
1240+ if (ee .getKind ().isVariable () && ee .getSimpleName ().contentEquals (simpleName )) {
1241+ yield (VariableElement )ee ;
1242+ }
1243+ }
1244+ }
1245+ yield null ;
1246+ }
1247+ };
11491248 }
11501249
11511250 /**
0 commit comments