Skip to content

Commit 98255d2

Browse files
authored
Merge pull request #897 from graphql-java-kickstart/refactor/determine-type
Determine input types with the same recursion as output types
2 parents 04b6789 + 7448f2c commit 98255d2

1 file changed

Lines changed: 18 additions & 54 deletions

File tree

‎src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt‎

Lines changed: 18 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,11 @@ class SchemaParser internal constructor(
205205
}
206206

207207
private fun createInputObject(definition: InputObjectTypeDefinition, inputObjects: List<GraphQLInputObjectType>,
208-
referencingInputObjects: MutableSet<String>): GraphQLInputObjectType {
208+
inputObjectsInProgress: MutableSet<String>): GraphQLInputObjectType {
209209
val extensionDefinitions = typeExtensions.extensionsOf<InputObjectTypeExtensionDefinition>(definition.name)
210210
val directives = directivesOf(definition, extensionDefinitions)
211211

212-
referencingInputObjects.add(definition.name)
212+
inputObjectsInProgress.add(definition.name)
213213

214214
val builder = GraphQLInputObjectType.newInputObject()
215215
.name(definition.name)
@@ -228,7 +228,7 @@ class SchemaParser internal constructor(
228228
.description(getDocumentation(fieldDefinition, options))
229229
.apply { fieldDefinition.defaultValue?.let { v -> defaultValueLiteral(v) } }
230230
.apply { getDeprecated(fieldDefinition.directives)?.let { deprecate(it) } }
231-
.type(determineInputType(fieldDefinition.type, inputObjects, referencingInputObjects))
231+
.type(determineInputType(fieldDefinition.type, inputObjects, inputObjectsInProgress))
232232
.withAppliedDirectives(*buildAppliedDirectives(fieldDefinition.directives, INPUT_FIELD_DEFINITION))
233233
.withDirectives(*buildDirectives(fieldDefinition.directives, INPUT_FIELD_DEFINITION))
234234
.build()
@@ -629,15 +629,15 @@ class SchemaParser internal constructor(
629629
private fun determineOutputType(typeDefinition: Type<*>) =
630630
determineType(GraphQLOutputType::class, typeDefinition, permittedTypesForObject) as GraphQLOutputType
631631

632-
// named types other than spec scalars are type references
633632
private fun <T : Any> determineType(
634633
expectedType: KClass<T>,
635634
typeDefinition: Type<*>,
636-
allowedTypeReferences: Set<String>
635+
allowedTypeReferences: Set<String>,
636+
namedType: (TypeName) -> GraphQLType = { GraphQLTypeReference(it.name) }
637637
): GraphQLType =
638638
when (typeDefinition) {
639-
is ListType -> GraphQLList(determineType(expectedType, typeDefinition.type, allowedTypeReferences))
640-
is NonNullType -> GraphQLNonNull(determineType(expectedType, typeDefinition.type, allowedTypeReferences))
639+
is ListType -> GraphQLList(determineType(expectedType, typeDefinition.type, allowedTypeReferences, namedType))
640+
is NonNullType -> GraphQLNonNull(determineType(expectedType, typeDefinition.type, allowedTypeReferences, namedType))
641641
is TypeName -> {
642642
val scalarType = scalarType(typeDefinition.name)
643643
if (scalarType != null) {
@@ -646,59 +646,23 @@ class SchemaParser internal constructor(
646646
if (!allowedTypeReferences.contains(typeDefinition.name)) {
647647
throw unexpectedTypeError(typeDefinition, expectedType)
648648
}
649-
GraphQLTypeReference(typeDefinition.name)
649+
namedType(typeDefinition)
650650
}
651651
}
652652
else -> throw SchemaError("Unknown type: $typeDefinition")
653653
}
654654

655-
private fun determineInputType(typeDefinition: Type<*>, inputObjects: List<GraphQLInputObjectType>, referencingInputObjects: MutableSet<String>) =
656-
determineInputType(GraphQLInputType::class, typeDefinition, permittedTypesForInputObject, inputObjects, referencingInputObjects)
655+
private fun determineInputType(typeDefinition: Type<*>, inputObjects: List<GraphQLInputObjectType>, inputObjectsInProgress: MutableSet<String>) =
656+
determineType(GraphQLInputType::class, typeDefinition, permittedTypesForInputObject) {
657+
inputObjectType(it, inputObjects, inputObjectsInProgress)
658+
} as GraphQLInputType
657659

658-
private fun <T : Any> determineInputType(
659-
expectedType: KClass<T>,
660-
typeDefinition: Type<*>,
661-
allowedTypeReferences: Set<String>,
662-
inputObjects: List<GraphQLInputObjectType>,
663-
referencingInputObjects: MutableSet<String>): GraphQLInputType =
664-
when (typeDefinition) {
665-
is ListType -> GraphQLList(determineInputType(expectedType, typeDefinition.type, allowedTypeReferences, inputObjects, referencingInputObjects))
666-
is NonNullType -> GraphQLNonNull(determineInputType(expectedType, typeDefinition.type, allowedTypeReferences, inputObjects, referencingInputObjects))
667-
is InputObjectTypeDefinition -> {
668-
log.info("Create input object")
669-
createInputObject(typeDefinition, inputObjects, referencingInputObjects)
670-
}
671-
is TypeName -> {
672-
val scalarType = scalarType(typeDefinition.name)
673-
if (scalarType != null) {
674-
scalarType
675-
} else {
676-
if (!allowedTypeReferences.contains(typeDefinition.name)) {
677-
throw unexpectedTypeError(typeDefinition, expectedType)
678-
}
679-
val found = inputObjects.filter { it.name == typeDefinition.name }
680-
if (found.size == 1) {
681-
found[0]
682-
} else {
683-
val filteredDefinitions = inputObjectDefinitions.filter { it.name == typeDefinition.name }
684-
if (filteredDefinitions.isNotEmpty()) {
685-
val referencingInputObject = referencingInputObjects.find { it == typeDefinition.name }
686-
if (referencingInputObject != null) {
687-
GraphQLTypeReference(referencingInputObject)
688-
} else {
689-
val inputObject = createInputObject(filteredDefinitions[0], inputObjects, referencingInputObjects)
690-
(inputObjects as MutableList).add(inputObject)
691-
inputObject
692-
}
693-
} else {
694-
// todo: handle enum type
695-
GraphQLTypeReference(typeDefinition.name)
696-
}
697-
}
698-
}
699-
}
700-
else -> throw SchemaError("Unknown type: $typeDefinition")
701-
}
660+
private fun inputObjectType(typeName: TypeName, inputObjects: List<GraphQLInputObjectType>, inputObjectsInProgress: MutableSet<String>): GraphQLType {
661+
inputObjects.find { it.name == typeName.name }?.let { return it }
662+
val definition = inputObjectDefinitions.find { it.name == typeName.name }
663+
if (definition == null || typeName.name in inputObjectsInProgress) return GraphQLTypeReference(typeName.name)
664+
return createInputObject(definition, inputObjects, inputObjectsInProgress).also { (inputObjects as MutableList).add(it) }
665+
}
702666

703667
private fun unexpectedTypeError(typeName: TypeName, expectedType: KClass<*>): SchemaError {
704668
val isInput = expectedType == GraphQLInputType::class

0 commit comments

Comments
 (0)