Default generic type arguments when resolving KType from a Class.

We now fill up missing KTypeProjection arguments with star because the Kotlin Reflection.typeOf resolution fails if arguments are not provided.

Closes #3041
Original pull request: #3048
This commit is contained in:
Christoph Strobl
2024-02-21 08:45:46 +01:00
committed by Mark Paluch
parent 2ebb6a768e
commit 25c7c7519e
2 changed files with 55 additions and 1 deletions

View File

@@ -25,10 +25,12 @@ import kotlin.reflect.KParameter;
import kotlin.reflect.KProperty;
import kotlin.reflect.KType;
import kotlin.reflect.KTypeParameter;
import kotlin.reflect.KTypeProjection;
import kotlin.reflect.jvm.ReflectJvmMapping;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -39,6 +41,7 @@ import org.springframework.util.Assert;
* Utilities for Kotlin Value class support.
*
* @author Mark Paluch
* @author Christoph Strobl
* @since 3.2
*/
class KotlinValueUtils {
@@ -72,7 +75,28 @@ class KotlinValueUtils {
public static ValueBoxing getConstructorValueHierarchy(Class<?> cls) {
KClass<?> kotlinClass = JvmClassMappingKt.getKotlinClass(cls);
return new ValueBoxing(BoxingRules.CONSTRUCTOR, Reflection.typeOf(kotlinClass), kotlinClass, false);
KType kType = extractKType(kotlinClass);
return new ValueBoxing(BoxingRules.CONSTRUCTOR, kType, kotlinClass, false);
}
/**
* Get the {@link KType} for a given {@link KClass} and potentially fill missing generic type arguments with
* {@link KTypeProjection#star} to prevent Kotlin internal checks to fail.
*
* @param kotlinClass
* @return
*/
private static KType extractKType(KClass<?> kotlinClass) {
return kotlinClass.getTypeParameters().isEmpty() ? Reflection.typeOf(kotlinClass)
: Reflection.typeOf(JvmClassMappingKt.getJavaClass(kotlinClass), stubKTypeProjections(kotlinClass));
}
private static KTypeProjection[] stubKTypeProjections(KClass<?> kotlinClass) {
KTypeProjection[] kTypeProjections = new KTypeProjection[kotlinClass.getTypeParameters().size()];
Arrays.fill(kTypeProjections, KTypeProjection.star);
return kTypeProjections;
}
/**