@@ -1078,8 +1078,9 @@ func NoUnusedVariablesRule(context *ValidationContext) *ValidationRuleInstance {
1078
1078
}
1079
1079
1080
1080
type fieldDefPair struct {
1081
- Field * ast.Field
1082
- FieldDef * FieldDefinition
1081
+ ParentType Composite
1082
+ Field * ast.Field
1083
+ FieldDef * FieldDefinition
1083
1084
}
1084
1085
1085
1086
func collectFieldASTsAndDefs (context * ValidationContext , parentType Named , selectionSet * ast.SelectionSet , visitedFragmentNames map [string ]bool , astAndDefs map [string ][]* fieldDefPair ) map [string ][]* fieldDefPair {
@@ -1116,10 +1117,18 @@ func collectFieldASTsAndDefs(context *ValidationContext, parentType Named, selec
1116
1117
if ! ok {
1117
1118
astAndDefs [responseName ] = []* fieldDefPair {}
1118
1119
}
1119
- astAndDefs [responseName ] = append (astAndDefs [responseName ], & fieldDefPair {
1120
- Field : selection ,
1121
- FieldDef : fieldDef ,
1122
- })
1120
+ if parentType , ok := parentType .(Composite ); ok {
1121
+ astAndDefs [responseName ] = append (astAndDefs [responseName ], & fieldDefPair {
1122
+ ParentType : parentType ,
1123
+ Field : selection ,
1124
+ FieldDef : fieldDef ,
1125
+ })
1126
+ } else {
1127
+ astAndDefs [responseName ] = append (astAndDefs [responseName ], & fieldDefPair {
1128
+ Field : selection ,
1129
+ FieldDef : fieldDef ,
1130
+ })
1131
+ }
1123
1132
case * ast.InlineFragment :
1124
1133
inlineFragmentType := parentType
1125
1134
if selection .TypeCondition != nil {
@@ -1279,6 +1288,10 @@ func sameValue(value1 ast.Value, value2 ast.Value) bool {
1279
1288
return val1 == val2
1280
1289
}
1281
1290
1291
+ func sameType (typeA , typeB Type ) bool {
1292
+ return fmt .Sprintf ("%v" , typeA ) == fmt .Sprintf ("%v" , typeB )
1293
+ }
1294
+
1282
1295
/**
1283
1296
* OverlappingFieldsCanBeMergedRule
1284
1297
* Overlapping fields can be merged
@@ -1291,15 +1304,38 @@ func OverlappingFieldsCanBeMergedRule(context *ValidationContext) *ValidationRul
1291
1304
1292
1305
comparedSet := newPairSet ()
1293
1306
var findConflicts func (fieldMap map [string ][]* fieldDefPair ) (conflicts []* conflict )
1294
- findConflict := func (responseName string , pair * fieldDefPair , pair2 * fieldDefPair ) * conflict {
1307
+ findConflict := func (responseName string , field * fieldDefPair , field2 * fieldDefPair ) * conflict {
1295
1308
1296
- ast1 := pair .Field
1297
- def1 := pair .FieldDef
1309
+ parentType1 := field .ParentType
1310
+ ast1 := field .Field
1311
+ def1 := field .FieldDef
1298
1312
1299
- ast2 := pair2 .Field
1300
- def2 := pair2 .FieldDef
1313
+ parentType2 := field2 .ParentType
1314
+ ast2 := field2 .Field
1315
+ def2 := field2 .FieldDef
1316
+
1317
+ // Not a pair.
1318
+ if ast1 == ast2 {
1319
+ return nil
1320
+ }
1321
+
1322
+ // If the statically known parent types could not possibly apply at the same
1323
+ // time, then it is safe to permit them to diverge as they will not present
1324
+ // any ambiguity by differing.
1325
+ // It is known that two parent types could never overlap if they are
1326
+ // different Object types. Interface or Union types might overlap - if not
1327
+ // in the current state of the schema, then perhaps in some future version,
1328
+ // thus may not safely diverge.
1329
+ if parentType1 != parentType2 {
1330
+ _ , ok1 := parentType1 .(* Object )
1331
+ _ , ok2 := parentType2 .(* Object )
1332
+ if ok1 && ok2 {
1333
+ return nil
1334
+ }
1335
+ }
1301
1336
1302
- if ast1 == ast2 || comparedSet .Has (ast1 , ast2 ) {
1337
+ // Memoize, do not report the same issue twice.
1338
+ if comparedSet .Has (ast1 , ast2 ) {
1303
1339
return nil
1304
1340
}
1305
1341
comparedSet .Add (ast1 , ast2 )
@@ -1332,7 +1368,7 @@ func OverlappingFieldsCanBeMergedRule(context *ValidationContext) *ValidationRul
1332
1368
type2 = def2 .Type
1333
1369
}
1334
1370
1335
- if type1 != nil && type2 != nil && ! isEqualType (type1 , type2 ) {
1371
+ if type1 != nil && type2 != nil && ! sameType (type1 , type2 ) {
1336
1372
return & conflict {
1337
1373
Reason : conflictReason {
1338
1374
Name : responseName ,
0 commit comments