diff --git a/spring-core/src/main/java/org/springframework/core/MethodParameter.java b/spring-core/src/main/java/org/springframework/core/MethodParameter.java index b730f042d5be..2ea648b2d5e4 100644 --- a/spring-core/src/main/java/org/springframework/core/MethodParameter.java +++ b/spring-core/src/main/java/org/springframework/core/MethodParameter.java @@ -972,14 +972,16 @@ public static boolean isOptional(MethodParameter param) { * functions via Kotlin reflection. */ private static Type getGenericReturnType(Method method) { - try { - KFunction function = ReflectJvmMapping.getKotlinFunction(method); - if (function != null && function.isSuspend()) { - return ReflectJvmMapping.getJavaType(function.getReturnType()); + if (KotlinDetector.isSuspendingFunction(method)) { + try { + KFunction function = ReflectJvmMapping.getKotlinFunction(method); + if (function != null && function.isSuspend()) { + return ReflectJvmMapping.getJavaType(function.getReturnType()); + } + } + catch (UnsupportedOperationException ex) { + // probably a synthetic class - let's use java reflection instead } - } - catch (UnsupportedOperationException ex) { - // probably a synthetic class - let's use java reflection instead } return method.getGenericReturnType(); } @@ -989,18 +991,20 @@ private static Type getGenericReturnType(Method method) { * functions via Kotlin reflection. */ private static Class getReturnType(Method method) { - try { - KFunction function = ReflectJvmMapping.getKotlinFunction(method); - if (function != null && function.isSuspend()) { - Type paramType = ReflectJvmMapping.getJavaType(function.getReturnType()); - if (paramType == Unit.class) { - paramType = void.class; + if (KotlinDetector.isSuspendingFunction(method)) { + try { + KFunction function = ReflectJvmMapping.getKotlinFunction(method); + if (function != null && function.isSuspend()) { + Type paramType = ReflectJvmMapping.getJavaType(function.getReturnType()); + if (paramType == Unit.class) { + paramType = void.class; + } + return ResolvableType.forType(paramType).resolve(method.getReturnType()); } - return ResolvableType.forType(paramType).resolve(method.getReturnType()); } - } - catch (UnsupportedOperationException ex) { - // probably a synthetic class - let's use java reflection instead + catch (UnsupportedOperationException ex) { + // probably a synthetic class - let's use java reflection instead + } } return method.getReturnType(); } diff --git a/spring-core/src/test/kotlin/org/springframework/core/MethodParameterKotlinTests.kt b/spring-core/src/test/kotlin/org/springframework/core/MethodParameterKotlinTests.kt index d63dae5ae5d5..c4e9216ab410 100644 --- a/spring-core/src/test/kotlin/org/springframework/core/MethodParameterKotlinTests.kt +++ b/spring-core/src/test/kotlin/org/springframework/core/MethodParameterKotlinTests.kt @@ -31,6 +31,7 @@ import kotlin.reflect.jvm.javaMethod * @author Sebastien Deleuze * @author Juergen Hoeller * @author Konrad Kaminski + * @author Greg Taube */ class MethodParameterKotlinTests { @@ -114,6 +115,18 @@ class MethodParameterKotlinTests { assertThat(returnGenericParameterType("suspendFun8")).isEqualTo(Any::class.java) } + @Test + fun `Regular function return type`() { + assertThat(returnParameterType("regularFun")).isEqualTo(Producer::class.java) + assertThat(returnGenericParameterTypeName("regularFun")).isEqualTo("org.springframework.core.Producer") + } + + @Test + fun `Regular function with Continuation parameter return type`() { + assertThat(returnParameterType("regularFunWithContinuation")).isEqualTo(Producer::class.java) + assertThat(returnGenericParameterTypeName("regularFunWithContinuation")).isEqualTo("org.springframework.core.Producer") + } + @Test fun `Parameter name for regular function`() { val methodParameter = returnMethodParameter("nullable", 0) @@ -186,6 +199,12 @@ class MethodParameterKotlinTests { @Suppress("unused", "unused_parameter") suspend fun suspendFun8(p1: String): Any? = TODO() + + @Suppress("unused", "unused_parameter") + fun regularFun(p1: String): Producer = TODO() + + @Suppress("unused", "unused_parameter") + fun regularFunWithContinuation(p1: String, continuation: Continuation): Producer = TODO() } interface Producer