From e992f8e3d15d81dffd5776f05c904361434049bf Mon Sep 17 00:00:00 2001 From: Warnar Boekkooi Date: Mon, 11 Aug 2014 17:11:49 +0800 Subject: [PATCH] Fixed Factory services not within the ServiceReferenceGraph. --- .../Compiler/AnalyzeServiceReferencesPass.php | 4 ++ .../AnalyzeServiceReferencesPassTest.php | 20 ++++++++++ .../CheckCircularReferencesPassTest.php | 39 +++++++++++++++++++ .../RemoveUnusedDefinitionsPassTest.php | 27 +++++++++++++ 4 files changed, 90 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php index 4a907ece296c..f488052596a9 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php @@ -69,7 +69,11 @@ public function process(ContainerBuilder $container) $this->currentId = $id; $this->currentDefinition = $definition; + $this->processArguments($definition->getArguments()); + if ($definition->getFactoryService()) { + $this->processArguments(array(new Reference($definition->getFactoryService()))); + } if (!$this->onlyConstructorArguments) { $this->processArguments($definition->getMethodCalls()); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php index c99659e5a67f..00322a22d003 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php @@ -97,6 +97,26 @@ public function testProcessDoesNotSaveDuplicateReferences() $this->assertCount(2, $graph->getNode('a')->getInEdges()); } + public function testProcessDetectsFactoryReferences() + { + $container = new ContainerBuilder(); + + $container + ->register('foo', 'stdClass') + ->setFactoryClass('stdClass') + ->setFactoryMethod('getInstance'); + + $container + ->register('bar', 'stdClass') + ->setFactoryService('foo') + ->setFactoryMethod('getInstance'); + + $graph = $this->process($container); + + $this->assertTrue($graph->hasNode('foo')); + $this->assertCount(1, $graph->getNode('foo')->getInEdges()); + } + protected function process(ContainerBuilder $container) { $pass = new RepeatedPass(array(new AnalyzeServiceReferencesPass())); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php index 085bc519b73e..8183014c5b0e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckCircularReferencesPassTest.php @@ -48,6 +48,26 @@ public function testProcessWithAliases() $this->process($container); } + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException + */ + public function testProcessWithFactory() + { + $container = new ContainerBuilder(); + + $container + ->register('a', 'stdClass') + ->setFactoryService('b') + ->setFactoryMethod('getInstance'); + + $container + ->register('b', 'stdClass') + ->setFactoryService('a') + ->setFactoryMethod('getInstance'); + + $this->process($container); + } + /** * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException */ @@ -61,6 +81,25 @@ public function testProcessDetectsIndirectCircularReference() $this->process($container); } + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException + */ + public function testProcessDetectsIndirectCircularReferenceWithFactory() + { + $container = new ContainerBuilder(); + + $container->register('a')->addArgument(new Reference('b')); + + $container + ->register('b', 'stdClass') + ->setFactoryService('c') + ->setFactoryMethod('getInstance'); + + $container->register('c')->addArgument(new Reference('a')); + + $this->process($container); + } + /** * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException */ diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.php index d7e55214a936..b3e451c551c4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/RemoveUnusedDefinitionsPassTest.php @@ -81,6 +81,33 @@ public function testProcessWorksWithInlinedDefinitions() $this->assertTrue($container->hasDefinition('bar')); } + public function testProcessWontRemovePrivateFactory() + { + $container = new ContainerBuilder(); + + $container + ->register('foo', 'stdClass') + ->setFactoryClass('stdClass') + ->setFactoryMethod('getInstance') + ->setPublic(false); + + $container + ->register('bar', 'stdClass') + ->setFactoryService('foo') + ->setFactoryMethod('getInstance') + ->setPublic(false); + + $container + ->register('foobar') + ->addArgument(new Reference('bar')); + + $this->process($container); + + $this->assertTrue($container->hasDefinition('foo')); + $this->assertTrue($container->hasDefinition('bar')); + $this->assertTrue($container->hasDefinition('foobar')); + } + protected function process(ContainerBuilder $container) { $repeatedPass = new RepeatedPass(array(new AnalyzeServiceReferencesPass(), new RemoveUnusedDefinitionsPass()));