Improve registration of the same hint for multiple classes

Based on the feedback in #28977 an easy way to create a list of
type references based on a vararg of classes is helpful when
registering the same hints for several types.
This commit is contained in:
Stephane Nicoll
2022-08-18 06:52:34 +02:00
parent 4556895e6e
commit d6afa8df2d
11 changed files with 158 additions and 124 deletions

View File

@@ -19,7 +19,6 @@ package org.springframework.aot.hint;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.function.Consumer;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
@@ -109,8 +108,8 @@ class ReflectionHintsTests {
@Test
void registerTypesApplyTheSameHints() {
this.reflectionHints.registerTypes(Stream.of(Integer.class, String.class, Double.class)
.map(TypeReference::of).toList(), hint -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS));
this.reflectionHints.registerTypes(TypeReference.listOf(Integer.class, String.class, Double.class),
hint -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS));
assertThat(this.reflectionHints.typeHints())
.anySatisfy(
typeWithMemberCategories(Integer.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS))

View File

@@ -82,7 +82,7 @@ class TypeHintTests {
@Test
void createWithConstructor() {
List<TypeReference> parameterTypes = List.of(TypeReference.of(byte[].class), TypeReference.of(int.class));
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
TypeHint hint = TypeHint.of(TypeReference.of(String.class)).withConstructor(parameterTypes,
constructorHint -> constructorHint.withMode(ExecutableMode.INVOKE)).build();
assertThat(hint.constructors()).singleElement().satisfies(constructorHint -> {
@@ -93,7 +93,7 @@ class TypeHintTests {
@Test
void createConstructorReuseBuilder() {
List<TypeReference> parameterTypes = List.of(TypeReference.of(byte[].class), TypeReference.of(int.class));
List<TypeReference> parameterTypes = TypeReference.listOf(byte[].class, int.class);
Builder builder = TypeHint.of(TypeReference.of(String.class)).withConstructor(parameterTypes,
constructorHint -> constructorHint.withMode(ExecutableMode.INVOKE));
TypeHint hint = builder.withConstructor(parameterTypes, constructorHint ->
@@ -118,7 +118,7 @@ class TypeHintTests {
@Test
void createWithMethodReuseBuilder() {
List<TypeReference> parameterTypes = List.of(TypeReference.of(char[].class));
List<TypeReference> parameterTypes = TypeReference.listOf(char[].class);
Builder builder = TypeHint.of(TypeReference.of(String.class)).withMethod("valueOf", parameterTypes,
methodHint -> methodHint.withMode(ExecutableMode.INVOKE));
TypeHint hint = builder.withMethod("valueOf", parameterTypes,

View File

@@ -19,7 +19,6 @@ package org.springframework.aot.hint.predicate;
import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import org.junit.jupiter.api.BeforeAll;
@@ -66,41 +65,44 @@ class ReflectionHintsPredicatesTests {
@Test
void reflectionOnClassShouldMatchIntrospection() {
runtimeHints.reflection().registerType(SampleClass.class, builder -> {
});
runtimeHints.reflection().registerType(SampleClass.class, builder -> {});
assertPredicateMatches(reflection.onType(SampleClass.class));
}
@Test
void reflectionOnTypeReferenceShouldMatchIntrospection() {
runtimeHints.reflection().registerType(SampleClass.class, builder -> {
});
runtimeHints.reflection().registerType(SampleClass.class, builder -> {});
assertPredicateMatches(reflection.onType(TypeReference.of(SampleClass.class)));
}
@Test
void reflectionOnDifferentClassShouldNotMatchIntrospection() {
runtimeHints.reflection().registerType(Integer.class, builder -> {
});
runtimeHints.reflection().registerType(Integer.class, builder -> {});
assertPredicateDoesNotMatch(reflection.onType(TypeReference.of(SampleClass.class)));
}
@Test
void typeWithMemberCategoryFailsWithNullCategory() {
runtimeHints.reflection().registerType(SampleClass.class, builder -> builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
assertThatIllegalArgumentException().isThrownBy(() -> reflection.onType(SampleClass.class).withMemberCategory(null));
runtimeHints.reflection().registerType(SampleClass.class, builder ->
builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
assertThatIllegalArgumentException().isThrownBy(() ->
reflection.onType(SampleClass.class).withMemberCategory(null));
}
@Test
void typeWithMemberCategoryMatchesCategory() {
runtimeHints.reflection().registerType(SampleClass.class, builder -> builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
assertPredicateMatches(reflection.onType(SampleClass.class).withMemberCategory(MemberCategory.INTROSPECT_PUBLIC_METHODS));
runtimeHints.reflection().registerType(SampleClass.class,
builder -> builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
assertPredicateMatches(reflection.onType(SampleClass.class)
.withMemberCategory(MemberCategory.INTROSPECT_PUBLIC_METHODS));
}
@Test
void typeWithMemberCategoryDoesNotMatchOtherCategory() {
runtimeHints.reflection().registerType(SampleClass.class, builder -> builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
assertPredicateDoesNotMatch(reflection.onType(SampleClass.class).withMemberCategory(MemberCategory.INVOKE_PUBLIC_METHODS));
runtimeHints.reflection().registerType(SampleClass.class,
builder -> builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
assertPredicateDoesNotMatch(reflection.onType(SampleClass.class)
.withMemberCategory(MemberCategory.INVOKE_PUBLIC_METHODS));
}
@Test
@@ -120,20 +122,26 @@ class ReflectionHintsPredicatesTests {
@Test
void typeWithAnyMemberCategoryFailsWithNullCategories() {
runtimeHints.reflection().registerType(SampleClass.class, builder -> builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
assertThatIllegalArgumentException().isThrownBy(() -> reflection.onType(SampleClass.class).withAnyMemberCategory(new MemberCategory[0]));
runtimeHints.reflection().registerType(SampleClass.class, builder ->
builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS));
assertThatIllegalArgumentException().isThrownBy(() ->
reflection.onType(SampleClass.class).withAnyMemberCategory(new MemberCategory[0]));
}
@Test
void typeWithAnyMemberCategoryMatchesCategory() {
runtimeHints.reflection().registerType(SampleClass.class, builder -> builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INVOKE_PUBLIC_METHODS));
assertPredicateMatches(reflection.onType(SampleClass.class).withAnyMemberCategory(MemberCategory.INTROSPECT_PUBLIC_METHODS));
runtimeHints.reflection().registerType(SampleClass.class,
builder -> builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INVOKE_PUBLIC_METHODS));
assertPredicateMatches(reflection.onType(SampleClass.class)
.withAnyMemberCategory(MemberCategory.INTROSPECT_PUBLIC_METHODS));
}
@Test
void typeWithAnyMemberCategoryDoesNotMatchOtherCategory() {
runtimeHints.reflection().registerType(SampleClass.class, builder -> builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INVOKE_PUBLIC_METHODS));
assertPredicateDoesNotMatch(reflection.onType(SampleClass.class).withAnyMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS));
runtimeHints.reflection().registerType(SampleClass.class,
builder -> builder.withMembers(MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INVOKE_PUBLIC_METHODS));
assertPredicateDoesNotMatch(reflection.onType(SampleClass.class)
.withAnyMemberCategory(MemberCategory.INVOKE_DECLARED_METHODS));
}
}
@@ -148,140 +156,157 @@ class ReflectionHintsPredicatesTests {
@Test
void constructorIntrospectionMatchesConstructorHint() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withConstructor(Collections.emptyList(), constructorHint -> {
}));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withConstructor(Collections.emptyList(), constructorHint -> {}));
assertPredicateMatches(reflection.onConstructor(publicConstructor).introspect());
}
@Test
void constructorIntrospectionMatchesIntrospectPublicConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS));
assertPredicateMatches(reflection.onConstructor(publicConstructor).introspect());
}
@Test
void constructorIntrospectionMatchesInvokePublicConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS));
assertPredicateMatches(reflection.onConstructor(publicConstructor).introspect());
}
@Test
void constructorIntrospectionMatchesIntrospectDeclaredConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS));
assertPredicateMatches(reflection.onConstructor(publicConstructor).introspect());
}
@Test
void constructorIntrospectionMatchesInvokeDeclaredConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
assertPredicateMatches(reflection.onConstructor(publicConstructor).introspect());
}
@Test
void constructorInvocationDoesNotMatchConstructorHint() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withConstructor(Collections.emptyList(), constructorHint -> {
}));
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.
withConstructor(Collections.emptyList(), constructorHint -> {}));
assertPredicateDoesNotMatch(reflection.onConstructor(publicConstructor).invoke());
}
@Test
void constructorInvocationMatchesConstructorInvocationHint() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withConstructor(Collections.emptyList(), constructorHint -> constructorHint.withMode(ExecutableMode.INVOKE)));
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.
withConstructor(Collections.emptyList(), constructorHint ->
constructorHint.withMode(ExecutableMode.INVOKE)));
assertPredicateMatches(reflection.onConstructor(publicConstructor).invoke());
}
@Test
void constructorInvocationDoesNotMatchIntrospectPublicConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS));
assertPredicateDoesNotMatch(reflection.onConstructor(publicConstructor).invoke());
}
@Test
void constructorInvocationMatchesInvokePublicConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS));
assertPredicateMatches(reflection.onConstructor(publicConstructor).invoke());
}
@Test
void constructorInvocationDoesNotMatchIntrospectDeclaredConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS));
assertPredicateDoesNotMatch(reflection.onConstructor(publicConstructor).invoke());
}
@Test
void constructorInvocationMatchesInvokeDeclaredConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
assertPredicateMatches(reflection.onConstructor(publicConstructor).invoke());
}
@Test
void privateConstructorIntrospectionMatchesConstructorHint() {
List<TypeReference> parameterTypes = Collections.singletonList(TypeReference.of(String.class));
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withConstructor(parameterTypes, constructorHint -> {
}));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withConstructor(TypeReference.listOf(String.class), constructorHint -> {}));
assertPredicateMatches(reflection.onConstructor(privateConstructor).introspect());
}
@Test
void privateConstructorIntrospectionDoesNotMatchIntrospectPublicConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS));
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).introspect());
}
@Test
void privateConstructorIntrospectionDoesNotMatchInvokePublicConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS));
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).introspect());
}
@Test
void privateConstructorIntrospectionMatchesIntrospectDeclaredConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS));
assertPredicateMatches(reflection.onConstructor(privateConstructor).introspect());
}
@Test
void privateConstructorIntrospectionMatchesInvokeDeclaredConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
assertPredicateMatches(reflection.onConstructor(privateConstructor).introspect());
}
@Test
void privateConstructorInvocationDoesNotMatchConstructorHint() {
List<TypeReference> parameterTypes = Collections.singletonList(TypeReference.of(String.class));
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withConstructor(parameterTypes, constructorHint -> {
}));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withConstructor(TypeReference.listOf(String.class), constructorHint -> {}));
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).invoke());
}
@Test
void privateConstructorInvocationMatchesConstructorInvocationHint() {
List<TypeReference> parameterTypes = Collections.singletonList(TypeReference.of(String.class));
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withConstructor(parameterTypes, constructorHint -> constructorHint.withMode(ExecutableMode.INVOKE)));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withConstructor(TypeReference.listOf(String.class),
constructorHint -> constructorHint.withMode(ExecutableMode.INVOKE)));
assertPredicateMatches(reflection.onConstructor(privateConstructor).invoke());
}
@Test
void privateConstructorInvocationDoesNotMatchIntrospectPublicConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS));
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).invoke());
}
@Test
void privateConstructorInvocationDoesNotMatchInvokePublicConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS));
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).invoke());
}
@Test
void privateConstructorInvocationDoesNotMatchIntrospectDeclaredConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS));
assertPredicateDoesNotMatch(reflection.onConstructor(privateConstructor).invoke());
}
@Test
void privateConstructorInvocationMatchesInvokeDeclaredConstructors() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint -> typeHint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS));
assertPredicateMatches(reflection.onConstructor(privateConstructor).invoke());
}
@@ -460,7 +485,7 @@ class ReflectionHintsPredicatesTests {
@Test
void fieldWriteReflectionMatchesFieldHintWithWrite() {
runtimeHints.reflection().registerType(SampleClass.class, typeHint ->
typeHint.withField("publicField", fieldHint -> fieldHint.allowWrite(true)));
typeHint.withField("publicField", fieldHint -> fieldHint.allowWrite(true)));
assertPredicateMatches(reflection.onField(SampleClass.class, "publicField").allowWrite());
}

