From e07ad2b477a6cd3c6a83f97f5f09037c267d0d26 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Thu, 13 Dec 2018 17:15:21 +0100 Subject: [PATCH] [DI] fix reporting bindings on overriden services as unused --- .../Compiler/ResolveBindingsPass.php | 2 + .../DependencyInjection/ContainerBuilder.php | 46 ++++++++++++++++--- .../Compiler/ResolveBindingsPassTest.php | 18 ++++++++ .../ResolveChildDefinitionsPassTest.php | 2 +- .../Tests/ContainerBuilderTest.php | 2 +- .../Fixtures/config/instanceof.expected.yml | 6 +-- .../Fixtures/config/prototype.expected.yml | 10 ++-- 7 files changed, 69 insertions(+), 17 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php index bcf265ab47235..166e23441c62a 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php @@ -34,6 +34,8 @@ class ResolveBindingsPass extends AbstractRecursivePass */ public function process(ContainerBuilder $container) { + $this->usedBindings = $container->getRemovedBindingIds(); + try { parent::process($container); diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index 5fe6f2ae6fdfd..93239a703db58 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -123,6 +123,8 @@ class ContainerBuilder extends Container implements TaggedContainerInterface private $removedIds = array(); + private $removedBindingIds = array(); + private static $internalTypes = array( 'int' => true, 'float' => true, @@ -531,7 +533,8 @@ public function set($id, $service) throw new BadMethodCallException(sprintf('Setting service "%s" for an unknown or non-synthetic service definition on a compiled container is not allowed.', $id)); } - unset($this->definitions[$id], $this->aliasDefinitions[$id], $this->removedIds[$id]); + $this->removeId($id); + unset($this->removedIds[$id]); parent::set($id, $service); } @@ -544,8 +547,7 @@ public function set($id, $service) public function removeDefinition($id) { if (isset($this->definitions[$id = $this->normalizeId($id)])) { - unset($this->definitions[$id]); - $this->removedIds[$id] = true; + $this->removeId($id); } } @@ -876,7 +878,8 @@ public function setAlias($alias, $id) throw new InvalidArgumentException(sprintf('An alias can not reference itself, got a circular reference on "%s".', $alias)); } - unset($this->definitions[$alias], $this->removedIds[$alias]); + $this->removeId($alias); + unset($this->removedIds[$alias]); return $this->aliasDefinitions[$alias] = $id; } @@ -889,8 +892,7 @@ public function setAlias($alias, $id) public function removeAlias($alias) { if (isset($this->aliasDefinitions[$alias = $this->normalizeId($alias)])) { - unset($this->aliasDefinitions[$alias]); - $this->removedIds[$alias] = true; + $this->removeId($alias); } } @@ -1019,7 +1021,8 @@ public function setDefinition($id, Definition $definition) $id = $this->normalizeId($id); - unset($this->aliasDefinitions[$id], $this->removedIds[$id]); + $this->removeId($id); + unset($this->removedIds[$id]); return $this->definitions[$id] = $definition; } @@ -1552,6 +1555,18 @@ public static function getInitializedConditionals($value) return $services; } + /** + * Gets removed binding ids. + * + * @return array + * + * @internal + */ + public function getRemovedBindingIds() + { + return $this->removedBindingIds; + } + /** * Computes a reasonably unique hash of a value. * @@ -1656,4 +1671,21 @@ private function inVendors($path) return false; } + + private function removeId($id) + { + $this->removedIds[$id] = true; + unset($this->aliasDefinitions[$id]); + + if (!isset($this->definitions[$id])) { + return; + } + + foreach ($this->definitions[$id]->getBindings() as $binding) { + list(, $identifier) = $binding->getValues(); + $this->removedBindingIds[$identifier] = true; + } + + unset($this->definitions[$id]); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php index d59b95af5c406..24909e1155fb8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveBindingsPassTest.php @@ -111,4 +111,22 @@ public function testScalarSetter() $this->assertEquals(array(array('setDefaultLocale', array('fr'))), $definition->getMethodCalls()); } + + public function testOverriddenBindings() + { + $container = new ContainerBuilder(); + + $binding = new BoundArgument('bar'); + + $container->register('foo', 'stdClass') + ->setBindings(array('$foo' => clone $binding)); + $container->register('bar', 'stdClass') + ->setBindings(array('$foo' => clone $binding)); + + $container->register('foo', 'stdClass'); + + (new ResolveBindingsPass())->process($container); + + $this->assertInstanceOf('stdClass', $container->get('foo')); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php index 1575bd7b07751..863f2833e5f7e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveChildDefinitionsPassTest.php @@ -434,7 +434,7 @@ protected function process(ContainerBuilder $container) /** * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException - * @expectedExceptionMessageRegExp /^Circular reference detected for service "c", path: "c -> b -> a -> c"./ + * @expectedExceptionMessageRegExp /^Circular reference detected for service "a", path: "a -> c -> b -> a"./ */ public function testProcessDetectsChildDefinitionIndirectCircularReference() { diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 0bf1befa3f84d..354b44187d6bc 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -559,7 +559,7 @@ public function testMerge() $config->setDefinition('baz', new Definition('BazClass')); $config->setAlias('alias_for_foo', 'foo'); $container->merge($config); - $this->assertEquals(array('service_container', 'foo', 'bar', 'baz'), array_keys($container->getDefinitions()), '->merge() merges definitions already defined ones'); + $this->assertEquals(array('foo', 'bar', 'service_container', 'baz'), array_keys($container->getDefinitions()), '->merge() merges definitions already defined ones'); $aliases = $container->getAliases(); $this->assertArrayHasKey('alias_for_foo', $aliases); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/instanceof.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/instanceof.expected.yml index b12a304221dd8..9f0bfbba78a2e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/instanceof.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/instanceof.expected.yml @@ -4,6 +4,9 @@ services: class: Symfony\Component\DependencyInjection\ContainerInterface public: true synthetic: true + foo: + class: App\FooService + public: true Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo: class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo public: true @@ -16,6 +19,3 @@ services: shared: false configurator: c - foo: - class: App\FooService - public: true diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml index ebfe087d779cf..0af4d530a0879 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/prototype.expected.yml @@ -4,22 +4,22 @@ services: class: Symfony\Component\DependencyInjection\ContainerInterface public: true synthetic: true - Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo: - class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo + Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar public: true tags: - { name: foo } - { name: baz } deprecated: '%service_id%' + lazy: true arguments: [1] factory: f - Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar: - class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Sub\Bar + Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo: + class: Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\Foo public: true tags: - { name: foo } - { name: baz } deprecated: '%service_id%' - lazy: true arguments: [1] factory: f pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy