diff --git a/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php b/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php index fd3173831..f4d01d8bc 100644 --- a/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php +++ b/Compiler/CheckExceptionOnInvalidReferenceBehaviorPass.php @@ -25,9 +25,6 @@ class CheckExceptionOnInvalidReferenceBehaviorPass extends AbstractRecursivePass { private $serviceLocatorContextIds = []; - /** - * {@inheritdoc} - */ public function process(ContainerBuilder $container) { $this->serviceLocatorContextIds = []; @@ -58,15 +55,7 @@ protected function processValue($value, bool $isRoot = false) if (isset($this->serviceLocatorContextIds[$currentId])) { $currentId = $this->serviceLocatorContextIds[$currentId]; $locator = $this->container->getDefinition($this->currentId)->getFactory()[0]; - - foreach ($locator->getArgument(0) as $k => $v) { - if ($v->getValues()[0] === $value) { - if ($k !== $id) { - $currentId = $k.'" in the container provided to "'.$currentId; - } - throw new ServiceNotFoundException($id, $currentId, null, $this->getAlternatives($id)); - } - } + $this->throwServiceNotFoundException($value, $currentId, $locator->getArgument(0)); } if ('.' === $currentId[0] && $graph->hasNode($currentId)) { @@ -80,14 +69,21 @@ protected function processValue($value, bool $isRoot = false) $currentId = $sourceId; break; } + + if (isset($this->serviceLocatorContextIds[$sourceId])) { + $currentId = $this->serviceLocatorContextIds[$sourceId]; + $locator = $this->container->getDefinition($this->currentId); + $this->throwServiceNotFoundException($value, $currentId, $locator->getArgument(0)); + } } } - throw new ServiceNotFoundException($id, $currentId, null, $this->getAlternatives($id)); + $this->throwServiceNotFoundException($value, $currentId, $value); } - private function getAlternatives(string $id): array + private function throwServiceNotFoundException(Reference $ref, string $sourceId, $value): void { + $id = (string) $ref; $alternatives = []; foreach ($this->container->getServiceIds() as $knownId) { if ('' === $knownId || '.' === $knownId[0]) { @@ -100,6 +96,31 @@ private function getAlternatives(string $id): array } } - return $alternatives; + $pass = new class() extends AbstractRecursivePass { + public $ref; + public $sourceId; + public $alternatives; + + /** + * @return mixed + */ + public function processValue($value, bool $isRoot = false) + { + if ($this->ref !== $value) { + return parent::processValue($value, $isRoot); + } + $sourceId = $this->sourceId; + if (null !== $this->currentId && $this->currentId !== (string) $value) { + $sourceId = $this->currentId.'" in the container provided to "'.$sourceId; + } + + throw new ServiceNotFoundException((string) $value, $sourceId, null, $this->alternatives); + } + }; + $pass->ref = $ref; + $pass->sourceId = $sourceId; + $pass->alternatives = $alternatives; + + $pass->processValue($value, true); } } diff --git a/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php b/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php index b2bd5023d..f98d06560 100644 --- a/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php +++ b/Tests/Compiler/CheckExceptionOnInvalidReferenceBehaviorPassTest.php @@ -82,7 +82,11 @@ public function testProcessDefinitionWithBindings() $this->addToAssertionCount(1); } - public function testWithErroredServiceLocator() + /** + * @testWith [true] + * [false] + */ + public function testWithErroredServiceLocator(bool $inline) { $this->expectException(ServiceNotFoundException::class); $this->expectExceptionMessage('The service "foo" in the container provided to "bar" has a dependency on a non-existent service "baz".'); @@ -91,11 +95,17 @@ public function testWithErroredServiceLocator() ServiceLocatorTagPass::register($container, ['foo' => new Reference('baz')], 'bar'); (new AnalyzeServiceReferencesPass())->process($container); - (new InlineServiceDefinitionsPass())->process($container); + if ($inline) { + (new InlineServiceDefinitionsPass())->process($container); + } $this->process($container); } - public function testWithErroredHiddenService() + /** + * @testWith [true] + * [false] + */ + public function testWithErroredHiddenService(bool $inline) { $this->expectException(ServiceNotFoundException::class); $this->expectExceptionMessage('The service "bar" has a dependency on a non-existent service "foo".'); @@ -104,7 +114,9 @@ public function testWithErroredHiddenService() ServiceLocatorTagPass::register($container, ['foo' => new Reference('foo')], 'bar'); (new AnalyzeServiceReferencesPass())->process($container); - (new InlineServiceDefinitionsPass())->process($container); + if ($inline) { + (new InlineServiceDefinitionsPass())->process($container); + } $this->process($container); }