Jakob Hofer 1 day ago committed by GitHub
parent
commit
9e076eccf3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      spring-core/spring-core.gradle
  2. 2
      spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java
  3. 32
      spring-core/src/test/kotlin/org/springframework/core/CoroutinesUtilsTests.kt
  4. 6
      spring-web/spring-web.gradle
  5. 2
      spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java
  6. 29
      spring-web/src/test/kotlin/org/springframework/web/method/support/InvocableHandlerMethodKotlinTests.kt

6
spring-core/spring-core.gradle

@ -127,6 +127,12 @@ jar { @@ -127,6 +127,12 @@ jar {
}
}
kotlin {
compilerOptions {
freeCompilerArgs.addAll("-Xcontext-parameters")
}
}
test {
// Make sure the classes dir is used on the test classpath (required by ResourceTests).
// When test fixtures are involved, the JAR is used by default.

2
spring-core/src/main/java/org/springframework/core/CoroutinesUtils.java

@ -130,7 +130,7 @@ public abstract class CoroutinesUtils { @@ -130,7 +130,7 @@ public abstract class CoroutinesUtils {
for (KParameter parameter : function.getParameters()) {
switch (parameter.getKind()) {
case INSTANCE -> argMap.put(parameter, target);
case VALUE, EXTENSION_RECEIVER -> {
case VALUE, EXTENSION_RECEIVER, CONTEXT -> {
Object arg = args[index];
if (!(parameter.isOptional() && arg == null)) {
KType type = parameter.getType();

32
spring-core/src/test/kotlin/org/springframework/core/CoroutinesUtilsTests.kt

@ -283,6 +283,26 @@ class CoroutinesUtilsTests { @@ -283,6 +283,26 @@ class CoroutinesUtilsTests {
}
}
@Test
fun invokeSuspendingFunctionWithContextParameter() {
val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithContextParameter",
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 invokeSuspendingFunctionWithContextParameterAndParameter() {
val method = CoroutinesUtilsTests::class.java.getDeclaredMethod("suspendingFunctionWithContextParameterAndParameter",
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")
}
}
@Test
fun invokeSuspendingFunctionWithGenericParameter() {
val method = GenericController::class.java.declaredMethods.first { it.name.startsWith("handle") }
@ -400,6 +420,18 @@ class CoroutinesUtilsTests { @@ -400,6 +420,18 @@ class CoroutinesUtilsTests {
return "${this.message}-$limit"
}
context(value: CustomException)
suspend fun suspendingFunctionWithContextParameter(): String {
delay(1)
return "${value.message}"
}
context(value: CustomException)
suspend fun suspendingFunctionWithContextParameterAndParameter(limit: Int): String {
delay(1)
return "${value.message}-$limit"
}
interface Named {
val name: String
}

6
spring-web/spring-web.gradle

@ -102,3 +102,9 @@ dependencies { @@ -102,3 +102,9 @@ dependencies {
testRuntimeOnly("org.glassfish:jakarta.el")
testRuntimeOnly("org.hibernate.validator:hibernate-validator")
}
kotlin {
compilerOptions {
freeCompilerArgs.addAll("-Xcontext-parameters")
}
}

2
spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java

@ -318,7 +318,7 @@ public class InvocableHandlerMethod extends HandlerMethod { @@ -318,7 +318,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
for (KParameter parameter : function.getParameters()) {
switch (parameter.getKind()) {
case INSTANCE -> argMap.put(parameter, target);
case VALUE, EXTENSION_RECEIVER -> {
case VALUE, EXTENSION_RECEIVER, CONTEXT -> {
Object arg = args[index];
if (!(parameter.isOptional() && arg == null)) {
KType type = parameter.getType();

29
spring-web/src/test/kotlin/org/springframework/web/method/support/InvocableHandlerMethodKotlinTests.kt

@ -238,6 +238,22 @@ class InvocableHandlerMethodKotlinTests { @@ -238,6 +238,22 @@ class InvocableHandlerMethodKotlinTests {
Assertions.assertThat(value).isEqualTo("foo-20")
}
@Test
fun contextParameter() {
composite.addResolver(StubArgumentResolver(CustomException::class.java, CustomException("foo")))
val value = getInvocable(ReflectionUtils.findMethod(ContextParameterHandler::class.java, "handle", CustomException::class.java)!!).invokeForRequest(request, null)
Assertions.assertThat(value).isEqualTo("foo")
}
@Test
fun contextParameterWithParameter() {
composite.addResolver(StubArgumentResolver(CustomException::class.java, CustomException("foo")))
composite.addResolver(StubArgumentResolver(Int::class.java, 20))
val value = getInvocable(ReflectionUtils.findMethod(ContextParameterHandler::class.java, "handleWithParameter", CustomException::class.java, Int::class.java)!!)
.invokeForRequest(request, null)
Assertions.assertThat(value).isEqualTo("foo-20")
}
@Test
fun genericParameter() {
val horse = Animal("horse")
@ -359,6 +375,19 @@ class InvocableHandlerMethodKotlinTests { @@ -359,6 +375,19 @@ class InvocableHandlerMethodKotlinTests {
}
}
private class ContextParameterHandler {
context(exception: CustomException)
fun handle(): String {
return "${exception.message}"
}
context(exception: CustomException)
fun handleWithParameter(limit: Int): String {
return "${exception.message}-$limit"
}
}
private abstract class GenericHandler<T : Named> {
fun handle(named: T) = named.name

Loading…
Cancel
Save