protected function collectConflictsBetweenFragments(
        ComparisonContext $context,
        string $fragmentNameA,
        string $fragmentNameB,
        bool $areMutuallyExclusive
    ): void {
        // No need to compare a fragment to itself.
        if ($fragmentNameA === $fragmentNameB) {
            return;
        }

        // Memoize so two fragments are not compared for conflicts more than once.
        if ($this->comparedFragmentPairs->has($fragmentNameA, $fragmentNameB, $areMutuallyExclusive)) {
            return;
        }

        $this->comparedFragmentPairs->add($fragmentNameA, $fragmentNameB, $areMutuallyExclusive);

        $fragmentA = $this->getContext()->getFragment($fragmentNameA);
        $fragmentB = $this->getContext()->getFragment($fragmentNameB);

        if (null === $fragmentA || null === $fragmentB) {
            return;
        }

        $contextA = $this->getReferencedFieldsAndFragmentNames($fragmentA);
        $contextB = $this->getReferencedFieldsAndFragmentNames($fragmentB);

        // (F) First, collect all conflicts between these two collections of fields
        // (not including any nested fragments).
        $this->collectConflictsBetween(
            $context,
            $contextA->getFieldMap(),
            $contextB->getFieldMap(),
            $areMutuallyExclusive
        );

        $fragmentNamesB = $contextB->getFragmentNames();

        // (G) Then collect conflicts between the first fragment and any nested
        // fragments spread in the second fragment.
        if (!empty($fragmentNamesB)) {
            $fragmentNamesBCount = \count($fragmentNamesB);

            /** @noinspection ForeachInvariantsInspection */
            for ($j = 0; $j < $fragmentNamesBCount; $j++) {
                $this->collectConflictsBetweenFragments(
                    $context,
                    $fragmentNameA,
                    $fragmentNamesB[$j],
                    $areMutuallyExclusive
                );
            }
        }

        $fragmentNamesA = $contextA->getFragmentNames();

        // (G) Then collect conflicts between the second fragment and any nested
        // fragments spread in the first fragment.
        if (!empty($fragmentNamesA)) {
            $fragmentNamesACount = \count($fragmentNamesA);

            /** @noinspection ForeachInvariantsInspection */
            for ($i = 0; $i < $fragmentNamesACount; $i++) {
                $this->collectConflictsBetweenFragments(
                    $context,
                    $fragmentNamesA[$i],
                    $fragmentNameB,
                    $areMutuallyExclusive
                );
            }
        }
    }
protected function collectConflictsBetweenFragments(
        ComparisonContext $context,
        string $fragmentNameA,
        string $fragmentNameB,
        bool $areMutuallyExclusive
    ): void {
        // No need to compare a fragment to itself.
        if ($fragmentNameA === $fragmentNameB) {
            return;
        }

        // Memoize so two fragments are not compared for conflicts more than once.
        if ($this->comparedFragmentPairs->has($fragmentNameA, $fragmentNameB, $areMutuallyExclusive)) {
            return;
        }

        $this->comparedFragmentPairs->add($fragmentNameA, $fragmentNameB, $areMutuallyExclusive);

        $fragmentA = $this->getContext()->getFragment($fragmentNameA);
        $fragmentB = $this->getContext()->getFragment($fragmentNameB);

        if (null === $fragmentA || null === $fragmentB) {
            return;
        }

        $contextA = $this->getReferencedFieldsAndFragmentNames($fragmentA);
        $contextB = $this->getReferencedFieldsAndFragmentNames($fragmentB);

        // (F) First, collect all conflicts between these two collections of fields
        // (not including any nested fragments).
        $this->collectConflictsBetween(
            $context,
            $contextA->getFieldMap(),
            $contextB->getFieldMap(),
            $areMutuallyExclusive
        );

        $fragmentNamesB = $contextB->getFragmentNames();

        // (G) Then collect conflicts between the first fragment and any nested
        // fragments spread in the second fragment.
        if (!empty($fragmentNamesB)) {
            $fragmentNamesBCount = \count($fragmentNamesB);

            /** @noinspection ForeachInvariantsInspection */
            for ($j = 0; $j < $fragmentNamesBCount; $j++) {
                $this->collectConflictsBetweenFragments(
                    $context,
                    $fragmentNameA,
                    $fragmentNamesB[$j],
                    $areMutuallyExclusive
                );
            }
        }

        $fragmentNamesA = $contextA->getFragmentNames();

        // (G) Then collect conflicts between the second fragment and any nested
        // fragments spread in the first fragment.
        if (!empty($fragmentNamesA)) {
            $fragmentNamesACount = \count($fragmentNamesA);

            /** @noinspection ForeachInvariantsInspection */
            for ($i = 0; $i < $fragmentNamesACount; $i++) {
                $this->collectConflictsBetweenFragments(
                    $context,
                    $fragmentNamesA[$i],
                    $fragmentNameB,
                    $areMutuallyExclusive
                );
            }
        }
    }
