@@ -280,7 +280,7 @@ class GraphQLDocumentParser(val schema: Schema, private val packageNameProvider:
280
280
val fields = selectionSet().parse(schemaFieldType)
281
281
val fragmentRefs = selectionSet().fragmentRefs()
282
282
val inlineFragments = selectionSet()?.selection()?.mapNotNull { ctx ->
283
- ctx.inlineFragment()?.parse(parentSelectionSet = selectionSet(), parentSchemaType = schemaFieldType )
283
+ ctx.inlineFragment()?.parse(parentSchemaType = schemaFieldType, parentFields = fields )
284
284
}?.flatten() ? : ParseResult (result = emptyList())
285
285
286
286
val inlineFragmentFieldsToMerge = inlineFragments.result
@@ -387,38 +387,55 @@ class GraphQLDocumentParser(val schema: Schema, private val packageNameProvider:
387
387
}
388
388
389
389
private fun GraphQLParser.InlineFragmentContext.parse (
390
- parentSelectionSet : GraphQLParser .SelectionSetContext ,
391
- parentSchemaType : Schema .Type
390
+ parentSchemaType : Schema .Type ,
391
+ parentFields : ParseResult <List <Field >>
392
+
392
393
): ParseResult <InlineFragment > {
393
394
val typeCondition = typeCondition().typeName().NAME ().text
394
395
val schemaType = schema[typeCondition] ? : throw ParseException (
395
396
message = " Unknown type`$typeCondition }`" ,
396
397
token = typeCondition().typeName().start
397
398
)
398
399
399
- if (! parentSchemaType.isAssignableFrom(schema = schema, other = schemaType )) {
400
+ if (! parentSchemaType.isAssignableFrom(other = schemaType, schema = schema )) {
400
401
throw ParseException (
401
- message = " Fragment cannot be spread here as objects of type ` ${parentSchemaType.name} ` can never be of type `$typeCondition `" ,
402
+ message = " Fragment cannot be spread here as result can never be of type `$typeCondition `" ,
402
403
token = typeCondition().typeName().start
403
404
)
404
405
}
405
406
406
- val possibleTypes = when (schemaType) {
407
- is Schema .Type .Interface -> schemaType.possibleTypes?.map { it.rawType.name!! } ? : emptyList()
408
- is Schema .Type .Union -> schemaType.possibleTypes?.map { it.rawType.name!! } ? : emptyList()
409
- else -> listOf (typeCondition)
410
- }.distinct()
407
+ val decoratedParentFields = parentFields.let { (parentFields, usedTypes) ->
408
+ // if inline fragment conditional type contains the same field as parent type
409
+ // carry over meta info such as: `description`, `isDeprecated`, `deprecationReason`
410
+ val decoratedFields = parentFields.map { parentField ->
411
+ when (schemaType) {
412
+ is Schema .Type .Interface -> schemaType.fields?.find { it.name == parentField.fieldName }
413
+ is Schema .Type .Object -> schemaType.fields?.find { it.name == parentField.fieldName }
414
+ is Schema .Type .Union -> schemaType.fields?.find { it.name == parentField.fieldName }
415
+ else -> null
416
+ }?.let { field ->
417
+ parentField.copy(
418
+ description = field.description ? : parentField.description,
419
+ isDeprecated = field.isDeprecated,
420
+ deprecationReason = field.deprecationReason ? : " "
421
+ )
422
+ } ? : parentField
423
+ }
424
+ ParseResult (
425
+ result = decoratedFields,
426
+ usedTypes = usedTypes
427
+ )
428
+ }
411
429
412
- val fields = parentSelectionSet.parse(schemaType).plus(
413
- selectionSet().parse(schemaType)
414
- ) { left, right -> left.union(right) }
430
+ val fields = decoratedParentFields.plus(selectionSet().parse(schemaType)) { left, right -> left.union(right) }
415
431
if (fields.result.isEmpty()) {
416
432
throw ParseException (
417
433
message = " Inline fragment `$typeCondition ` must have a selection of sub-fields" ,
418
434
token = typeCondition().typeName().NAME ().symbol
419
435
)
420
436
}
421
437
438
+ val possibleTypes = schemaType.possibleTypes(schema).toList()
422
439
return ParseResult (
423
440
result = InlineFragment (
424
441
typeCondition = typeCondition,
@@ -449,12 +466,7 @@ class GraphQLDocumentParser(val schema: Schema, private val packageNameProvider:
449
466
token = typeCondition().typeName().NAME ().symbol
450
467
)
451
468
452
- val possibleTypes = when (schemaType) {
453
- is Schema .Type .Interface -> schemaType.possibleTypes?.map { it.rawType.name!! } ? : emptyList()
454
- is Schema .Type .Union -> schemaType.possibleTypes?.map { it.rawType.name!! } ? : emptyList()
455
- else -> listOf (typeCondition)
456
- }.distinct()
457
-
469
+ val possibleTypes = schemaType.possibleTypes(schema)
458
470
val fields = selectionSet().parse(schemaType)
459
471
if (fields.result.isEmpty()) {
460
472
throw ParseException (
@@ -466,7 +478,7 @@ class GraphQLDocumentParser(val schema: Schema, private val packageNameProvider:
466
478
val fragmentRefs = selectionSet().fragmentRefs()
467
479
468
480
val inlineFragments = selectionSet()?.selection()?.mapNotNull { ctx ->
469
- ctx.inlineFragment()?.parse(parentSelectionSet = selectionSet(), parentSchemaType = schemaType )
481
+ ctx.inlineFragment()?.parse(parentSchemaType = schemaType, parentFields = fields )
470
482
}?.flatten() ? : ParseResult (result = emptyList())
471
483
472
484
val mergeInlineFragmentFields = inlineFragments.result
@@ -482,7 +494,7 @@ class GraphQLDocumentParser(val schema: Schema, private val packageNameProvider:
482
494
fragmentName = fragmentName,
483
495
typeCondition = typeCondition,
484
496
source = graphQLDocumentSource,
485
- possibleTypes = possibleTypes,
497
+ possibleTypes = possibleTypes.toList() ,
486
498
fields = fields.result.mergeFields(mergeInlineFragmentFields),
487
499
fragmentRefs = fragmentRefs.union(mergeInlineFragmentRefs).toList(),
488
500
inlineFragments = inlineFragments.result.filter { it.typeCondition != typeCondition },
@@ -744,8 +756,7 @@ class GraphQLDocumentParser(val schema: Schema, private val packageNameProvider:
744
756
}.also { possibleTypes ->
745
757
if (fragment.possibleTypes.intersect(possibleTypes).isEmpty()) {
746
758
throw GraphQLDocumentParseException (
747
- message = " Fragment `${ref.name} ` can't be spread here as objects of type `$typeCondition ` can never be of " +
748
- " type `${fragment.typeCondition} `" ,
759
+ message = " Fragment `${ref.name} ` can't be spread here as result can never be of type `${fragment.typeCondition} `" ,
749
760
sourceLocation = ref.sourceLocation,
750
761
graphQLFilePath = filePath
751
762
)
0 commit comments