Support Kotlin suspending functions in MethodParameter

Before this commit, the return type for Kotlin suspending functions
(as returned by MethodParameter#getParameterType and
MethodParameter#getGenericReturnType methods) was incorrect.

This change leverages Kotlin reflection instead of Java one
to return the correct type.

Closes gh-21058
This commit is contained in:
Konrad Kamiński
2017-12-13 16:16:05 +01:00
committed by Sebastien Deleuze
parent 5938742afd
commit 9302cb2f85
3 changed files with 168 additions and 4 deletions

View File

@@ -402,7 +402,9 @@ public class MethodParameter {
if (paramType == null) {
if (this.parameterIndex < 0) {
Method method = getMethod();
paramType = (method != null ? method.getReturnType() : void.class);
paramType = (method != null ?
(KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(getContainingClass()) ?
KotlinDelegate.getReturnType(method) : method.getReturnType()) : void.class);
}
else {
paramType = this.executable.getParameterTypes()[this.parameterIndex];
@@ -422,7 +424,9 @@ public class MethodParameter {
if (paramType == null) {
if (this.parameterIndex < 0) {
Method method = getMethod();
paramType = (method != null ? method.getGenericReturnType() : void.class);
paramType = (method != null ?
(KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(getContainingClass()) ?
KotlinDelegate.getGenericReturnType(method) : method.getGenericReturnType()) : void.class);
}
else {
Type[] genericParameterTypes = this.executable.getGenericParameterTypes();
@@ -799,6 +803,32 @@ public class MethodParameter {
}
return false;
}
}
/**
* Return the generic return type of the method, with support of suspending
* functions via Kotlin reflection.
*/
static private Type getGenericReturnType(Method method) {
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
if (function != null && function.isSuspend()) {
return ReflectJvmMapping.getJavaType(function.getReturnType());
}
return method.getGenericReturnType();
}
/**
* Return the return type of the method, with support of suspending
* functions via Kotlin reflection.
*/
static private Class<?> getReturnType(Method method) {
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method);
if (function != null && function.isSuspend()) {
Type paramType = ReflectJvmMapping.getJavaType(function.getReturnType());
Class<?> paramClass = ResolvableType.forType(paramType).resolve();
Assert.notNull(paramClass, "Type " + paramType + "can't be resolved to a class");
return paramClass;
}
return method.getReturnType();
}
}
}