protected function collectConflictsBetweenFragments ( ComparisonContext $ context , string $ fragmentNameA , string $ fragmentNameB , bool $ areMutuallyExclusive ) : void { // No need to compare a fragment to itself. if ( $ fragmentNameA === $ fragmentNameB ) { return ; } // Memoize so two fragments are not compared for conflicts more than once. if ( $ this -> comparedFragmentPairs -> has ( $ fragmentNameA , $ fragmentNameB , $ areMutuallyExclusive ) ) { return ; } $ this -> comparedFragmentPairs -> add ( $ fragmentNameA , $ fragmentNameB , $ areMutuallyExclusive ) ; $ fragmentA = $ this -> getContext ( ) -> getFragment ( $ fragmentNameA ) ; $ fragmentB = $ this -> getContext ( ) -> getFragment ( $ fragmentNameB ) ; if ( null === $ fragmentA || null === $ fragmentB ) { return ; } $ contextA = $ this -> getReferencedFieldsAndFragmentNames ( $ fragmentA ) ; $ contextB = $ this -> getReferencedFieldsAndFragmentNames ( $ fragmentB ) ; // (F) First, collect all conflicts between these two collections of fields // (not including any nested fragments). $ this -> collectConflictsBetween ( $ context , $ contextA -> getFieldMap ( ) , $ contextB -> getFieldMap ( ) , $ areMutuallyExclusive ) ; $ fragmentNamesB = $ contextB -> getFragmentNames ( ) ; // (G) Then collect conflicts between the first fragment and any nested // fragments spread in the second fragment. if ( ! empty ( $ fragmentNamesB ) ) { $ fragmentNamesBCount = \ count ( $ fragmentNamesB ) ; /** @noinspection ForeachInvariantsInspection */ for ( $ j = 0 ; $ j < $ fragmentNamesBCount ; $ j ++ ) { $ this -> collectConflictsBetweenFragments ( $ context , $ fragmentNameA , $ fragmentNamesB [ $ j ] , $ areMutuallyExclusive ) ; } } $ fragmentNamesA = $ contextA -> getFragmentNames ( ) ; // (G) Then collect conflicts between the second fragment and any nested // fragments spread in the first fragment. if ( ! empty ( $ fragmentNamesA ) ) { $ fragmentNamesACount = \ count ( $ fragmentNamesA ) ; /** @noinspection ForeachInvariantsInspection */ for ( $ i = 0 ; $ i < $ fragmentNamesACount ; $ i ++ ) { $ this -> collectConflictsBetweenFragments ( $ context , $ fragmentNamesA [ $ i ] , $ fragmentNameB , $ areMutuallyExclusive ) ; } } }
Collect all conflicts found between two fragments, including via spreading in
any nested fragments.

@param ComparisonContext $context
@param string            $fragmentNameA
@param string            $fragmentNameB
@param bool              $areMutuallyExclusive
@throws ConversionException
@throws InvalidTypeException
@throws InvariantException
Collect all conflicts found between two fragments including via spreading in any nested fragments .