From 7816a98204aad2904b2b95b941b656a995abad32 Mon Sep 17 00:00:00 2001 From: Warnar Boekkooi Date: Mon, 3 Nov 2014 19:58:57 +0800 Subject: [PATCH] [DependencyInjection] inlined factory not referenced --- .../Compiler/AnalyzeServiceReferencesPass.php | 4 + .../Compiler/InlineServiceDefinitionsPass.php | 4 + .../AnalyzeServiceReferencesPassTest.php | 22 ++++++ .../InlineServiceDefinitionsPassTest.php | 78 +++++++++++++++++++ 4 files changed, 108 insertions(+) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php index 10718533bb..7d62569e66 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php @@ -111,6 +111,10 @@ class AnalyzeServiceReferencesPass implements RepeatablePassInterface $this->processArguments($argument->getArguments()); $this->processArguments($argument->getMethodCalls()); $this->processArguments($argument->getProperties()); + + if ($argument->getFactoryService()) { + $this->processArguments(array(new Reference($argument->getFactoryService()))); + } } } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php index 5d4f2bf58b..6623e73afc 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php @@ -138,6 +138,10 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface return false; } + if (count($ids) > 1 && $definition->getFactoryService()) { + return false; + } + return $container->getDefinition(reset($ids))->getScope() === $definition->getScope(); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php index 00322a22d0..e45ac9305a 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/AnalyzeServiceReferencesPassTest.php @@ -79,6 +79,28 @@ class AnalyzeServiceReferencesPassTest extends \PHPUnit_Framework_TestCase $this->assertSame($ref, $refs[0]->getValue()); } + public function testProcessDetectsReferencesFromInlinedFactoryDefinitions() + { + $container = new ContainerBuilder(); + + $container + ->register('a') + ; + + $factory = new Definition(); + $factory->setFactoryService('a'); + + $container + ->register('b') + ->addArgument($factory) + ; + + $graph = $this->process($container); + + $this->assertTrue($graph->hasNode('a')); + $this->assertCount(1, $refs = $graph->getNode('a')->getInEdges()); + } + public function testProcessDoesNotSaveDuplicateReferences() { $container = new ContainerBuilder(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php index 6458a335d8..fc404467a6 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php @@ -110,6 +110,84 @@ class InlineServiceDefinitionsPassTest extends \PHPUnit_Framework_TestCase $this->assertSame($a, $inlinedArguments[0]); } + public function testProcessInlinesPrivateFactoryReference() + { + $container = new ContainerBuilder(); + + $container->register('a')->setPublic(false); + $b = $container + ->register('b') + ->setPublic(false) + ->setFactoryService('a') + ; + + $container + ->register('foo') + ->setArguments(array( + $ref = new Reference('b'), + )); + + $this->process($container); + + $inlinedArguments = $container->getDefinition('foo')->getArguments(); + $this->assertSame($b, $inlinedArguments[0]); + } + + public function testProcessDoesNotInlinePrivateFactoryIfReferencedMultipleTimesWithinTheSameDefinition() + { + $container = new ContainerBuilder(); + $container + ->register('a') + ; + $container + ->register('b') + ->setPublic(false) + ->setFactoryService('a') + ; + + $container + ->register('foo') + ->setArguments(array( + $ref1 = new Reference('b'), + $ref2 = new Reference('b'), + )) + ; + $this->process($container); + + $args = $container->getDefinition('foo')->getArguments(); + $this->assertSame($ref1, $args[0]); + $this->assertSame($ref2, $args[1]); + } + + public function testProcessDoesNotInlineReferenceWhenUsedByInlineFactory() + { + $container = new ContainerBuilder(); + $container + ->register('a') + ; + $container + ->register('b') + ->setPublic(false) + ->setFactoryService('a') + ; + + $inlineFactory = new Definition(); + $inlineFactory->setPublic(false); + $inlineFactory->setFactoryService('b'); + + $container + ->register('foo') + ->setArguments(array( + $ref = new Reference('b'), + $inlineFactory, + )) + ; + $this->process($container); + + $args = $container->getDefinition('foo')->getArguments(); + $this->assertSame($ref, $args[0]); + } + public function testProcessInlinesOnlyIfSameScope() { $container = new ContainerBuilder();