From 7e2b4fb65abfff69b71659a7fad6e2c2cb6e21e8 Mon Sep 17 00:00:00 2001 From: Tim Ward Date: Mon, 6 Mar 2023 23:55:38 -0800 Subject: [PATCH 1/2] Add support for unused types for all dictionary types --- .../kotlin/graphql/kickstart/tools/SchemaClassScanner.kt | 8 +++----- .../graphql/kickstart/tools/SchemaClassScannerTest.kt | 9 ++++++++- .../kotlin/graphql/kickstart/tools/TestInterfaces.kt | 7 +++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt b/src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt index fd445ff9..887f1f57 100644 --- a/src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt +++ b/src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt @@ -91,15 +91,13 @@ internal class SchemaClassScanner( do { val unusedDefinitions = (definitionsByName.values - (dictionary.keys.toSet() + unvalidatedTypes)) .filter { definition -> definition.name != "PageInfo" } - .filterIsInstance().distinct() + .distinct() if (unusedDefinitions.isEmpty()) { break } - val unusedDefinition = unusedDefinitions.first() - - handleDictionaryTypes(listOf(unusedDefinition)) { "Object type '${it.name}' is unused and includeUnusedTypes is true. Please pass a class for type '${it.name}' in the parser's dictionary." } + handleDictionaryTypes(unusedDefinitions) { "Type '${it.name}' is unused and includeUnusedTypes is true. Please pass a class for type '${it.name}' in the parser's dictionary." } } while (scanQueue()) } @@ -229,7 +227,7 @@ internal class SchemaClassScanner( }.flatten().distinct() } - private fun handleDictionaryTypes(types: List, failureMessage: (ObjectTypeDefinition) -> String) { + private fun handleDictionaryTypes(types: List>, failureMessage: (TypeDefinition<*>) -> String) { types.forEach { type -> val dictionaryContainsType = dictionary.filter { it.key.name == type.name }.isNotEmpty() if (!unvalidatedTypes.contains(type) && !dictionaryContainsType) { diff --git a/src/test/kotlin/graphql/kickstart/tools/SchemaClassScannerTest.kt b/src/test/kotlin/graphql/kickstart/tools/SchemaClassScannerTest.kt index 673fbe33..87af797f 100644 --- a/src/test/kotlin/graphql/kickstart/tools/SchemaClassScannerTest.kt +++ b/src/test/kotlin/graphql/kickstart/tools/SchemaClassScannerTest.kt @@ -497,12 +497,19 @@ class SchemaClassScannerTest { type Implementation implements SomeInterface { value: String } + + union SomeUnion = Unused | Implementation + + enum SomeEnum { + A + B + } """) .resolvers(object : GraphQLQueryResolver { fun whatever(): Whatever? = null }) .options(SchemaParserOptions.newOptions().includeUnusedTypes(true).build()) - .dictionary(Unused::class, Implementation::class) + .dictionary(Unused::class, Implementation::class, SomeInterface::class, SomeUnion::class, SomeEnum::class) .build() .makeExecutableSchema() diff --git a/src/test/kotlin/graphql/kickstart/tools/TestInterfaces.kt b/src/test/kotlin/graphql/kickstart/tools/TestInterfaces.kt index 17a22a91..52e2ff54 100644 --- a/src/test/kotlin/graphql/kickstart/tools/TestInterfaces.kt +++ b/src/test/kotlin/graphql/kickstart/tools/TestInterfaces.kt @@ -14,3 +14,10 @@ interface SomeInterface { fun getValue(): String? } +interface SomeUnion + +enum class SomeEnum { + A, + B +} + From 4b83c0b3d9295aa8aec11fbbc3f7b7f392cf1c92 Mon Sep 17 00:00:00 2001 From: Tim Ward Date: Tue, 14 Mar 2023 13:47:06 -0700 Subject: [PATCH 2/2] Restrict to composite and enum types. --- .../kotlin/graphql/kickstart/tools/SchemaClassScanner.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt b/src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt index 887f1f57..b7258512 100644 --- a/src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt +++ b/src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt @@ -91,6 +91,7 @@ internal class SchemaClassScanner( do { val unusedDefinitions = (definitionsByName.values - (dictionary.keys.toSet() + unvalidatedTypes)) .filter { definition -> definition.name != "PageInfo" } + .filter { isCompositeOrEnumType(it) } .distinct() if (unusedDefinitions.isEmpty()) { @@ -104,6 +105,10 @@ internal class SchemaClassScanner( return validateAndCreateResult(rootTypeHolder) } + private fun isCompositeOrEnumType(definition: TypeDefinition<*>): Boolean { + return definition is ObjectTypeDefinition || definition is InterfaceTypeDefinition || definition is UnionTypeDefinition || definition is EnumTypeDefinition + } + private fun scanQueue(): Boolean { if (queue.isEmpty()) { return false