diff --git a/src/validation/rules/OverlappingFieldsCanBeMergedRule.ts b/src/validation/rules/OverlappingFieldsCanBeMergedRule.ts index 466326a2ce6..9d70dd28142 100644 --- a/src/validation/rules/OverlappingFieldsCanBeMergedRule.ts +++ b/src/validation/rules/OverlappingFieldsCanBeMergedRule.ts @@ -207,26 +207,15 @@ function findConflictsWithinSelectionSet( discoveredFragments, ); - // (E) Then collect any conflicts between the provided collection of fields - // and any fragment names found in the given fragment. - while (discoveredFragments.length !== 0) { - const item = discoveredFragments.pop(); - if (!item || comparedFragmentPairs.has(item[1], item[0], false)) { - continue; - } - const [fragmentName, referencedFragmentName] = item; - comparedFragmentPairs.add(referencedFragmentName, fragmentName, false); - collectConflictsBetweenFieldsAndFragment( - context, - conflicts, - cachedFieldsAndFragmentNames, - comparedFragmentPairs, - false, - fieldMap, - referencedFragmentName, - discoveredFragments, - ); - } + processDiscoveredFragments( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFragmentPairs, + false, + fieldMap, + discoveredFragments, + ) // (C) Then compare this fragment with all other fragments found in this // selection set to collect conflicts between fragments spread together. // This compares each item in the list of fragment names to every other @@ -439,33 +428,15 @@ function findConflictsBetweenSubSelectionSets( ); } - // (E) Then collect any conflicts between the provided collection of fields - // and any fragment names found in the given fragment. - while (discoveredFragments.length !== 0) { - const item = discoveredFragments.pop(); - if ( - !item || - comparedFragmentPairs.has(item[1], item[0], areMutuallyExclusive) - ) { - continue; - } - const [fragmentName, referencedFragmentName] = item; - comparedFragmentPairs.add( - referencedFragmentName, - fragmentName, - areMutuallyExclusive, - ); - collectConflictsBetweenFieldsAndFragment( - context, - conflicts, - cachedFieldsAndFragmentNames, - comparedFragmentPairs, - areMutuallyExclusive, - fieldMap1, - referencedFragmentName, - discoveredFragments, - ); - } + processDiscoveredFragments( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFragmentPairs, + areMutuallyExclusive, + fieldMap1, + discoveredFragments, + ) // (I) Then collect conflicts between the second collection of fields and // those referenced by each fragment name associated with the first. @@ -482,8 +453,46 @@ function findConflictsBetweenSubSelectionSets( ); } - // (E) Then collect any conflicts between the provided collection of fields - // and any fragment names found in the given fragment. + processDiscoveredFragments( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFragmentPairs, + areMutuallyExclusive, + fieldMap2, + discoveredFragments, + ) + + // (J) Also collect conflicts between any fragment names by the first and + // fragment names by the second. This compares each item in the first set of + // names to each item in the second set of names. + for (const fragmentName1 of fragmentNames1) { + for (const fragmentName2 of fragmentNames2) { + collectConflictsBetweenFragments( + context, + conflicts, + cachedFieldsAndFragmentNames, + comparedFragmentPairs, + areMutuallyExclusive, + fragmentName1, + fragmentName2, + ); + } + } + return conflicts; +} + +// (E) Then collect any conflicts between the provided collection of fields +// and any fragment names found in the given fragment. +const processDiscoveredFragments = ( + context: ValidationContext, + conflicts: Array, + cachedFieldsAndFragmentNames: Map, + comparedFragmentPairs: PairSet, + areMutuallyExclusive: boolean, + fieldMap: NodeAndDefCollection, + discoveredFragments: Array>, +) => { while (discoveredFragments.length !== 0) { const item = discoveredFragments.pop(); if ( @@ -504,29 +513,11 @@ function findConflictsBetweenSubSelectionSets( cachedFieldsAndFragmentNames, comparedFragmentPairs, areMutuallyExclusive, - fieldMap2, + fieldMap, referencedFragmentName, discoveredFragments, ); } - - // (J) Also collect conflicts between any fragment names by the first and - // fragment names by the second. This compares each item in the first set of - // names to each item in the second set of names. - for (const fragmentName1 of fragmentNames1) { - for (const fragmentName2 of fragmentNames2) { - collectConflictsBetweenFragments( - context, - conflicts, - cachedFieldsAndFragmentNames, - comparedFragmentPairs, - areMutuallyExclusive, - fragmentName1, - fragmentName2, - ); - } - } - return conflicts; } // Collect all Conflicts "within" one collection of fields.