View File

@@ -111,9 +111,9 @@ public class FileNativeConfigurationWriterTests {
fieldBuilder.allowWrite(true);
fieldBuilder.allowUnsafeAccess(true);
})
.withConstructor(List.of(TypeReference.of(List.class), TypeReference.of(boolean.class), TypeReference.of(MimeType.class)), constructorHint ->
.withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), constructorHint ->
constructorHint.withMode(ExecutableMode.INTROSPECT))
.withMethod("setDefaultCharset", List.of(TypeReference.of(Charset.class)), ctorBuilder -> {})
.withMethod("setDefaultCharset", TypeReference.listOf(Charset.class), ctorBuilder -> {})
.withMethod("getDefaultCharset", Collections.emptyList(), constructorHint ->
constructorHint.withMode(ExecutableMode.INTROSPECT));
});

View File

@@ -63,7 +63,7 @@ public class ReflectionHintsWriterTests {
fieldBuilder.allowWrite(true);
fieldBuilder.allowUnsafeAccess(true);
})
.withConstructor(List.of(TypeReference.of(List.class), TypeReference.of(boolean.class), TypeReference.of(MimeType.class)), constructorHint ->
.withConstructor(TypeReference.listOf(List.class, boolean.class, MimeType.class), constructorHint ->
constructorHint.withMode(ExecutableMode.INTROSPECT))
.withMethod("setDefaultCharset", List.of(TypeReference.of(Charset.class)), ctorBuilder -> {})
.withMethod("getDefaultCharset", Collections.emptyList(), constructorHint ->
@@ -119,8 +119,8 @@ public class ReflectionHintsWriterTests {
@Test
void queriedMethods() throws JSONException {
ReflectionHints hints = new ReflectionHints();
hints.registerType(Integer.class, builder -> builder.withMethod("parseInt", List.of(TypeReference.of(String.class)),
b -> b.withMode(ExecutableMode.INTROSPECT)));
hints.registerType(Integer.class, builder -> builder.withMethod("parseInt",
TypeReference.listOf(String.class), b -> b.withMode(ExecutableMode.INTROSPECT)));
assertEquals("""
[
@@ -140,8 +140,8 @@ public class ReflectionHintsWriterTests {
@Test
void methods() throws JSONException {
ReflectionHints hints = new ReflectionHints();
hints.registerType(Integer.class, builder -> builder.withMethod("parseInt", List.of(TypeReference.of(String.class)),
b -> b.withMode(ExecutableMode.INVOKE)));
hints.registerType(Integer.class, builder -> builder.withMethod("parseInt",
TypeReference.listOf(String.class), b -> b.withMode(ExecutableMode.INVOKE)));
assertEquals("""
[
@@ -161,8 +161,8 @@ public class ReflectionHintsWriterTests {
@Test
void methodWithInnerClassParameter() throws JSONException {
ReflectionHints hints = new ReflectionHints();
hints.registerType(Integer.class, builder -> builder.withMethod("test", List.of(TypeReference.of(Inner.class)),
b -> b.withMode(ExecutableMode.INVOKE)));
hints.registerType(Integer.class, builder -> builder.withMethod("test",
TypeReference.listOf(Inner.class), b -> b.withMode(ExecutableMode.INVOKE)));
assertEquals("""
[
@@ -182,10 +182,10 @@ public class ReflectionHintsWriterTests {
@Test
void methodAndQueriedMethods() throws JSONException {
ReflectionHints hints = new ReflectionHints();
hints.registerType(Integer.class, builder -> builder.withMethod("parseInt", List.of(TypeReference.of(String.class)),
b -> b.withMode(ExecutableMode.INVOKE)));
hints.registerType(Integer.class, builder -> builder.withMethod("parseInt", List.of(TypeReference.of(String.class)),
b -> b.withMode(ExecutableMode.INTROSPECT)));
hints.registerType(Integer.class, builder -> builder.withMethod("parseInt",
TypeReference.listOf(String.class), b -> b.withMode(ExecutableMode.INVOKE)));
hints.registerType(Integer.class, builder -> builder.withMethod("parseInt",
TypeReference.listOf(String.class), b -> b.withMode(ExecutableMode.INTROSPECT)));
assertEquals("""
[