@@ -14,8 +14,6 @@ import graphql.schema.DataFetchingEnvironment
1414import graphql.schema.GraphQLTypeUtil.isScalar
1515import kotlinx.coroutines.future.future
1616import java.lang.reflect.Method
17- import java.lang.reflect.ParameterizedType
18- import java.lang.reflect.WildcardType
1917import java.util.*
2018import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
2119import kotlin.reflect.full.valueParameters
@@ -82,15 +80,13 @@ internal class MethodFieldResolver(
8280 return @add Optional .empty<Any >()
8381 }
8482
85- if (value != null
86- && parameterType.unwrap().isAssignableFrom( value.javaClass)
87- && isScalarType(environment, definition.type, parameterType)) {
88- return @add value
83+ if (isValueMustBeConvert( value, definition, parameterType, environment)) {
84+ return @add mapper.convertValue( value, object : TypeReference < Any >() {
85+ override fun getType () = parameterType
86+ })
8987 }
9088
91- return @add mapper.convertValue(value, object : TypeReference <Any >() {
92- override fun getType () = parameterType
93- })
89+ return @add value
9490 }
9591 }
9692
@@ -110,23 +106,27 @@ internal class MethodFieldResolver(
110106 }
111107 }
112108
113- private fun isScalarType (environment : DataFetchingEnvironment , type : Type <* >, genericParameterType : JavaType ): Boolean =
109+ private fun isValueMustBeConvert (value : Any? , definition : InputValueDefinition , parameterType : JavaType , environment : DataFetchingEnvironment ): Boolean {
110+ return value != null
111+ && (! parameterType.unwrap().isAssignableFrom(value.javaClass)
112+ || ! isConcreteScalarType(environment, definition.type, parameterType))
113+ }
114+
115+ /* *
116+ * A concrete scalar type is a scalar type where values are always coerce to the same Java type.
117+ * The ID scalar type is not concrete because values can be coerce to many Java types (eg. String, Long, UUID).
118+ * All values of a non concrete scalar type must be convert to the method field type.
119+ */
120+ private fun isConcreteScalarType (environment : DataFetchingEnvironment , type : Type <* >, genericParameterType : JavaType ): Boolean =
114121 when (type) {
115122 is ListType -> List ::class .java.isAssignableFrom(this .genericType.getRawClass(genericParameterType))
116- && isScalarType (environment, type.type, this .genericType.unwrapGenericType(genericParameterType))
117- is TypeName -> environment.graphQLSchema?.getType(type.name)?.let { isScalar(it) && ! isJavaLanguageType(genericParameterType) }
118- ? : false
119- is NonNullType -> isScalarType (environment, type.type, genericParameterType)
123+ && isConcreteScalarType (environment, type.type, this .genericType.unwrapGenericType(genericParameterType))
124+ is TypeName -> environment.graphQLSchema?.getType(type.name)?.let { isScalar(it) && type.name != " ID " }
125+ ? : false
126+ is NonNullType -> isConcreteScalarType (environment, type.type, genericParameterType)
120127 else -> false
121128 }
122129
123- private fun isJavaLanguageType (type : JavaType ): Boolean =
124- when (type) {
125- is ParameterizedType -> isJavaLanguageType(type.actualTypeArguments[0 ])
126- is WildcardType -> isJavaLanguageType(type.upperBounds[0 ])
127- else -> genericType.getRawClass(type).`package`.name == " java.lang"
128- }
129-
130130 override fun scanForMatches (): List <TypeClassMatcher .PotentialMatch > {
131131 val unwrappedGenericType = genericType.unwrapGenericType(try {
132132 method.kotlinFunction?.returnType?.javaType ? : method.genericReturnType
0 commit comments