Support Kotlin extensions in web handlers
This commit restores support for Kotlin extensions in web handlers, and adds support for invoking reflectively suspending extension functions, as well as the other features supported as of Spring Framework 6.1 like value classes and default value for parameters. Closes gh-31876
This commit is contained in:
@@ -117,8 +117,11 @@ public abstract class CoroutinesUtils {
|
||||
int index = 0;
|
||||
for (KParameter parameter : function.getParameters()) {
|
||||
switch (parameter.getKind()) {
|
||||
case INSTANCE -> argMap.put(parameter, target);
|
||||
case VALUE -> {
|
||||
case INSTANCE:
|
||||
argMap.put(parameter, target);
|
||||
break;
|
||||
case VALUE:
|
||||
case EXTENSION_RECEIVER:
|
||||
if (!parameter.isOptional() || args[index] != null) {
|
||||
if (parameter.getType().getClassifier() instanceof KClass<?> kClass && kClass.isValue()) {
|
||||
Class<?> javaClass = JvmClassMappingKt.getJavaClass(kClass);
|
||||
@@ -131,7 +134,8 @@ public abstract class CoroutinesUtils {
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return KCallables.callSuspendBy(function, argMap, continuation);
|
||||
|
||||
@@ -154,6 +154,26 @@ class CoroutinesUtilsTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun invokeSuspendingFunctionWithExtension() {
|
||||
val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithExtension",
|
||||
CustomException::class.java, Continuation::class.java)
|
||||
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, CustomException("foo")) as Mono
|
||||
runBlocking {
|
||||
Assertions.assertThat(mono.awaitSingleOrNull()).isEqualTo("foo")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun invokeSuspendingFunctionWithExtensionAndParameter() {
|
||||
val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithExtensionAndParameter",
|
||||
CustomException::class.java, Int::class.java, Continuation::class.java)
|
||||
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, CustomException("foo"), 20) as Mono
|
||||
runBlocking {
|
||||
Assertions.assertThat(mono.awaitSingleOrNull()).isEqualTo("foo-20")
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun suspendingFunction(value: String): String {
|
||||
delay(1)
|
||||
return value
|
||||
@@ -186,7 +206,19 @@ class CoroutinesUtilsTests {
|
||||
return value.value
|
||||
}
|
||||
|
||||
suspend fun CustomException.suspendingFunctionWithExtension(): String {
|
||||
delay(1)
|
||||
return "${this.message}"
|
||||
}
|
||||
|
||||
suspend fun CustomException.suspendingFunctionWithExtensionAndParameter(limit: Int): String {
|
||||
delay(1)
|
||||
return "${this.message}-$limit"
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class ValueClass(val value: String)
|
||||
|
||||
class CustomException(message: String) : Throwable(message)
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user