|
|
|
@ -58,8 +58,20 @@ import org.springframework.util.ClassUtils;
@@ -58,8 +58,20 @@ import org.springframework.util.ClassUtils;
|
|
|
|
|
*/ |
|
|
|
|
public class MethodParameter { |
|
|
|
|
|
|
|
|
|
private static final boolean kotlinPresent = |
|
|
|
|
ClassUtils.isPresent("kotlin.Metadata", MethodParameter.class.getClassLoader()); |
|
|
|
|
@Nullable |
|
|
|
|
private static final Class<?> kotlinMetadata; |
|
|
|
|
|
|
|
|
|
static { |
|
|
|
|
Class<?> metadata; |
|
|
|
|
try { |
|
|
|
|
metadata = ClassUtils.forName("kotlin.Metadata", MethodParameter.class.getClassLoader()); |
|
|
|
|
} |
|
|
|
|
catch (ClassNotFoundException ex) { |
|
|
|
|
// Kotlin API not available - no Kotlin support
|
|
|
|
|
metadata = null; |
|
|
|
|
} |
|
|
|
|
kotlinMetadata = metadata; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Executable executable; |
|
|
|
@ -341,7 +353,16 @@ public class MethodParameter {
@@ -341,7 +353,16 @@ public class MethodParameter {
|
|
|
|
|
*/ |
|
|
|
|
public boolean isOptional() { |
|
|
|
|
return (getParameterType() == Optional.class || hasNullableAnnotation() || |
|
|
|
|
(kotlinPresent && KotlinDelegate.isNullable(this))); |
|
|
|
|
(useKotlinSupport(this.getContainingClass()) && KotlinDelegate.isNullable(this))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Return true if Kotlin is present and if the specified class is a Kotlin one. |
|
|
|
|
*/ |
|
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
|
private static boolean useKotlinSupport(Class<?> clazz) { |
|
|
|
|
return (kotlinMetadata != null && |
|
|
|
|
clazz.getDeclaredAnnotation((Class<? extends Annotation>) kotlinMetadata) != null); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -736,41 +757,30 @@ public class MethodParameter {
@@ -736,41 +757,30 @@ public class MethodParameter {
|
|
|
|
|
* Check whether the specified {@link MethodParameter} represents a nullable Kotlin type or not. |
|
|
|
|
*/ |
|
|
|
|
public static boolean isNullable(MethodParameter param) { |
|
|
|
|
if (isKotlinClass(param.getContainingClass())) { |
|
|
|
|
Method method = param.getMethod(); |
|
|
|
|
Constructor<?> ctor = param.getConstructor(); |
|
|
|
|
int index = param.getParameterIndex(); |
|
|
|
|
if (method != null && index == -1) { |
|
|
|
|
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method); |
|
|
|
|
return (function != null && function.getReturnType().isMarkedNullable()); |
|
|
|
|
Method method = param.getMethod(); |
|
|
|
|
Constructor<?> ctor = param.getConstructor(); |
|
|
|
|
int index = param.getParameterIndex(); |
|
|
|
|
if (method != null && index == -1) { |
|
|
|
|
KFunction<?> function = ReflectJvmMapping.getKotlinFunction(method); |
|
|
|
|
return (function != null && function.getReturnType().isMarkedNullable()); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
KFunction<?> function = null; |
|
|
|
|
if (method != null) { |
|
|
|
|
function = ReflectJvmMapping.getKotlinFunction(method); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
KFunction<?> function = null; |
|
|
|
|
if (method != null) { |
|
|
|
|
function = ReflectJvmMapping.getKotlinFunction(method); |
|
|
|
|
} |
|
|
|
|
else if (ctor != null) { |
|
|
|
|
function = ReflectJvmMapping.getKotlinFunction(ctor); |
|
|
|
|
} |
|
|
|
|
if (function != null) { |
|
|
|
|
List<KParameter> parameters = function.getParameters(); |
|
|
|
|
return parameters |
|
|
|
|
.stream() |
|
|
|
|
.filter(p -> KParameter.Kind.VALUE.equals(p.getKind())) |
|
|
|
|
.collect(Collectors.toList()) |
|
|
|
|
.get(index) |
|
|
|
|
.getType() |
|
|
|
|
.isMarkedNullable(); |
|
|
|
|
} |
|
|
|
|
else if (ctor != null) { |
|
|
|
|
function = ReflectJvmMapping.getKotlinFunction(ctor); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static boolean isKotlinClass(Class<?> clazz) { |
|
|
|
|
for (Annotation annotation : clazz.getDeclaredAnnotations()) { |
|
|
|
|
if (annotation.annotationType().getName().equals("kotlin.Metadata")) { |
|
|
|
|
return true; |
|
|
|
|
if (function != null) { |
|
|
|
|
List<KParameter> parameters = function.getParameters(); |
|
|
|
|
return parameters |
|
|
|
|
.stream() |
|
|
|
|
.filter(p -> KParameter.Kind.VALUE.equals(p.getKind())) |
|
|
|
|
.collect(Collectors.toList()) |
|
|
|
|
.get(index) |
|
|
|
|
.getType() |
|
|
|
|
.isMarkedNullable(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|