2525import java .util .Optional ;
2626
2727import graphql .schema .DataFetchingEnvironment ;
28+ import kotlin .jvm .JvmClassMappingKt ;
29+ import kotlin .reflect .KClass ;
30+ import kotlin .reflect .KFunction ;
31+ import kotlin .reflect .KParameter ;
32+ import kotlin .reflect .KType ;
33+ import kotlin .reflect .full .KClasses ;
34+ import kotlin .reflect .jvm .KCallablesJvm ;
35+ import kotlin .reflect .jvm .ReflectJvmMapping ;
2836
2937import org .springframework .beans .BeanInstantiationException ;
3038import org .springframework .beans .BeanUtils ;
3644import org .springframework .beans .TypeMismatchException ;
3745import org .springframework .core .CollectionFactory ;
3846import org .springframework .core .Conventions ;
47+ import org .springframework .core .KotlinDetector ;
3948import org .springframework .core .MethodParameter ;
4049import org .springframework .core .ResolvableType ;
4150import org .springframework .core .convert .ConversionService ;
@@ -280,7 +289,7 @@ private Object bindViaConstructorAndSetters(Constructor<?> constructor,
280289 Map <String , Object > dataToBind = new HashMap <>(rawMap );
281290 String [] paramNames = BeanUtils .getParameterNames (constructor );
282291 Class <?>[] paramTypes = constructor .getParameterTypes ();
283- Object [] constructorArguments = new Object [paramTypes .length ];
292+ Object [] constructorArguments = new Object [paramNames .length ];
284293
285294 for (int i = 0 ; i < paramNames .length ; i ++) {
286295 String name = paramNames [i ];
@@ -290,8 +299,12 @@ private Object bindViaConstructorAndSetters(Constructor<?> constructor,
290299
291300 constructorArguments [i ] = bindRawValue (
292301 name , dataToBind .get (name ), !dataToBind .containsKey (name ), targetType , paramTypes [i ], bindingResult );
302+
293303 dataToBind .remove (name );
294304 }
305+ if (KotlinDetector .isKotlinReflectPresent () && KotlinDetector .isKotlinType (constructor .getDeclaringClass ())) {
306+ KotlinDelegate .rebindKotlinArguments (constructorArguments , constructor );
307+ }
295308
296309 Object target ;
297310 try {
@@ -419,4 +432,37 @@ void rejectArgumentValue(
419432 }
420433 }
421434
435+ // remove in favor of https://github.com/spring-projects/spring-framework/issues/33630
436+ private static final class KotlinDelegate {
437+
438+ public static void rebindKotlinArguments (Object [] arguments , Constructor <?> constructor ) {
439+ KFunction <?> function = ReflectJvmMapping .getKotlinFunction (constructor );
440+ if (function == null ) {
441+ return ;
442+ }
443+ int index = 0 ;
444+ for (KParameter parameter : function .getParameters ()) {
445+ switch (parameter .getKind ()) {
446+ case VALUE , EXTENSION_RECEIVER -> {
447+ Object rawValue = arguments [index ];
448+ if (!(parameter .isOptional () && rawValue == null )) {
449+ KType type = parameter .getType ();
450+ if (!(type .isMarkedNullable () && rawValue == null ) && type .getClassifier () instanceof KClass <?> kClass
451+ && KotlinDetector .isInlineClass (JvmClassMappingKt .getJavaClass (kClass ))) {
452+ KFunction <?> argConstructor = KClasses .getPrimaryConstructor (kClass );
453+ if (argConstructor != null ) {
454+ if (!KCallablesJvm .isAccessible (argConstructor )) {
455+ KCallablesJvm .setAccessible (argConstructor , true );
456+ }
457+ arguments [index ] = argConstructor .call (rawValue );
458+ }
459+ }
460+ }
461+ }
462+ }
463+ index ++;
464+ }
465+ }
466+ }
467+
422468}
0 commit comments