@@ -112,7 +112,8 @@ public void visitSelectionSetOfOperationDefinition(OperationDefinition operation
112112 Map <String , Map <GraphQLObjectType , NormalizedField >> result = new LinkedHashMap <>(rootField .getChildrenAsMap ());
113113 // we need do set it before as this is accessed in visitSelectionSet
114114 rootField .setChildren (result );
115- visitSelectionSetImpl (operationDefinition .getSelectionSet (), result , possibleObjects , level , rootField , rootType );
115+ List <String > queryPath = new ArrayList <>();
116+ visitSelectionSetImpl (operationDefinition .getSelectionSet (), result , possibleObjects , level , rootField , rootType , queryPath );
116117 }
117118
118119 // This traverses the selection set of
@@ -137,6 +138,7 @@ public void visitSelectionSetOfField(Field field) {
137138 }
138139 GraphQLCompositeType astParentType = (GraphQLCompositeType ) fieldDef .getType ();
139140
141+ List <String > queryPath = new ArrayList <>(validationContext .getQueryPath ());
140142
141143 List <NormalizedField > parentNormalizedFields = fieldToNormalizedField .get (field );
142144 if (parentNormalizedFields == null ) {
@@ -148,7 +150,13 @@ public void visitSelectionSetOfField(Field field) {
148150 Set <GraphQLObjectType > possibleObjects = new LinkedHashSet <>(resolvePossibleObjects ((GraphQLCompositeType ) fieldType ));
149151 Map <String , Map <GraphQLObjectType , NormalizedField >> result = new LinkedHashMap <>(parentNormalizedField .getChildrenAsMap ());
150152
151- visitSelectionSetImpl (field .getSelectionSet (), result , possibleObjects , level , parentNormalizedField , astParentType );
153+ visitSelectionSetImpl (field .getSelectionSet (),
154+ result ,
155+ possibleObjects ,
156+ level ,
157+ parentNormalizedField ,
158+ astParentType ,
159+ queryPath );
152160 parentNormalizedField .replaceChildren (result );
153161 }
154162 // this means this field a top level field
@@ -161,17 +169,18 @@ private void visitSelectionSetImpl(SelectionSet selectionSet,
161169 Set <GraphQLObjectType > possibleObjects ,
162170 int level ,
163171 NormalizedField parentNormalizedField ,
164- GraphQLCompositeType astParentType
172+ GraphQLCompositeType astParentType ,
173+ List <String > queryPath
165174 ) {
166175
167176
168177 for (Selection selection : selectionSet .getSelections ()) {
169178 if (selection instanceof Field ) {
170- visitField ((Field ) selection , result , possibleObjects , level , parentNormalizedField , astParentType );
179+ visitField ((Field ) selection , result , possibleObjects , level , parentNormalizedField , astParentType , queryPath );
171180 } else if (selection instanceof InlineFragment ) {
172- visitInlineFragment ((InlineFragment ) selection , result , possibleObjects , level , parentNormalizedField , astParentType );
181+ visitInlineFragment ((InlineFragment ) selection , result , possibleObjects , level , parentNormalizedField , astParentType , queryPath );
173182 } else if (selection instanceof FragmentSpread ) {
174- visitFragmentSpread ((FragmentSpread ) selection , result , possibleObjects , level , parentNormalizedField , astParentType );
183+ visitFragmentSpread ((FragmentSpread ) selection , result , possibleObjects , level , parentNormalizedField , astParentType , queryPath );
175184 }
176185 }
177186 }
@@ -181,7 +190,8 @@ private void visitFragmentSpread(FragmentSpread fragmentSpread,
181190 Set <GraphQLObjectType > possibleObjects ,
182191 int level ,
183192 NormalizedField parentNormalizedField ,
184- GraphQLCompositeType astParentType ) {
193+ GraphQLCompositeType astParentType ,
194+ List <String > queryPath ) {
185195 FragmentDefinition fragmentDefinition = fragmentsByName .get (fragmentSpread .getName ());
186196 if (fragmentDefinition == null ) {
187197 return ;
@@ -192,15 +202,17 @@ private void visitFragmentSpread(FragmentSpread fragmentSpread,
192202 return ;
193203 }
194204 Set <GraphQLObjectType > newPossibleObjects = narrowDownPossibleObjects (possibleObjects , newParentType );
195- visitSelectionSetImpl (fragmentDefinition .getSelectionSet (), result , newPossibleObjects , level , parentNormalizedField , newParentType );
205+ queryPath .add (fragmentDefinition .getName ());
206+ visitSelectionSetImpl (fragmentDefinition .getSelectionSet (), result , newPossibleObjects , level , parentNormalizedField , newParentType , queryPath );
196207 }
197208
198209 private void visitInlineFragment (InlineFragment inlineFragment ,
199210 Map <String , Map <GraphQLObjectType , NormalizedField >> result ,
200211 Set <GraphQLObjectType > possibleObjects ,
201212 int level ,
202213 NormalizedField parentNormalizedField ,
203- GraphQLCompositeType astParentType ) {
214+ GraphQLCompositeType astParentType ,
215+ List <String > queryPath ) {
204216 Set <GraphQLObjectType > newPossibleObjects = possibleObjects ;
205217
206218 GraphQLCompositeType newParentType = astParentType ;
@@ -213,20 +225,23 @@ private void visitInlineFragment(InlineFragment inlineFragment,
213225 newParentType = newCondition ;
214226 newPossibleObjects = narrowDownPossibleObjects (possibleObjects , newCondition );
215227 }
216- visitSelectionSetImpl (inlineFragment .getSelectionSet (), result , newPossibleObjects , level , parentNormalizedField , newParentType );
228+ visitSelectionSetImpl (inlineFragment .getSelectionSet (), result , newPossibleObjects , level , parentNormalizedField , newParentType , queryPath );
217229 }
218230
219231 private void visitField (Field field ,
220232 Map <String , Map <GraphQLObjectType , NormalizedField >> result ,
221233 Set <GraphQLObjectType > objectTypes ,
222234 int level ,
223235 NormalizedField parentNormalizedField ,
224- GraphQLCompositeType astParentType ) {
236+ GraphQLCompositeType astParentType ,
237+ List <String > queryPath ) {
225238 GraphQLFieldDefinition fieldDef = getFieldDef (astParentType , field );
226239 if (fieldDef == null ) {
227240 return ;
228241 }
229242 String resultKey = field .getResultKey ();
243+ queryPath = new ArrayList <>(queryPath );
244+ // queryPath.add(resultKey);
230245
231246 result .computeIfAbsent (resultKey , ignored -> new LinkedHashMap <>());
232247 Map <GraphQLObjectType , NormalizedField > objectTypeToNormalizedField = result .get (resultKey );
@@ -236,13 +251,14 @@ private void visitField(Field field,
236251 ChildOverlappingState childOverlappingState = astParentType instanceof GraphQLObjectType ? UNDECIDED_OBJECTS : SAME_FIELD ;
237252 parentNormalizedField .updateChildOverlappingState (resultKey , childOverlappingState );
238253 }
254+ // we need to check here bases on the resultKey, not only matching object types!
239255 for (GraphQLObjectType objectType : objectTypes ) {
240256
241257 if (objectTypeToNormalizedField .containsKey (objectType )) {
242258 NormalizedField existingChild = objectTypeToNormalizedField .get (objectType );
243259 Conflict conflict = checkIfFieldIsCompatible (field , astParentType , fieldDef .getType (), existingChild , parentNormalizedField );
244260 if (conflict != null ) {
245- addError (FieldsConflict , conflict .fields , conflict .reason );
261+ addError (FieldsConflict , conflict .fields , conflict .reason , queryPath );
246262 continue ;
247263 }
248264
@@ -378,7 +394,7 @@ private Conflict checkExactlySameField(String resultKey, Field fieldA, Field fie
378394 String fieldNameB = fieldB .getName ();
379395 if (!fieldNameA .equals (fieldNameB )) {
380396 String reason = format ("%s: %s and %s are different fields" , resultKey , fieldNameB , fieldNameA );
381- return new Conflict (resultKey , reason , fieldA , fieldB );
397+ return new Conflict (resultKey , reason , fieldB , fieldA );
382398 }
383399 if (!sameType (typeA , typeB )) {
384400 return mkNotSameTypeError (resultKey , fieldA , fieldB , typeA , typeB );
@@ -545,15 +561,20 @@ private GraphQLFieldDefinition getFieldDef(GraphQLType parentType, Field field)
545561 return null ;
546562 }
547563
548- public void addError (ValidationErrorType validationErrorType , List <? extends Node <?>> locations , String description ) {
564+ public void addError (ValidationErrorType validationErrorType ,
565+ List <? extends Node <?>> locations ,
566+ String description ,
567+ List <String > queryPath ) {
549568 List <SourceLocation > locationList = new ArrayList <>();
550569 for (Node <?> node : locations ) {
551570 locationList .add (node .getSourceLocation ());
552571 }
553572 addError (newValidationError ()
554573 .validationErrorType (validationErrorType )
555574 .sourceLocations (locationList )
556- .description (description ));
575+ .description (description )
576+ .queryPath (queryPath )
577+ );
557578 }
558579
559580 public void addError (ValidationErrorType validationErrorType , SourceLocation location , String description ) {
@@ -564,7 +585,7 @@ public void addError(ValidationErrorType validationErrorType, SourceLocation loc
564585 }
565586
566587 public void addError (ValidationError .Builder validationError ) {
567- validationErrorCollector .addError (validationError .queryPath ( validationContext . getQueryPath ()). build ());
588+ validationErrorCollector .addError (validationError .build ());
568589 }
569590
570591
0 commit comments