@@ -22,6 +22,7 @@ import com.squareup.kotlinpoet.ClassName
22
22
import com.squareup.kotlinpoet.FLOAT
23
23
import com.squareup.kotlinpoet.INT
24
24
import com.squareup.kotlinpoet.LIST
25
+ import com.squareup.kotlinpoet.ParameterizedTypeName
25
26
import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy
26
27
import com.squareup.kotlinpoet.STRING
27
28
import com.squareup.kotlinpoet.TypeName
@@ -97,7 +98,7 @@ internal fun generateCustomClassName(context: GraphQLClientGeneratorContext, gra
97
98
} else {
98
99
// verify we got same selection set for interface and/or objects (unions shouldn't have any fields)
99
100
for (cachedType in cachedTypeNames) {
100
- if (isCachedTypeApplicable(context, cachedType.simpleName , graphQLTypeDefinition, selectionSet)) {
101
+ if (isCachedTypeApplicable(context, cachedType.simpleNameWithoutWrapper() , graphQLTypeDefinition, selectionSet)) {
101
102
return cachedType
102
103
}
103
104
}
@@ -111,11 +112,13 @@ internal fun generateCustomClassName(context: GraphQLClientGeneratorContext, gra
111
112
else -> throw RuntimeException (" should never happen" )
112
113
}
113
114
val className = ClassName (context.packageName, " ${context.rootType} .${typeSpec.name} " )
114
- context.classNameCache[overriddenName ]?.add(className)
115
+ context.classNameCache[graphQLTypeName ]?.add(className)
115
116
className
116
117
}
117
118
}
118
119
120
+ private fun ClassName.simpleNameWithoutWrapper () = this .simpleName.substringAfter(" ." )
121
+
119
122
private fun isCachedTypeApplicable (context : GraphQLClientGeneratorContext , graphQLTypeName : String , graphQLTypeDefinition : TypeDefinition <* >, selectionSet : SelectionSet ): Boolean =
120
123
when (graphQLTypeDefinition) {
121
124
is UnionTypeDefinition -> {
@@ -148,21 +151,28 @@ private fun isCachedTypeApplicable(context: GraphQLClientGeneratorContext, graph
148
151
149
152
private fun verifySelectionSet (context : GraphQLClientGeneratorContext , graphQLTypeName : String , selectionSet : SelectionSet ): Boolean {
150
153
val selectedFields = calculateSelectedFields(context, graphQLTypeName, selectionSet)
151
- val typeSpec = context.typeSpecs[graphQLTypeName]
152
- val properties = typeSpec?.propertySpecs?.map { it.name }?.toSet() ? : emptySet()
153
- return selectedFields == properties ||
154
- (selectedFields.minus(properties).size == 1 && selectedFields.contains(" __typename" ) && context.objectsWithTypeNameSelection.contains(graphQLTypeName))
154
+ val properties = calculateGeneratedTypeProperties(context, graphQLTypeName)
155
+ if (context.objectsWithTypeNameSelection.contains(graphQLTypeName)) {
156
+ properties.add(" __typename" )
157
+ }
158
+ return selectedFields == properties
155
159
}
156
160
157
161
private fun calculateSelectedFields (
158
162
context : GraphQLClientGeneratorContext ,
159
163
targetType : String ,
160
- selectionSet : SelectionSet
164
+ selectionSet : SelectionSet ,
165
+ path : String = ""
161
166
): Set <String > {
162
167
val result = mutableSetOf<String >()
163
168
selectionSet.selections.forEach { selection ->
164
169
when (selection) {
165
- is Field -> result.add(selection.name)
170
+ is Field -> {
171
+ result.add(path + selection.name)
172
+ if (selection.selectionSet != null ) {
173
+ result.addAll(calculateSelectedFields(context, targetType, selection.selectionSet, " $path${selection.name} ." ))
174
+ }
175
+ }
166
176
is InlineFragment -> if (selection.typeCondition.name == targetType) {
167
177
result.addAll(calculateSelectedFields(context, targetType, selection.selectionSet))
168
178
}
@@ -178,3 +188,24 @@ private fun calculateSelectedFields(
178
188
}
179
189
return result
180
190
}
191
+
192
+ private fun calculateGeneratedTypeProperties (context : GraphQLClientGeneratorContext , graphQLTypeName : String , path : String = ""): MutableSet <String > {
193
+ val props = mutableSetOf<String >()
194
+
195
+ val typeSpec = context.typeSpecs[graphQLTypeName]
196
+ for (property in typeSpec?.propertySpecs ? : emptyList()) {
197
+ props.add(path + property.name)
198
+ when (val propertyType = property.type) {
199
+ is ParameterizedTypeName -> {
200
+ val genericType = propertyType.typeArguments.firstOrNull() as ? ClassName
201
+ val genericTypeName = genericType?.simpleNameWithoutWrapper() ? : " "
202
+ props.addAll(calculateGeneratedTypeProperties(context, genericTypeName, " $path${property.name} ." ))
203
+ }
204
+ is ClassName -> {
205
+ val fieldTypeName = propertyType.simpleNameWithoutWrapper()
206
+ props.addAll(calculateGeneratedTypeProperties(context, fieldTypeName, " $path${property.name} ." ))
207
+ }
208
+ }
209
+ }
210
+ return props
211
+ }
0 commit comments