public function __invoke(ValidationContext $context)
{
// Gather all the fragment spreads ASTs for each fragment definition.
// Importantly this does not include inline fragments.
$definitions = $context->getDocument()->definitions;
$spreadsInFragment = [];
foreach ($definitions as $node) {
if ($node instanceof FragmentDefinition) {
$spreadsInFragment[$node->name->value] = $this->gatherSpreads($node);
}
}
// Tracks spreads known to lead to cycles to ensure that cycles are not
// redundantly reported.
$knownToLeadToCycle = new \SplObjectStorage();
return [Node::FRAGMENT_DEFINITION => function (FragmentDefinition $node) use($spreadsInFragment, $knownToLeadToCycle) {
$errors = [];
$initialName = $node->name->value;
// Array of AST nodes used to produce meaningful errors
$spreadPath = [];
$this->detectCycleRecursive($initialName, $spreadsInFragment, $knownToLeadToCycle, $initialName, $spreadPath, $errors);
if (!empty($errors)) {
return $errors;
}
}];
}