Merge branch '6.0.x'
This commit is contained in:
@@ -74,21 +74,17 @@ public class KotlinReflectionParameterNameDiscoverer implements ParameterNameDis
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private String[] getParameterNames(List<KParameter> parameters) {
|
private String[] getParameterNames(List<KParameter> parameters) {
|
||||||
List<KParameter> filteredParameters = parameters
|
String[] parameterNames = parameters.stream()
|
||||||
.stream()
|
|
||||||
// Extension receivers of extension methods must be included as they appear as normal method parameters in Java
|
// Extension receivers of extension methods must be included as they appear as normal method parameters in Java
|
||||||
.filter(p -> KParameter.Kind.VALUE.equals(p.getKind()) || KParameter.Kind.EXTENSION_RECEIVER.equals(p.getKind()))
|
.filter(p -> KParameter.Kind.VALUE.equals(p.getKind()) || KParameter.Kind.EXTENSION_RECEIVER.equals(p.getKind()))
|
||||||
.toList();
|
// extension receivers are not explicitly named, but require a name for Java interoperability
|
||||||
String[] parameterNames = new String[filteredParameters.size()];
|
// $receiver is not a valid Kotlin identifier, but valid in Java, so it can be used here
|
||||||
for (int i = 0; i < filteredParameters.size(); i++) {
|
.map(p -> KParameter.Kind.EXTENSION_RECEIVER.equals(p.getKind()) ? "$receiver" : p.getName())
|
||||||
KParameter parameter = filteredParameters.get(i);
|
.toArray(String[]::new);
|
||||||
// extension receivers are not explicitly named, but require a name for Java interoperability
|
for (String parameterName : parameterNames) {
|
||||||
// $receiver is not a valid Kotlin identifier, but valid in Java, so it can be used here
|
if (parameterName == null) {
|
||||||
String name = KParameter.Kind.EXTENSION_RECEIVER.equals(parameter.getKind()) ? "$receiver" : parameter.getName();
|
|
||||||
if (name == null) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
parameterNames[i] = name;
|
|
||||||
}
|
}
|
||||||
return parameterNames;
|
return parameterNames;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class KotlinCoroutinesUtilsTests {
|
|||||||
fun deferredToMono() {
|
fun deferredToMono() {
|
||||||
runBlocking {
|
runBlocking {
|
||||||
val deferred: Deferred<String> = async(Dispatchers.IO) {
|
val deferred: Deferred<String> = async(Dispatchers.IO) {
|
||||||
delay(10)
|
delay(1)
|
||||||
"foo"
|
"foo"
|
||||||
}
|
}
|
||||||
val mono = CoroutinesUtils.deferredToMono(deferred)
|
val mono = CoroutinesUtils.deferredToMono(deferred)
|
||||||
@@ -122,12 +122,12 @@ class KotlinCoroutinesUtilsTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun suspendingFunction(value: String): String {
|
suspend fun suspendingFunction(value: String): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun suspendingFunctionWithFlow(): Flow<String> {
|
suspend fun suspendingFunctionWithFlow(): Flow<String> {
|
||||||
delay(10)
|
delay(1)
|
||||||
return flowOf("foo", "bar")
|
return flowOf("foo", "bar")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ class KotlinCoroutinesUtilsTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun suspendingFunctionWithContext(value: String): String {
|
suspend fun suspendingFunctionWithContext(value: String): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
Assertions.assertThat(coroutineContext[CoroutineName]?.name).isEqualTo("name")
|
Assertions.assertThat(coroutineContext[CoroutineName]?.name).isEqualTo("name")
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -154,13 +154,13 @@ class RSocketClientToServerCoroutinesIntegrationTests {
|
|||||||
|
|
||||||
@MessageMapping("receive-async")
|
@MessageMapping("receive-async")
|
||||||
suspend fun receiveAsync(payload: String) {
|
suspend fun receiveAsync(payload: String) {
|
||||||
delay(10)
|
delay(1)
|
||||||
fireForgetPayloads.tryEmitNext(payload)
|
fireForgetPayloads.tryEmitNext(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
@MessageMapping("echo-async")
|
@MessageMapping("echo-async")
|
||||||
suspend fun echoAsync(payload: String): String {
|
suspend fun echoAsync(payload: String): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
return "$payload async"
|
return "$payload async"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +169,7 @@ class RSocketClientToServerCoroutinesIntegrationTests {
|
|||||||
var i = 0
|
var i = 0
|
||||||
return flow {
|
return flow {
|
||||||
while(true) {
|
while(true) {
|
||||||
delay(10)
|
delay(1)
|
||||||
emit("$payload ${i++}")
|
emit("$payload ${i++}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,11 +177,11 @@ class RSocketClientToServerCoroutinesIntegrationTests {
|
|||||||
|
|
||||||
@MessageMapping("echo-stream-async")
|
@MessageMapping("echo-stream-async")
|
||||||
suspend fun echoStreamAsync(payload: String): Flow<String> {
|
suspend fun echoStreamAsync(payload: String): Flow<String> {
|
||||||
delay(10)
|
delay(1)
|
||||||
var i = 0
|
var i = 0
|
||||||
return flow {
|
return flow {
|
||||||
while(true) {
|
while(true) {
|
||||||
delay(10)
|
delay(1)
|
||||||
emit("$payload ${i++}")
|
emit("$payload ${i++}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,31 +189,31 @@ class RSocketClientToServerCoroutinesIntegrationTests {
|
|||||||
|
|
||||||
@MessageMapping("echo-channel")
|
@MessageMapping("echo-channel")
|
||||||
fun echoChannel(payloads: Flow<String>) = payloads.map {
|
fun echoChannel(payloads: Flow<String>) = payloads.map {
|
||||||
delay(10)
|
delay(1)
|
||||||
"$it async"
|
"$it async"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
@Suppress("UNUSED_PARAMETER")
|
||||||
@MessageMapping("thrown-exception")
|
@MessageMapping("thrown-exception")
|
||||||
suspend fun handleAndThrow(payload: String): String {
|
suspend fun handleAndThrow(payload: String): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
throw IllegalArgumentException("Invalid input error")
|
throw IllegalArgumentException("Invalid input error")
|
||||||
}
|
}
|
||||||
|
|
||||||
@MessageMapping("unit-return-value")
|
@MessageMapping("unit-return-value")
|
||||||
suspend fun unitReturnValue(payload: String) =
|
suspend fun unitReturnValue(payload: String) =
|
||||||
if (payload != "bad") delay(10) else throw IllegalStateException("bad")
|
if (payload != "bad") delay(1) else throw IllegalStateException("bad")
|
||||||
|
|
||||||
@MessageExceptionHandler
|
@MessageExceptionHandler
|
||||||
suspend fun handleException(ex: IllegalArgumentException): String {
|
suspend fun handleException(ex: IllegalArgumentException): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
return "${ex.message} handled"
|
return "${ex.message} handled"
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
@Suppress("UNUSED_PARAMETER")
|
||||||
@MessageExceptionHandler
|
@MessageExceptionHandler
|
||||||
suspend fun handleExceptionWithVoidReturnValue(ex: IllegalStateException) {
|
suspend fun handleExceptionWithVoidReturnValue(ex: IllegalStateException) {
|
||||||
delay(10)
|
delay(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -160,48 +160,48 @@ class CoroutinesAnnotationTransactionInterceptorTests {
|
|||||||
open class TestWithCoroutines {
|
open class TestWithCoroutines {
|
||||||
|
|
||||||
open suspend fun suspendingNoValueSuccess() {
|
open suspend fun suspendingNoValueSuccess() {
|
||||||
delay(10)
|
delay(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
open suspend fun suspendingNoValueFailure() {
|
open suspend fun suspendingNoValueFailure() {
|
||||||
delay(10)
|
delay(1)
|
||||||
throw IllegalStateException()
|
throw IllegalStateException()
|
||||||
}
|
}
|
||||||
|
|
||||||
open suspend fun suspendingValueSuccess(): String {
|
open suspend fun suspendingValueSuccess(): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
return "foo"
|
return "foo"
|
||||||
}
|
}
|
||||||
|
|
||||||
open suspend fun suspendingValueFailure(): String {
|
open suspend fun suspendingValueFailure(): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
throw IllegalStateException()
|
throw IllegalStateException()
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun flowSuccess(): Flow<String> {
|
open fun flowSuccess(): Flow<String> {
|
||||||
return flow {
|
return flow {
|
||||||
emit("foo")
|
emit("foo")
|
||||||
delay(10)
|
delay(1)
|
||||||
emit("foo")
|
emit("foo")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open suspend fun suspendingFlowSuccess(): Flow<String> {
|
open suspend fun suspendingFlowSuccess(): Flow<String> {
|
||||||
delay(10)
|
delay(1)
|
||||||
return flow {
|
return flow {
|
||||||
emit("foo")
|
emit("foo")
|
||||||
delay(10)
|
delay(1)
|
||||||
emit("foo")
|
emit("foo")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open suspend fun suspendingValueSuccessWithContext(): String {
|
open suspend fun suspendingValueSuccessWithContext(): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
return coroutineContext[ExampleContext.Key].toString()
|
return coroutineContext[ExampleContext.Key].toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
open suspend fun suspendingValueFailureWithContext(): String {
|
open suspend fun suspendingValueFailureWithContext(): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
throw IllegalStateException(coroutineContext[ExampleContext.Key].toString())
|
throw IllegalStateException(coroutineContext[ExampleContext.Key].toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -337,17 +337,17 @@ abstract class AbstractCoroutinesTransactionAspectTests {
|
|||||||
private var name: String? = null
|
private var name: String? = null
|
||||||
|
|
||||||
override suspend fun getName(): String? {
|
override suspend fun getName(): String? {
|
||||||
delay(10)
|
delay(1)
|
||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setName(name: String?) {
|
override suspend fun setName(name: String?) {
|
||||||
delay(10)
|
delay(1)
|
||||||
this.name = name
|
this.name = name
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun exceptional(t: Throwable?) {
|
override suspend fun exceptional(t: Throwable?) {
|
||||||
delay(10)
|
delay(1)
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
throw t
|
throw t
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import kotlin.reflect.KFunction;
|
|||||||
import kotlin.reflect.KParameter;
|
import kotlin.reflect.KParameter;
|
||||||
import kotlin.reflect.jvm.KCallablesJvm;
|
import kotlin.reflect.jvm.KCallablesJvm;
|
||||||
import kotlin.reflect.jvm.ReflectJvmMapping;
|
import kotlin.reflect.jvm.ReflectJvmMapping;
|
||||||
import org.reactivestreams.Publisher;
|
|
||||||
|
|
||||||
import org.springframework.context.MessageSource;
|
import org.springframework.context.MessageSource;
|
||||||
import org.springframework.core.CoroutinesUtils;
|
import org.springframework.core.CoroutinesUtils;
|
||||||
@@ -287,7 +286,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
|||||||
* instead.
|
* instead.
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
*/
|
*/
|
||||||
protected Publisher<?> invokeSuspendingFunction(Method method, Object target, Object[] args) {
|
protected Object invokeSuspendingFunction(Method method, Object target, Object[] args) {
|
||||||
return CoroutinesUtils.invokeSuspendingFunction(method, target, args);
|
return CoroutinesUtils.invokeSuspendingFunction(method, target, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -197,12 +197,12 @@ class KotlinInvocableHandlerMethodTests {
|
|||||||
class CoroutinesController {
|
class CoroutinesController {
|
||||||
|
|
||||||
suspend fun singleArg(q: String?): String {
|
suspend fun singleArg(q: String?): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
return "success:$q"
|
return "success:$q"
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun noArgs(): String {
|
suspend fun noArgs(): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
return "success"
|
return "success"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,12 +212,12 @@ class KotlinInvocableHandlerMethodTests {
|
|||||||
|
|
||||||
@ResponseStatus(HttpStatus.CREATED)
|
@ResponseStatus(HttpStatus.CREATED)
|
||||||
suspend fun created(): String {
|
suspend fun created(): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
return "created"
|
return "created"
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun response(response: ServerHttpResponse) {
|
suspend fun response(response: ServerHttpResponse) {
|
||||||
delay(10)
|
delay(1)
|
||||||
response.headers.add("foo", "bar")
|
response.headers.add("foo", "bar")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ class KotlinInvocableHandlerMethodTests {
|
|||||||
private class PrivateCoroutinesController {
|
private class PrivateCoroutinesController {
|
||||||
|
|
||||||
suspend fun singleArg(q: String?): String {
|
suspend fun singleArg(q: String?): String {
|
||||||
delay(10)
|
delay(1)
|
||||||
return "success:$q"
|
return "success:$q"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -172,7 +172,7 @@ class CoroutinesIntegrationTests : AbstractRequestMappingIntegrationTests() {
|
|||||||
|
|
||||||
@GetMapping("/suspending-flow")
|
@GetMapping("/suspending-flow")
|
||||||
suspend fun suspendingFlowEndpoint(): Flow<String> {
|
suspend fun suspendingFlowEndpoint(): Flow<String> {
|
||||||
delay(10)
|
delay(1)
|
||||||
return flow {
|
return flow {
|
||||||
emit("foo")
|
emit("foo")
|
||||||
delay(1)
|
delay(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user