src/Validator/Rules/OverlappingFieldsCanBeMerged.php
private function collectConflictsBetweenFieldsAndFragment(
        ValidationContext $context,
        array &$conflicts,
        array &$comparedFragments,
        $areMutuallyExclusive,
        array $fieldMap,
        $fragmentName
    ) {
        if (isset($comparedFragments[$fragmentName])) {
            return;
        }
        $comparedFragments[$fragmentName] = true;

        $fragment = $context->getFragment($fragmentName);
        if (! $fragment) {
            return;
        }

        [$fieldMap2, $fragmentNames2] = $this->getReferencedFieldsAndFragmentNames(
            $context,
            $fragment
        );

        if ($fieldMap === $fieldMap2) {
            return;
        }

        // (D) First collect any conflicts between the provided collection of fields
        // and the collection of fields represented by the given fragment.
        $this->collectConflictsBetween(
            $context,
            $conflicts,
            $areMutuallyExclusive,
            $fieldMap,
            $fieldMap2
        );

        // (E) Then collect any conflicts between the provided collection of fields
        // and any fragment names found in the given fragment.
        $fragmentNames2Length = count($fragmentNames2);
        for ($i = 0; $i < $fragmentNames2Length; $i++) {
            $this->collectConflictsBetweenFieldsAndFragment(
                $context,
                $conflicts,
                $comparedFragments,
                $areMutuallyExclusive,
                $fieldMap,
                $fragmentNames2[$i]
            );
        }
    }
private function collectConflictsBetweenFieldsAndFragment(
        ValidationContext $context,
        array &$conflicts,
        array &$comparedFragments,
        $areMutuallyExclusive,
        array $fieldMap,
        $fragmentName
    ) {
        if (isset($comparedFragments[$fragmentName])) {
            return;
        }
        $comparedFragments[$fragmentName] = true;

        $fragment = $context->getFragment($fragmentName);
        if (! $fragment) {
            return;
        }

        [$fieldMap2, $fragmentNames2] = $this->getReferencedFieldsAndFragmentNames(
            $context,
            $fragment
        );

        if ($fieldMap === $fieldMap2) {
            return;
        }

        // (D) First collect any conflicts between the provided collection of fields
        // and the collection of fields represented by the given fragment.
        $this->collectConflictsBetween(
            $context,
            $conflicts,
            $areMutuallyExclusive,
            $fieldMap,
            $fieldMap2
        );

        // (E) Then collect any conflicts between the provided collection of fields
        // and any fragment names found in the given fragment.
        $fragmentNames2Length = count($fragmentNames2);
        for ($i = 0; $i < $fragmentNames2Length; $i++) {
            $this->collectConflictsBetweenFieldsAndFragment(
                $context,
                $conflicts,
                $comparedFragments,
                $areMutuallyExclusive,
                $fieldMap,
                $fragmentNames2[$i]
            );
        }
    }
Collect all conflicts found between a set of fields and a fragment reference
including via spreading in any nested fragments.

@param mixed[][] $conflicts
@param bool[]    $comparedFragments
@param bool      $areMutuallyExclusive
@param mixed[][] $fieldMap
@param string    $fragmentName