From e0923ae1d0934a8b4b5e2196ea596539089b4def Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 5 Jan 2013 10:16:41 +0100 Subject: [PATCH] [DependencyInjection] fixed PhpDumper optimizations when an inlined service depends on the current one indirectly --- .../DependencyInjection/Dumper/PhpDumper.php | 17 +++++++++++++---- .../Fixtures/containers/container9.php | 6 +++++- .../Fixtures/graphviz/services9.dot | 4 +++- .../Fixtures/includes/classes.php | 13 +++++++++++++ .../Fixtures/php/services9.php | 19 ++++++++++++++++++- .../Fixtures/php/services9_compiled.php | 19 ++++++++++++++++++- .../Fixtures/xml/services9.xml | 5 +++++ .../Fixtures/yaml/services9.yml | 5 +++++ 8 files changed, 80 insertions(+), 8 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index d5acdd729d..18251f064c 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -246,7 +246,7 @@ class PhpDumper extends Dumper $code .= sprintf(" \$%s = new \\%s(%s);\n", $name, substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments)); } - if (!$this->hasReference($id, $sDefinition->getMethodCalls()) && !$this->hasReference($id, $sDefinition->getProperties())) { + if (!$this->hasReference($id, $sDefinition->getMethodCalls(), true) && !$this->hasReference($id, $sDefinition->getProperties(), true)) { $code .= $this->addServiceMethodCalls(null, $sDefinition, $name); $code .= $this->addServiceProperties(null, $sDefinition, $name); $code .= $this->addServiceConfigurator(null, $sDefinition, $name); @@ -415,7 +415,7 @@ class PhpDumper extends Dumper } $processed->offsetSet($iDefinition); - if (!$this->hasReference($id, $iDefinition->getMethodCalls()) && !$this->hasReference($id, $iDefinition->getProperties())) { + if (!$this->hasReference($id, $iDefinition->getMethodCalls(), true) && !$this->hasReference($id, $iDefinition->getProperties(), true)) { continue; } @@ -958,17 +958,26 @@ EOF; * * @return Boolean */ - private function hasReference($id, array $arguments) + private function hasReference($id, array $arguments, $deep = false) { foreach ($arguments as $argument) { if (is_array($argument)) { - if ($this->hasReference($id, $argument)) { + if ($this->hasReference($id, $argument, $deep)) { return true; } } elseif ($argument instanceof Reference) { if ($id === (string) $argument) { return true; } + + if ($deep) { + $service = $this->container->getDefinition((string) $argument); + $arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties()); + + if ($this->hasReference($id, $arguments, $deep)) { + return true; + } + } } } diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/containers/container9.php b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/containers/container9.php index 72c355f70c..71d29f209b 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/containers/container9.php +++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/containers/container9.php @@ -64,8 +64,12 @@ $container $container ->register('inlined', 'Bar') ->setProperty('pub', 'pub') - ->addMethodCall('setFoo', array(new Reference('foo_with_inline'))) + ->addMethodCall('setBaz', array(new Reference('baz'))) ->setPublic(false) ; +$container + ->register('baz', 'Baz') + ->addMethodCall('setFoo', array(new Reference('foo_with_inline'))) +; return $container; diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/graphviz/services9.dot b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/graphviz/services9.dot index b9618bb051..73608e27fc 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/graphviz/services9.dot +++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/graphviz/services9.dot @@ -11,6 +11,7 @@ digraph sc { node_factory_service [label="factory_service\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_foo_with_inline [label="foo_with_inline\nFoo\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_inlined [label="inlined\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_baz [label="baz\nBaz\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"]; node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"]; node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"]; @@ -25,5 +26,6 @@ digraph sc { node_method_call1 -> node_foo3 [label="setBar()" style="dashed"]; node_method_call1 -> node_foobaz [label="setBar()" style="dashed"]; node_foo_with_inline -> node_inlined [label="setBar()" style="dashed"]; - node_inlined -> node_foo_with_inline [label="setFoo()" style="dashed"]; + node_inlined -> node_baz [label="setBaz()" style="dashed"]; + node_baz -> node_foo_with_inline [label="setFoo()" style="dashed"]; } diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/includes/classes.php b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/includes/classes.php index 514df23e51..fb6d4cf19d 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/includes/classes.php +++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/includes/classes.php @@ -7,10 +7,23 @@ function sc_configure($instance) class BarClass { + protected $baz; + + public function setBaz(BazClass $baz) + { + $this->baz = $baz; + } } class BazClass { + protected $foo; + + public function setFoo(Foo $foo) + { + $this->foo = $foo; + } + public function configure($instance) { $instance->configure(); diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9.php b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9.php index 92969123e7..0d4008583e 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9.php +++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9.php @@ -40,6 +40,23 @@ class ProjectServiceContainer extends Container return $instance; } + /** + * Gets the 'baz' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return Baz A Baz instance. + */ + protected function getBazService() + { + $this->services['baz'] = $instance = new \Baz(); + + $instance->setFoo($this->get('foo_with_inline')); + + return $instance; + } + /** * Gets the 'factory_service' service. * @@ -173,7 +190,7 @@ class ProjectServiceContainer extends Container { $this->services['inlined'] = $instance = new \Bar(); - $instance->setFoo($this->get('foo_with_inline')); + $instance->setBaz($this->get('baz')); $instance->pub = 'pub'; return $instance; diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9_compiled.php b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9_compiled.php index 0ef72e1c71..f41d4b23d8 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9_compiled.php +++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9_compiled.php @@ -49,6 +49,23 @@ class ProjectServiceContainer extends Container return $instance; } + /** + * Gets the 'baz' service. + * + * This service is shared. + * This method always returns the same instance of the service. + * + * @return Baz A Baz instance. + */ + protected function getBazService() + { + $this->services['baz'] = $instance = new \Baz(); + + $instance->setFoo($this->get('foo_with_inline')); + + return $instance; + } + /** * Gets the 'factory_service' service. * @@ -126,7 +143,7 @@ class ProjectServiceContainer extends Container $this->services['foo_with_inline'] = $instance = new \Foo(); - $a->setFoo($instance); + $a->setBaz($this->get('baz')); $a->pub = 'pub'; $instance->setBar($a); diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/xml/services9.xml b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/xml/services9.xml index 4c22e6b51f..58eb6d79a3 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/xml/services9.xml +++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/xml/services9.xml @@ -58,6 +58,11 @@ pub + + + + + diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/yaml/services9.yml b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/yaml/services9.yml index ab26425a7d..d0085536ac 100644 --- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/yaml/services9.yml +++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/yaml/services9.yml @@ -49,6 +49,11 @@ services: inlined: class: Bar properties: { pub: pub } + calls: + - [setBaz, ['@baz']] + + baz: + class: Baz calls: - [setFoo, ['@foo_with_inline']]