diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php b/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php index aabc5b71d6cab..cb0c58894c811 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/DefinitionErrorExceptionPass.php @@ -26,7 +26,6 @@ class DefinitionErrorExceptionPass extends AbstractRecursivePass { private $erroredDefinitions = []; - private $targetReferences = []; private $sourceReferences = []; /** @@ -37,45 +36,10 @@ public function process(ContainerBuilder $container) try { parent::process($container); - if (!$this->erroredDefinitions) { - return; - } - - $runtimeIds = []; - - foreach ($this->sourceReferences as $id => $sourceIds) { - foreach ($sourceIds as $sourceId => $isRuntime) { - if (!$isRuntime) { - continue 2; - } - } - - unset($this->erroredDefinitions[$id]); - $runtimeIds[$id] = $id; - } - - if (!$this->erroredDefinitions) { - return; - } - - foreach ($this->targetReferences as $id => $targetIds) { - if (!isset($this->sourceReferences[$id]) || isset($runtimeIds[$id]) || isset($this->erroredDefinitions[$id])) { - continue; - } - foreach ($this->targetReferences[$id] as $targetId => $isRuntime) { - foreach ($this->sourceReferences[$id] as $sourceId => $isRuntime) { - if ($sourceId !== $targetId) { - $this->sourceReferences[$targetId][$sourceId] = false; - $this->targetReferences[$sourceId][$targetId] = false; - } - } - } - - unset($this->sourceReferences[$id]); - } + $visitedIds = []; foreach ($this->erroredDefinitions as $id => $definition) { - if (isset($this->sourceReferences[$id])) { + if ($this->isErrorForRuntime($id, $visitedIds)) { continue; } @@ -86,7 +50,6 @@ public function process(ContainerBuilder $container) } } finally { $this->erroredDefinitions = []; - $this->targetReferences = []; $this->sourceReferences = []; } } @@ -105,10 +68,8 @@ protected function processValue($value, bool $isRoot = false) if ($value instanceof Reference && $this->currentId !== $targetId = (string) $value) { if (ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior()) { $this->sourceReferences[$targetId][$this->currentId] ?? $this->sourceReferences[$targetId][$this->currentId] = true; - $this->targetReferences[$this->currentId][$targetId] ?? $this->targetReferences[$this->currentId][$targetId] = true; } else { $this->sourceReferences[$targetId][$this->currentId] = false; - $this->targetReferences[$this->currentId][$targetId] = false; } return $value; @@ -122,4 +83,29 @@ protected function processValue($value, bool $isRoot = false) return parent::processValue($value); } + + private function isErrorForRuntime(string $id, array &$visitedIds): bool + { + if (!isset($this->sourceReferences[$id])) { + return false; + } + + if (isset($visitedIds[$id])) { + return $visitedIds[$id]; + } + + $visitedIds[$id] = true; + + foreach ($this->sourceReferences[$id] as $sourceId => $isRuntime) { + if ($visitedIds[$sourceId] ?? $visitedIds[$sourceId] = $this->isErrorForRuntime($sourceId, $visitedIds)) { + continue; + } + + if (!$isRuntime) { + return false; + } + } + + return true; + } }