private Conflict findConflict()

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;
  }