@@ -14,8 +14,6 @@ import graphql.schema.DataFetchingEnvironment
14
14
import graphql.schema.GraphQLTypeUtil.isScalar
15
15
import kotlinx.coroutines.future.future
16
16
import java.lang.reflect.Method
17
- import java.lang.reflect.ParameterizedType
18
- import java.lang.reflect.WildcardType
19
17
import java.util.*
20
18
import kotlin.coroutines.intrinsics.suspendCoroutineUninterceptedOrReturn
21
19
import kotlin.reflect.full.valueParameters
@@ -82,15 +80,13 @@ internal class MethodFieldResolver(
82
80
return @add Optional .empty<Any >()
83
81
}
84
82
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
+ })
89
87
}
90
88
91
- return @add mapper.convertValue(value, object : TypeReference <Any >() {
92
- override fun getType () = parameterType
93
- })
89
+ return @add value
94
90
}
95
91
}
96
92
@@ -110,23 +106,27 @@ internal class MethodFieldResolver(
110
106
}
111
107
}
112
108
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 =
114
121
when (type) {
115
122
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)
120
127
else -> false
121
128
}
122
129
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
-
130
130
override fun scanForMatches (): List <TypeClassMatcher .PotentialMatch > {
131
131
val unwrappedGenericType = genericType.unwrapGenericType(try {
132
132
method.kotlinFunction?.returnType?.javaType ? : method.genericReturnType
0 commit comments