From b27735d4a6ab6f0f17174e2cd1ffae1a41dbc219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Sun, 11 Dec 2022 11:34:30 +0100 Subject: [PATCH] Refine BindingReflectionHintsRegistrar Kotlin support Closes gh-29593 --- .../aot/hint/BindingReflectionHintsRegistrar.java | 4 +++- .../KotlinBindingReflectionHintsRegistrarTests.kt | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java b/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java index 4860d1f059c8..4e3d0f4136ab 100644 --- a/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java +++ b/spring-core/src/main/java/org/springframework/aot/hint/BindingReflectionHintsRegistrar.java @@ -111,6 +111,8 @@ else if ((methodName.startsWith("get") && method.getParameterCount() == 0 && met if (KotlinDetector.isKotlinType(clazz)) { KotlinDelegate.registerComponentHints(hints, clazz); registerKotlinSerializationHints(hints, clazz); + // For Kotlin reflection + typeHint.withMembers(MemberCategory.INTROSPECT_DECLARED_METHODS); } }); } @@ -192,7 +194,7 @@ public static void registerComponentHints(ReflectionHints hints, Class type) if (kClass.isData()) { for (Method method : type.getMethods()) { String methodName = method.getName(); - if (methodName.startsWith("component") || methodName.equals("copy")) { + if (methodName.startsWith("component") || methodName.equals("copy") || methodName.equals("copy$default")) { hints.registerMethod(method, ExecutableMode.INVOKE); } } diff --git a/spring-core/src/test/kotlin/org/springframework/aot/hint/KotlinBindingReflectionHintsRegistrarTests.kt b/spring-core/src/test/kotlin/org/springframework/aot/hint/KotlinBindingReflectionHintsRegistrarTests.kt index cc00a89d354c..f4d0ff82561b 100644 --- a/spring-core/src/test/kotlin/org/springframework/aot/hint/KotlinBindingReflectionHintsRegistrarTests.kt +++ b/spring-core/src/test/kotlin/org/springframework/aot/hint/KotlinBindingReflectionHintsRegistrarTests.kt @@ -20,6 +20,7 @@ import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.ThrowingConsumer import org.junit.jupiter.api.Test import org.springframework.aot.hint.predicate.RuntimeHintsPredicates +import java.lang.reflect.Method /** * Tests for Kotlin support in [BindingReflectionHintsRegistrar]. @@ -67,6 +68,16 @@ class KotlinBindingReflectionHintsRegistrarTests { assertThat(RuntimeHintsPredicates.reflection().onMethod(SampleDataClass::class.java, "component1")).accepts(hints) assertThat(RuntimeHintsPredicates.reflection().onMethod(SampleDataClass::class.java, "copy")).accepts(hints) assertThat(RuntimeHintsPredicates.reflection().onMethod(SampleDataClass::class.java, "getName")).accepts(hints) + val copyDefault: Method = SampleDataClass::class.java.getMethod("copy\$default", SampleDataClass::class.java, + String::class.java , Int::class.java, Object::class.java) + assertThat(RuntimeHintsPredicates.reflection().onMethod(copyDefault)).accepts(hints) + } + + @Test + fun `Register reflection hints on declared methods for Kotlin class`() { + bindingRegistrar.registerReflectionHints(hints.reflection(), SampleClass::class.java) + assertThat(RuntimeHintsPredicates.reflection().onType(SampleClass::class.java) + .withMemberCategory(MemberCategory.INTROSPECT_DECLARED_METHODS)).accepts(hints) } } @@ -74,3 +85,5 @@ class KotlinBindingReflectionHintsRegistrarTests { class SampleSerializableClass(val name: String) data class SampleDataClass(val name: String) + +class SampleClass(val name: String)