Browse Source

Support Kotlin synthetic classes in MethodParameter and SpEL

Closes gh-23812
pull/23992/head
Sébastien Deleuze 5 years ago
parent
commit
7646895fd4
  1. 24
      spring-core/src/main/java/org/springframework/core/MethodParameter.java
  2. 4
      spring-expression/spring-expression.gradle
  3. 28
      spring-expression/src/test/kotlin/org/springframework/expression/spel/KotlinSpelReproTests.kt

24
spring-core/src/main/java/org/springframework/core/MethodParameter.java

@ -908,9 +908,14 @@ public class MethodParameter { @@ -908,9 +908,14 @@ public class MethodParameter {
* functions via Kotlin reflection.
*/
static private Type getGenericReturnType(Method method) {
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
if (function != null && function.isSuspend()) {
return ReflectJvmMapping.getJavaType(function.getReturnType());
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
}
return method.getGenericReturnType();
}
@ -920,10 +925,15 @@ public class MethodParameter { @@ -920,10 +925,15 @@ public class MethodParameter {
* functions via Kotlin reflection.
*/
static private Class<?> getReturnType(Method method) {
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
if (function != null && function.isSuspend()) {
Type paramType = ReflectJvmMapping.getJavaType(function.getReturnType());
return ResolvableType.forType(paramType).resolve(method.getReturnType());
try {
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
if (function != null && function.isSuspend()) {
Type paramType = ReflectJvmMapping.getJavaType(function.getReturnType());
return ResolvableType.forType(paramType).resolve(method.getReturnType());
}
}
catch (UnsupportedOperationException ex) {
// probably a synthetic class - let's use java reflection instead
}
return method.getReturnType();
}

4
spring-expression/spring-expression.gradle

@ -1,5 +1,9 @@ @@ -1,5 +1,9 @@
description = "Spring Expression Language (SpEL)"
apply plugin: "kotlin"
dependencies {
compile(project(":spring-core"))
testCompile("org.jetbrains.kotlin:kotlin-reflect")
testCompile("org.jetbrains.kotlin:kotlin-stdlib")
}

28
spring-expression/src/test/kotlin/org/springframework/expression/spel/KotlinSpelReproTests.kt

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
package org.springframework.expression.spel
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.springframework.expression.ExpressionParser
import org.springframework.expression.spel.standard.SpelExpressionParser
class KotlinSpelReproTests {
private val parser: ExpressionParser = SpelExpressionParser()
private val context = TestScenarioCreator.getTestEvaluationContext()
@Test
fun `gh-23812 SpEL cannot invoke Kotlin synthetic classes`() {
val expr = parser.parseExpression("new org.springframework.expression.spel.KotlinSpelReproTests\$Config().kotlinSupplier().invoke()")
assertThat(expr.getValue(context)).isEqualTo("test")
}
class Config {
fun kotlinSupplier(): () -> String {
return { "test" }
}
}
}
Loading…
Cancel
Save