diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java index 827ee3fd893e..58b9002519f0 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.java @@ -120,7 +120,7 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter public LocalValidatorFactoryBean() { if (KotlinDetector.isKotlinReflectPresent()) { - this.parameterNameDiscoverer = new KotlinReflectionParameterNameDiscoverer(); + this.parameterNameDiscoverer = new KotlinReflectionParameterNameDiscoverer(true); } } diff --git a/spring-core/src/main/java/org/springframework/core/KotlinReflectionParameterNameDiscoverer.java b/spring-core/src/main/java/org/springframework/core/KotlinReflectionParameterNameDiscoverer.java index 610cf5d1cb82..71940a76a122 100644 --- a/spring-core/src/main/java/org/springframework/core/KotlinReflectionParameterNameDiscoverer.java +++ b/spring-core/src/main/java/org/springframework/core/KotlinReflectionParameterNameDiscoverer.java @@ -39,6 +39,15 @@ * @see DefaultParameterNameDiscoverer */ public class KotlinReflectionParameterNameDiscoverer implements ParameterNameDiscoverer { + private boolean includeContinuationParameter; + + public KotlinReflectionParameterNameDiscoverer() { + this(false); + } + + public KotlinReflectionParameterNameDiscoverer(boolean includeContinuationParameter) { + this.includeContinuationParameter = includeContinuationParameter; + } @Override @Nullable @@ -49,7 +58,7 @@ public String[] getParameterNames(Method method) { try { KFunction function = ReflectJvmMapping.getKotlinFunction(method); - return (function != null ? getParameterNames(function.getParameters()) : null); + return (function != null ? getParameterNames(function.getParameters(), includeContinuationParameter && function.isSuspend()) : null); } catch (UnsupportedOperationException ex) { return null; @@ -65,7 +74,7 @@ public String[] getParameterNames(Constructor ctor) { try { KFunction function = ReflectJvmMapping.getKotlinFunction(ctor); - return (function != null ? getParameterNames(function.getParameters()) : null); + return (function != null ? getParameterNames(function.getParameters(), false) : null); } catch (UnsupportedOperationException ex) { return null; @@ -73,13 +82,13 @@ public String[] getParameterNames(Constructor ctor) { } @Nullable - private String[] getParameterNames(List parameters) { + private String[] getParameterNames(List parameters, boolean addContinuationName) { List filteredParameters = parameters .stream() // 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())) .toList(); - String[] parameterNames = new String[filteredParameters.size()]; + String[] parameterNames = new String[filteredParameters.size() + (addContinuationName ? 1 : 0)]; for (int i = 0; i < filteredParameters.size(); i++) { KParameter parameter = filteredParameters.get(i); // extension receivers are not explicitly named, but require a name for Java interoperability @@ -90,7 +99,9 @@ private String[] getParameterNames(List parameters) { } parameterNames[i] = name; } + if (addContinuationName) { + parameterNames[filteredParameters.size()] = "continuation"; + } return parameterNames; } - }