in src/main/com/intellij/lang/jsgraphql/types/validation/rules/OverlappingFieldsCanBeMerged.java [88:161]
private Conflict findConflict(String responseName, FieldAndType fieldAndTypeA, FieldAndType fieldAndTypeB) {
Field fieldA = fieldAndTypeA.field;
Field fieldB = fieldAndTypeB.field;
if (isAlreadyChecked(fieldA, fieldB)) {
return null;
}
alreadyChecked.add(new FieldPair(fieldA, fieldB));
String fieldNameA = fieldA.getName();
String fieldNameB = fieldB.getName();
GraphQLType typeA = fieldAndTypeA.graphQLType;
GraphQLType typeB = fieldAndTypeB.graphQLType;
Conflict conflict = checkListAndNonNullConflict(responseName, fieldAndTypeA, fieldAndTypeB);
if (conflict != null) {
return conflict;
}
typeA = unwrapAll(typeA);
typeB = unwrapAll(typeB);
if (checkScalarAndEnumConflict(typeA, typeB)) {
return mkNotSameTypeError(responseName, fieldA, fieldB, typeA, typeB);
}
// If the statically known parent types could not possibly apply at the same
// time, then it is safe to permit them to diverge as they will not present
// any ambiguity by differing.
// It is known that two parent types could never overlap if they are
// different Object types. Interface or Union types might overlap - if not
// in the current state of the schema, then perhaps in some future version,
// thus may not safely diverge.
if (!sameType(fieldAndTypeA.parentType, fieldAndTypeB.parentType) &&
fieldAndTypeA.parentType instanceof GraphQLObjectType &&
fieldAndTypeB.parentType instanceof GraphQLObjectType) {
return null;
}
if (!fieldNameA.equals(fieldNameB)) {
String reason = format("%s: %s and %s are different fields", responseName, fieldNameA, fieldNameB);
return new Conflict(responseName, reason, fieldA, fieldB);
}
if (!sameType(typeA, typeB)) {
return mkNotSameTypeError(responseName, fieldA, fieldB, typeA, typeB);
}
if (!sameArguments(fieldA.getArguments(), fieldB.getArguments())) {
String reason = format("%s: they have differing arguments", responseName);
return new Conflict(responseName, reason, fieldA, fieldB);
}
SelectionSet selectionSet1 = fieldA.getSelectionSet();
SelectionSet selectionSet2 = fieldB.getSelectionSet();
if (selectionSet1 != null && selectionSet2 != null) {
Set<String> visitedFragmentSpreads = new LinkedHashSet<>();
Map<String, List<FieldAndType>> subFieldMap = new LinkedHashMap<>();
collectFields(subFieldMap, selectionSet1, typeA, visitedFragmentSpreads);
collectFields(subFieldMap, selectionSet2, typeB, visitedFragmentSpreads);
List<Conflict> subConflicts = findConflicts(subFieldMap);
if (!subConflicts.isEmpty()) {
String reason = format("%s: %s", responseName, joinReasons(subConflicts));
List<Field> fields = new ArrayList<>();
fields.add(fieldA);
fields.add(fieldB);
fields.addAll(collectFields(subConflicts));
return new Conflict(responseName, reason, fields);
}
}
return null;
}