You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 404b3e7
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt
+35-7Lines changed: 35 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -75,16 +75,24 @@ internal class SchemaClassScanner(
75
75
76
76
scanQueue()
77
77
78
-
// Loop over all objects scanning each one only once for more objects to discover.
79
-
do {
80
-
do {
81
-
// Require all implementors of discovered interfaces to be discovered or provided.
82
-
handleDictionaryTypes(getAllObjectTypesImplementingDiscoveredInterfaces()) { "Object type '${it.name}' implements a known interface, but no class could be found for that type name. Please pass a class for type '${it.name}' in the parser's dictionary." }
83
-
} while(scanQueue())
78
+
// Loop over all objects scanning each one only once for more objects to discover. Each step only runs once the steps
79
+
// above it have nothing left, and anything new starts over from the top.
80
+
while (true) {
81
+
// Require all implementors of discovered interfaces to be discovered or provided.
82
+
handleDictionaryTypes(getAllObjectTypesImplementingDiscoveredInterfaces()) { "Object type '${it.name}' implements a known interface, but no class could be found for that type name. Please pass a class for type '${it.name}' in the parser's dictionary." }
83
+
if(scanQueue())continue
84
84
85
85
// Require all members of discovered unions to be discovered.
86
86
handleDictionaryTypes(getAllObjectTypeMembersOfDiscoveredUnions()) { "Object type '${it.name}' is a member of a known union, but no class could be found for that type name. Please pass a class for type '${it.name}' in the parser's dictionary." }
87
-
} while (scanQueue())
87
+
if (scanQueue()) continue
88
+
89
+
// Look for unions and interfaces used only by interface fields last, so types that can be reached some other way
90
+
// are still discovered in the same order as before. With includeUnusedTypes the unused types loop below already
91
+
// picks these up one at a time, scanning in between, so leave that path unchanged.
92
+
if (!options.includeUnusedTypes && handleInterfaceFieldTypes()) continue
93
+
94
+
break
95
+
}
88
96
89
97
handleDirectives()
90
98
@@ -270,6 +278,26 @@ internal class SchemaClassScanner(
270
278
}.flatten().distinct()
271
279
}
272
280
281
+
/**
282
+
* Implementations can narrow an interface field to a member of its union or an implementor of its interface, so such a
283
+
* union or interface may not be reachable from any object field. Returns whether any new types were found.
284
+
*/
285
+
privatefunhandleInterfaceFieldTypes(): Boolean {
286
+
val newTypes = dictionary.keys.filterIsInstance<InterfaceTypeDefinition>().flatMap { iface ->
287
+
iface.fieldDefinitions.mapNotNull { field ->
288
+
val type = definitionsByName[(field.type.unwrap() asTypeName).name]
289
+
if ((type isUnionTypeDefinition|| type isInterfaceTypeDefinition) &&!dictionary.containsKey(type)) {
290
+
type to FieldTypeReference("${iface.name}.${field.name}")
0 commit comments