function PhpDumper::collectCircularReferences
1 call to PhpDumper::collectCircularReferences()
- PhpDumper::analyzeReferences in vendor/
symfony/ dependency-injection/ Dumper/ PhpDumper.php
File
-
vendor/
symfony/ dependency-injection/ Dumper/ PhpDumper.php, line 439
Class
- PhpDumper
- PhpDumper dumps a service container as a PHP class.
Namespace
Symfony\Component\DependencyInjection\DumperCode
private function collectCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$loops = [], array $path = [], bool $byConstructor = true) : void {
$path[$sourceId] = $byConstructor;
$checkedNodes[$sourceId] = true;
foreach ($edges as $edge) {
$node = $edge->getDestNode();
$id = $node->getId();
if ($sourceId === $id || !$node->getValue() instanceof Definition || $edge->isWeak()) {
continue;
}
if (isset($path[$id])) {
$loop = null;
$loopByConstructor = $edge->isReferencedByConstructor() && !$edge->isLazy();
$pathInLoop = [
$id,
[],
];
foreach ($path as $k => $pathByConstructor) {
if (null !== $loop) {
$loop[] = $k;
$pathInLoop[1][$k] = $pathByConstructor;
$loops[$k][] =& $pathInLoop;
$loopByConstructor = $loopByConstructor && $pathByConstructor;
}
elseif ($k === $id) {
$loop = [];
}
}
$this->addCircularReferences($id, $loop, $loopByConstructor);
}
elseif (!isset($checkedNodes[$id])) {
$this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $loops, $path, $edge->isReferencedByConstructor() && !$edge->isLazy());
}
elseif (isset($loops[$id])) {
// we already had detected loops for this edge
// let's check if we have a common ancestor in one of the detected loops
foreach ($loops[$id] as [
$first,
$loopPath,
]) {
if (!isset($path[$first])) {
continue;
}
// We have a common ancestor, let's fill the current path
$fillPath = null;
foreach ($loopPath as $k => $pathByConstructor) {
if (null !== $fillPath) {
$fillPath[$k] = $pathByConstructor;
}
elseif ($k === $id) {
$fillPath = $path;
$fillPath[$k] = $pathByConstructor;
}
}
// we can now build the loop
$loop = null;
$loopByConstructor = $edge->isReferencedByConstructor() && !$edge->isLazy();
foreach ($fillPath as $k => $pathByConstructor) {
if (null !== $loop) {
$loop[] = $k;
$loopByConstructor = $loopByConstructor && $pathByConstructor;
}
elseif ($k === $first) {
$loop = [];
}
}
$this->addCircularReferences($first, $loop, $loopByConstructor);
break;
}
}
}
unset($path[$sourceId]);
}