@@ -62,11 +62,11 @@ export function OverlappingFieldsCanBeMergedRule(
62
62
// A memoization for when fields and a fragment or two fragments are compared
63
63
// "between" each other for conflicts. Comparisons made be made many times,
64
64
// so memoizing this can dramatically improve the performance of this validator.
65
- const comparedFieldsAndFragmentPairs = new PairSet <
65
+ const comparedFieldsAndFragmentPairs = new OrderedPairSet <
66
66
NodeAndDefCollection ,
67
67
string
68
- > ( ( a , _ ) => typeof a === 'string' ) ;
69
- const comparedFragmentPairs = new PairSet < string , string > ( ( a , b ) => a < b ) ;
68
+ > ( ) ;
69
+ const comparedFragmentPairs = new PairSet < string > ( ( a , b ) => a < b ) ;
70
70
71
71
// A cache for the "field map" and list of fragment names found in any given
72
72
// selection set. Selection sets may be asked for this information multiple
@@ -173,8 +173,8 @@ type FieldsAndFragmentNames = readonly [NodeAndDefCollection, FragmentNames];
173
173
function findConflictsWithinSelectionSet (
174
174
context : ValidationContext ,
175
175
cachedFieldsAndFragmentNames : Map < SelectionSetNode , FieldsAndFragmentNames > ,
176
- comparedFieldsAndFragmentPairs : PairSet < NodeAndDefCollection , string > ,
177
- comparedFragmentPairs : PairSet < string , string > ,
176
+ comparedFieldsAndFragmentPairs : OrderedPairSet < NodeAndDefCollection , string > ,
177
+ comparedFragmentPairs : PairSet < string > ,
178
178
parentType : Maybe < GraphQLNamedType > ,
179
179
selectionSet : SelectionSetNode ,
180
180
) : Array < Conflict > {
@@ -239,8 +239,8 @@ function collectConflictsBetweenFieldsAndFragment(
239
239
context : ValidationContext ,
240
240
conflicts : Array < Conflict > ,
241
241
cachedFieldsAndFragmentNames : Map < SelectionSetNode , FieldsAndFragmentNames > ,
242
- comparedFieldsAndFragmentPairs : PairSet < NodeAndDefCollection , string > ,
243
- comparedFragmentPairs : PairSet < string , string > ,
242
+ comparedFieldsAndFragmentPairs : OrderedPairSet < NodeAndDefCollection , string > ,
243
+ comparedFragmentPairs : PairSet < string > ,
244
244
areMutuallyExclusive : boolean ,
245
245
fieldMap : NodeAndDefCollection ,
246
246
fragmentName : string ,
@@ -314,8 +314,8 @@ function collectConflictsBetweenFragments(
314
314
context : ValidationContext ,
315
315
conflicts : Array < Conflict > ,
316
316
cachedFieldsAndFragmentNames : Map < SelectionSetNode , FieldsAndFragmentNames > ,
317
- comparedFieldsAndFragmentPairs : PairSet < NodeAndDefCollection , string > ,
318
- comparedFragmentPairs : PairSet < string , string > ,
317
+ comparedFieldsAndFragmentPairs : OrderedPairSet < NodeAndDefCollection , string > ,
318
+ comparedFragmentPairs : PairSet < string > ,
319
319
areMutuallyExclusive : boolean ,
320
320
fragmentName1 : string ,
321
321
fragmentName2 : string ,
@@ -406,8 +406,8 @@ function collectConflictsBetweenFragments(
406
406
function findConflictsBetweenSubSelectionSets (
407
407
context : ValidationContext ,
408
408
cachedFieldsAndFragmentNames : Map < SelectionSetNode , FieldsAndFragmentNames > ,
409
- comparedFieldsAndFragmentPairs : PairSet < NodeAndDefCollection , string > ,
410
- comparedFragmentPairs : PairSet < string , string > ,
409
+ comparedFieldsAndFragmentPairs : OrderedPairSet < NodeAndDefCollection , string > ,
410
+ comparedFragmentPairs : PairSet < string > ,
411
411
areMutuallyExclusive : boolean ,
412
412
parentType1 : Maybe < GraphQLNamedType > ,
413
413
selectionSet1 : SelectionSetNode ,
@@ -496,8 +496,8 @@ function collectConflictsWithin(
496
496
context : ValidationContext ,
497
497
conflicts : Array < Conflict > ,
498
498
cachedFieldsAndFragmentNames : Map < SelectionSetNode , FieldsAndFragmentNames > ,
499
- comparedFieldsAndFragmentPairs : PairSet < NodeAndDefCollection , string > ,
500
- comparedFragmentPairs : PairSet < string , string > ,
499
+ comparedFieldsAndFragmentPairs : OrderedPairSet < NodeAndDefCollection , string > ,
500
+ comparedFragmentPairs : PairSet < string > ,
501
501
fieldMap : NodeAndDefCollection ,
502
502
) : void {
503
503
// A field map is a keyed collection, where each key represents a response
@@ -539,8 +539,8 @@ function collectConflictsBetween(
539
539
context : ValidationContext ,
540
540
conflicts : Array < Conflict > ,
541
541
cachedFieldsAndFragmentNames : Map < SelectionSetNode , FieldsAndFragmentNames > ,
542
- comparedFieldsAndFragmentPairs : PairSet < NodeAndDefCollection , string > ,
543
- comparedFragmentPairs : PairSet < string , string > ,
542
+ comparedFieldsAndFragmentPairs : OrderedPairSet < NodeAndDefCollection , string > ,
543
+ comparedFragmentPairs : PairSet < string > ,
544
544
parentFieldsAreMutuallyExclusive : boolean ,
545
545
fieldMap1 : NodeAndDefCollection ,
546
546
fieldMap2 : NodeAndDefCollection ,
@@ -579,8 +579,8 @@ function collectConflictsBetween(
579
579
function findConflict (
580
580
context : ValidationContext ,
581
581
cachedFieldsAndFragmentNames : Map < SelectionSetNode , FieldsAndFragmentNames > ,
582
- comparedFieldsAndFragmentPairs : PairSet < NodeAndDefCollection , string > ,
583
- comparedFragmentPairs : PairSet < string , string > ,
582
+ comparedFieldsAndFragmentPairs : OrderedPairSet < NodeAndDefCollection , string > ,
583
+ comparedFragmentPairs : PairSet < string > ,
584
584
parentFieldsAreMutuallyExclusive : boolean ,
585
585
responseName : string ,
586
586
field1 : NodeAndDef ,
@@ -841,44 +841,62 @@ function subfieldConflicts(
841
841
}
842
842
843
843
/**
844
- * A way to keep track of pairs of things when the ordering of the pair does not matter.
844
+ * A way to keep track of pairs of things where the ordering of the pair
845
+ * matters.
846
+ *
847
+ * Provides a third argument for has/set to allow flagging the pair as
848
+ * weakly or strongly present within the collection.
845
849
*/
846
- class PairSet < T , U > {
847
- _data : Map < T | U , Map < T | U , boolean > > ;
848
- _orderer : ( a : T | U , b : T | U ) => [ T | U , T | U ] ;
850
+ class OrderedPairSet < T , U > {
851
+ _data : Map < T , Map < U , boolean > > ;
849
852
850
- constructor ( comparator : ( a : T | U , b : T | U ) => boolean ) {
853
+ constructor ( ) {
851
854
this . _data = new Map ( ) ;
852
- this . _orderer = ( a : T | U , b : T | U ) =>
853
- comparator ( a , b ) ? [ a , b ] : [ b , a ] ;
854
855
}
855
856
856
- has ( a : T , b : U , areMutuallyExclusive : boolean ) : boolean ;
857
- has ( a : U , b : T , areMutuallyExclusive : boolean ) : boolean ;
858
- has ( a : T | U , b : T | U , areMutuallyExclusive : boolean ) : boolean {
859
- const [ key1 , key2 ] = this . _orderer ( a , b ) ;
860
-
861
- const result = this . _data . get ( key1 ) ?. get ( key2 ) ;
857
+ has ( a : T , b : U , weaklyPresent : boolean ) : boolean {
858
+ const result = this . _data . get ( a ) ?. get ( b ) ;
862
859
if ( result === undefined ) {
863
860
return false ;
864
861
}
865
862
866
- // areMutuallyExclusive being false is a superset of being true, hence if
867
- // we want to know if this PairSet "has" these two with no exclusivity,
868
- // we have to ensure it was added as such.
869
- return areMutuallyExclusive ? true : areMutuallyExclusive === result ;
863
+ return weaklyPresent ? true : weaklyPresent === result ;
870
864
}
871
865
872
- add ( a : T , b : U , areMutuallyExclusive : boolean ) : void ;
873
- add ( a : U , b : T , areMutuallyExclusive : boolean ) : void ;
874
- add ( a : T | U , b : T | U , areMutuallyExclusive : boolean ) : void {
875
- const [ key1 , key2 ] = this . _orderer ( a , b ) ;
876
-
877
- const map = this . _data . get ( key1 ) ;
866
+ add ( a : T , b : U , weaklyPresent : boolean ) : void {
867
+ const map = this . _data . get ( a ) ;
878
868
if ( map === undefined ) {
879
- this . _data . set ( key1 , new Map ( [ [ key2 , areMutuallyExclusive ] ] ) ) ;
869
+ this . _data . set ( a , new Map ( [ [ b , weaklyPresent ] ] ) ) ;
870
+ } else {
871
+ map . set ( b , weaklyPresent ) ;
872
+ }
873
+ }
874
+ }
875
+
876
+ /**
877
+ * A way to keep track of pairs of similar things when the ordering of the pair
878
+ * does not matter.
879
+ */
880
+ class PairSet < T > {
881
+ _orderedPairSet : OrderedPairSet < T , T > ;
882
+ _comparator : ( a : T , b : T ) => boolean ;
883
+
884
+ constructor ( comparator : ( a : T , b : T ) => boolean ) {
885
+ this . _orderedPairSet = new OrderedPairSet ( ) ;
886
+ this . _comparator = comparator ;
887
+ }
888
+
889
+ has ( a : T , b : T , weaklyPresent : boolean ) : boolean {
890
+ return this . _comparator ( a , b )
891
+ ? this . _orderedPairSet . has ( a , b , weaklyPresent )
892
+ : this . _orderedPairSet . has ( b , a , weaklyPresent ) ;
893
+ }
894
+
895
+ add ( a : T , b : T , weaklyPresent : boolean ) : void {
896
+ if ( this . _comparator ( a , b ) ) {
897
+ this . _orderedPairSet . add ( a , b , weaklyPresent ) ;
880
898
} else {
881
- map . set ( key2 , areMutuallyExclusive ) ;
899
+ this . _orderedPairSet . add ( b , a , weaklyPresent ) ;
882
900
}
883
901
}
884
902
}
0 commit comments