@@ -192,6 +192,7 @@ function findConflictsWithinSelectionSet(
192
192
) ;
193
193
194
194
if ( fragmentNames . length !== 0 ) {
195
+ const discoveredFragments : Array < [ string , string ] > = [ ] ;
195
196
// (B) Then collect conflicts between these fields and those represented by
196
197
// each spread fragment name found.
197
198
for ( let i = 0 ; i < fragmentNames . length ; i ++ ) {
@@ -203,7 +204,29 @@ function findConflictsWithinSelectionSet(
203
204
false ,
204
205
fieldMap ,
205
206
fragmentNames [ i ] ,
207
+ discoveredFragments ,
206
208
) ;
209
+
210
+ // (E) Then collect any conflicts between the provided collection of fields
211
+ // and any fragment names found in the given fragment.
212
+ while ( discoveredFragments . length !== 0 ) {
213
+ const item = discoveredFragments . pop ( ) ;
214
+ if ( ! item || comparedFragmentPairs . has ( item [ 1 ] , item [ 0 ] , false ) ) {
215
+ continue ;
216
+ }
217
+ const [ fragmentName , referencedFragmentName ] = item ;
218
+ comparedFragmentPairs . add ( referencedFragmentName , fragmentName , false ) ;
219
+ collectConflictsBetweenFieldsAndFragment (
220
+ context ,
221
+ conflicts ,
222
+ cachedFieldsAndFragmentNames ,
223
+ comparedFragmentPairs ,
224
+ false ,
225
+ fieldMap ,
226
+ fragmentName ,
227
+ discoveredFragments ,
228
+ ) ;
229
+ }
207
230
// (C) Then compare this fragment with all other fragments found in this
208
231
// selection set to collect conflicts between fragments spread together.
209
232
// This compares each item in the list of fragment names to every other
@@ -234,6 +257,7 @@ function collectConflictsBetweenFieldsAndFragment(
234
257
areMutuallyExclusive : boolean ,
235
258
fieldMap : NodeAndDefCollection ,
236
259
fragmentName : string ,
260
+ discoveredFragments : Array < Array < string > > ,
237
261
) : void {
238
262
const fragment = context . getFragment ( fragmentName ) ;
239
263
if ( ! fragment ) {
@@ -264,35 +288,12 @@ function collectConflictsBetweenFieldsAndFragment(
264
288
fieldMap2 ,
265
289
) ;
266
290
267
- // (E) Then collect any conflicts between the provided collection of fields
268
- // and any fragment names found in the given fragment.
269
- for ( const referencedFragmentName of referencedFragmentNames ) {
270
- // Memoize so two fragments are not compared for conflicts more than once.
271
- if (
272
- comparedFragmentPairs . has (
273
- referencedFragmentName ,
274
- fragmentName ,
275
- areMutuallyExclusive ,
276
- )
277
- ) {
278
- continue ;
279
- }
280
- comparedFragmentPairs . add (
281
- referencedFragmentName ,
291
+ discoveredFragments . push (
292
+ ...referencedFragmentNames . map ( ( referencedFragmentName ) => [
282
293
fragmentName ,
283
- areMutuallyExclusive ,
284
- ) ;
285
-
286
- collectConflictsBetweenFieldsAndFragment (
287
- context ,
288
- conflicts ,
289
- cachedFieldsAndFragmentNames ,
290
- comparedFragmentPairs ,
291
- areMutuallyExclusive ,
292
- fieldMap ,
293
294
referencedFragmentName ,
294
- ) ;
295
- }
295
+ ] ) ,
296
+ ) ;
296
297
}
297
298
298
299
// Collect all conflicts found between two fragments, including via spreading in
@@ -433,6 +434,7 @@ function findConflictsBetweenSubSelectionSets(
433
434
areMutuallyExclusive ,
434
435
fieldMap1 ,
435
436
fragmentName2 ,
437
+ [ ] ,
436
438
) ;
437
439
}
438
440
@@ -447,6 +449,7 @@ function findConflictsBetweenSubSelectionSets(
447
449
areMutuallyExclusive ,
448
450
fieldMap2 ,
449
451
fragmentName1 ,
452
+ [ ] ,
450
453
) ;
451
454
}
452
455
0 commit comments