Merge branch '6.2.x'
Build and Deploy Snapshot / Build and Deploy Snapshot (push) Waiting to run Details
Build and Deploy Snapshot / Verify (push) Blocked by required conditions Details
Deploy Docs / Dispatch docs deployment (push) Waiting to run Details

This commit is contained in:
Sébastien Deleuze 2025-04-01 09:53:42 +02:00
commit 5c93bb38c4
2 changed files with 33 additions and 5 deletions

View File

@ -19,6 +19,7 @@ package org.springframework.core;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import kotlin.Unit;
import kotlin.coroutines.CoroutineContext;
@ -131,11 +132,7 @@ public abstract class CoroutinesUtils {
if (!(type.isMarkedNullable() && arg == null) &&
type.getClassifier() instanceof KClass<?> kClass &&
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(kClass))) {
KFunction<?> constructor = KClasses.getPrimaryConstructor(kClass);
if (!KCallablesJvm.isAccessible(constructor)) {
KCallablesJvm.setAccessible(constructor, true);
}
arg = constructor.call(arg);
arg = box(kClass, arg);
}
argMap.put(parameter, arg);
}
@ -161,6 +158,20 @@ public abstract class CoroutinesUtils {
return mono;
}
private static Object box(KClass<?> kClass, @Nullable Object arg) {
KFunction<?> constructor = Objects.requireNonNull(KClasses.getPrimaryConstructor(kClass));
KType type = constructor.getParameters().get(0).getType();
if (!(type.isMarkedNullable() && arg == null) &&
type.getClassifier() instanceof KClass<?> parameterClass &&
KotlinDetector.isInlineClass(JvmClassMappingKt.getJavaClass(parameterClass))) {
arg = box(parameterClass, arg);
}
if (!KCallablesJvm.isAccessible(constructor)) {
KCallablesJvm.setAccessible(constructor, true);
}
return constructor.call(arg);
}
private static Flux<?> asFlux(Object flow) {
return ReactorFlowKt.asFlux(((Flow<?>) flow));
}

View File

@ -199,6 +199,15 @@ class CoroutinesUtilsTests {
}
}
@Test
fun invokeSuspendingFunctionWithNestedValueClassParameter() {
val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithNestedValueClassParameter") }
val mono = CoroutinesUtils.invokeSuspendingFunction(method, this, "foo", null) as Mono
runBlocking {
Assertions.assertThat(mono.awaitSingle()).isEqualTo("foo")
}
}
@Test
fun invokeSuspendingFunctionWithValueClassReturnValue() {
val method = CoroutinesUtilsTests::class.java.declaredMethods.first { it.name.startsWith("suspendingFunctionWithValueClassReturnValue") }
@ -328,6 +337,11 @@ class CoroutinesUtilsTests {
return value.value
}
suspend fun suspendingFunctionWithNestedValueClassParameter(value: NestedValueClass): String {
delay(1)
return value.value.value
}
suspend fun suspendingFunctionWithValueClassReturnValue(): ValueClass {
delay(1)
return ValueClass("foo")
@ -382,6 +396,9 @@ class CoroutinesUtilsTests {
@JvmInline
value class ValueClass(val value: String)
@JvmInline
value class NestedValueClass(val value: ValueClass)
@JvmInline
value class ValueClassWithInit(val value: String) {
init {