src/Validator/Rules/OverlappingFieldsCanBeMerged.php
private function findConflictsBetweenSubSelectionSets(
        ValidationContext $context,
        $areMutuallyExclusive,
        $parentType1,
        SelectionSetNode $selectionSet1,
        $parentType2,
        SelectionSetNode $selectionSet2
    ) {
        $conflicts = [];

        [$fieldMap1, $fragmentNames1] = $this->getFieldsAndFragmentNames(
            $context,
            $parentType1,
            $selectionSet1
        );
        [$fieldMap2, $fragmentNames2] = $this->getFieldsAndFragmentNames(
            $context,
            $parentType2,
            $selectionSet2
        );

        // (H) First, collect all conflicts between these two collections of field.
        $this->collectConflictsBetween(
            $context,
            $conflicts,
            $areMutuallyExclusive,
            $fieldMap1,
            $fieldMap2
        );

        // (I) Then collect conflicts between the first collection of fields and
        // those referenced by each fragment name associated with the second.
        $fragmentNames2Length = count($fragmentNames2);
        if ($fragmentNames2Length !== 0) {
            $comparedFragments = [];
            for ($j = 0; $j < $fragmentNames2Length; $j++) {
                $this->collectConflictsBetweenFieldsAndFragment(
                    $context,
                    $conflicts,
                    $comparedFragments,
                    $areMutuallyExclusive,
                    $fieldMap1,
                    $fragmentNames2[$j]
                );
            }
        }

        // (I) Then collect conflicts between the second collection of fields and
        // those referenced by each fragment name associated with the first.
        $fragmentNames1Length = count($fragmentNames1);
        if ($fragmentNames1Length !== 0) {
            $comparedFragments = [];
            for ($i = 0; $i < $fragmentNames1Length; $i++) {
                $this->collectConflictsBetweenFieldsAndFragment(
                    $context,
                    $conflicts,
                    $comparedFragments,
                    $areMutuallyExclusive,
                    $fieldMap2,
                    $fragmentNames1[$i]
                );
            }
        }

        // (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 ($i = 0; $i < $fragmentNames1Length; $i++) {
            for ($j = 0; $j < $fragmentNames2Length; $j++) {
                $this->collectConflictsBetweenFragments(
                    $context,
                    $conflicts,
                    $areMutuallyExclusive,
                    $fragmentNames1[$i],
                    $fragmentNames2[$j]
                );
            }
        }

        return $conflicts;
    }
private function findConflictsBetweenSubSelectionSets(
        ValidationContext $context,
        $areMutuallyExclusive,
        $parentType1,
        SelectionSetNode $selectionSet1,
        $parentType2,
        SelectionSetNode $selectionSet2
    ) {
        $conflicts = [];

        [$fieldMap1, $fragmentNames1] = $this->getFieldsAndFragmentNames(
            $context,
            $parentType1,
            $selectionSet1
        );
        [$fieldMap2, $fragmentNames2] = $this->getFieldsAndFragmentNames(
            $context,
            $parentType2,
            $selectionSet2
        );

        // (H) First, collect all conflicts between these two collections of field.
        $this->collectConflictsBetween(
            $context,
            $conflicts,
            $areMutuallyExclusive,
            $fieldMap1,
            $fieldMap2
        );

        // (I) Then collect conflicts between the first collection of fields and
        // those referenced by each fragment name associated with the second.
        $fragmentNames2Length = count($fragmentNames2);
        if ($fragmentNames2Length !== 0) {
            $comparedFragments = [];
            for ($j = 0; $j < $fragmentNames2Length; $j++) {
                $this->collectConflictsBetweenFieldsAndFragment(
                    $context,
                    $conflicts,
                    $comparedFragments,
                    $areMutuallyExclusive,
                    $fieldMap1,
                    $fragmentNames2[$j]
                );
            }
        }

        // (I) Then collect conflicts between the second collection of fields and
        // those referenced by each fragment name associated with the first.
        $fragmentNames1Length = count($fragmentNames1);
        if ($fragmentNames1Length !== 0) {
            $comparedFragments = [];
            for ($i = 0; $i < $fragmentNames1Length; $i++) {
                $this->collectConflictsBetweenFieldsAndFragment(
                    $context,
                    $conflicts,
                    $comparedFragments,
                    $areMutuallyExclusive,
                    $fieldMap2,
                    $fragmentNames1[$i]
                );
            }
        }

        // (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 ($i = 0; $i < $fragmentNames1Length; $i++) {
            for ($j = 0; $j < $fragmentNames2Length; $j++) {
                $this->collectConflictsBetweenFragments(
                    $context,
                    $conflicts,
                    $areMutuallyExclusive,
                    $fragmentNames1[$i],
                    $fragmentNames2[$j]
                );
            }
        }

        return $conflicts;
    }
Find all conflicts found between two selection sets, including those found
via spreading in fragments. Called when determining if conflicts exist
between the sub-fields of two overlapping fields.

@param bool          $areMutuallyExclusive
@param CompositeType $parentType1
@param CompositeType $parentType2

@return mixed[][]