From 8f4bb4b207713ecbd5ff482234b33548e79448cf Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 20 Aug 2024 11:50:02 +0200 Subject: [PATCH 1/2] [DependencyInjection] Fix handling of repeated `#[Autoconfigure]` attributes --- Loader/YamlFileLoader.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Loader/YamlFileLoader.php b/Loader/YamlFileLoader.php index 66e1cd84d..05e383396 100644 --- a/Loader/YamlFileLoader.php +++ b/Loader/YamlFileLoader.php @@ -448,8 +448,9 @@ private function parseDefinition(string $id, $service, string $file, array $defa return $return ? $alias : $this->container->setAlias($id, $alias); } + $changes = []; if (null !== $definition) { - // no-op + $changes = $definition->getChanges(); } elseif ($this->isLoadingInstanceof) { $definition = new ChildDefinition(''); } elseif (isset($service['parent'])) { @@ -472,7 +473,7 @@ private function parseDefinition(string $id, $service, string $file, array $defa $definition->setAutoconfigured($defaults['autoconfigure']); } - $definition->setChanges([]); + $definition->setChanges($changes); if (isset($service['class'])) { $definition->setClass($service['class']); From 960d2596145afab3f6faea0b3d22c70700087e9a Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Mon, 3 Jun 2024 13:09:03 +0200 Subject: [PATCH 2/2] [DependencyInjection] Add tests for repeating `#[Autoconfigure]` attributes --- ...egisterAutoconfigureAttributesPassTest.php | 99 +++++++++++++++++++ Tests/Fixtures/AutoconfigureRepeated.php | 11 +++ .../AutoconfigureRepeatedBindings.php | 11 +++ Tests/Fixtures/AutoconfigureRepeatedCalls.php | 18 ++++ .../AutoconfigureRepeatedOverwrite.php | 11 +++ .../AutoconfigureRepeatedProperties.php | 11 +++ Tests/Fixtures/AutoconfigureRepeatedTag.php | 11 +++ 7 files changed, 172 insertions(+) create mode 100644 Tests/Fixtures/AutoconfigureRepeated.php create mode 100644 Tests/Fixtures/AutoconfigureRepeatedBindings.php create mode 100644 Tests/Fixtures/AutoconfigureRepeatedCalls.php create mode 100644 Tests/Fixtures/AutoconfigureRepeatedOverwrite.php create mode 100644 Tests/Fixtures/AutoconfigureRepeatedProperties.php create mode 100644 Tests/Fixtures/AutoconfigureRepeatedTag.php diff --git a/Tests/Compiler/RegisterAutoconfigureAttributesPassTest.php b/Tests/Compiler/RegisterAutoconfigureAttributesPassTest.php index 689c75aa7..958d1d9b3 100644 --- a/Tests/Compiler/RegisterAutoconfigureAttributesPassTest.php +++ b/Tests/Compiler/RegisterAutoconfigureAttributesPassTest.php @@ -19,6 +19,12 @@ use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureAttributed; use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfiguredInterface; +use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeated; +use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedBindings; +use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedCalls; +use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedOverwrite; +use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedProperties; +use Symfony\Component\DependencyInjection\Tests\Fixtures\AutoconfigureRepeatedTag; use Symfony\Component\DependencyInjection\Tests\Fixtures\ParentNotExists; /** @@ -77,6 +83,99 @@ public function testAutoconfiguredTag() $this->assertEquals([AutoconfiguredInterface::class => $expected], $container->getAutoconfiguredInstanceof()); } + public function testAutoconfiguredRepeated() + { + $container = new ContainerBuilder(); + $container->register('foo', AutoconfigureRepeated::class) + ->setAutoconfigured(true); + + (new RegisterAutoconfigureAttributesPass())->process($container); + + $expected = (new ChildDefinition('')) + ->setLazy(true) + ->setPublic(true) + ->setShared(false); + + $this->assertEquals([AutoconfigureRepeated::class => $expected], $container->getAutoconfiguredInstanceof()); + } + + public function testAutoconfiguredRepeatedOverwrite() + { + $container = new ContainerBuilder(); + $container->register('foo', AutoconfigureRepeatedOverwrite::class) + ->setAutoconfigured(true); + + (new RegisterAutoconfigureAttributesPass())->process($container); + + $expected = (new ChildDefinition('')) + ->setLazy(true) + ->setPublic(false) + ->setShared(true); + + $this->assertEquals([AutoconfigureRepeatedOverwrite::class => $expected], $container->getAutoconfiguredInstanceof()); + } + + public function testAutoconfiguredRepeatedTag() + { + $container = new ContainerBuilder(); + $container->register('foo', AutoconfigureRepeatedTag::class) + ->setAutoconfigured(true); + + (new RegisterAutoconfigureAttributesPass())->process($container); + + $expected = (new ChildDefinition('')) + ->addTag('foo', ['priority' => 2]) + ->addTag('bar'); + + $this->assertEquals([AutoconfigureRepeatedTag::class => $expected], $container->getAutoconfiguredInstanceof()); + } + + public function testAutoconfiguredRepeatedCalls() + { + $container = new ContainerBuilder(); + $container->register('foo', AutoconfigureRepeatedCalls::class) + ->setAutoconfigured(true); + + (new RegisterAutoconfigureAttributesPass())->process($container); + + $expected = (new ChildDefinition('')) + ->addMethodCall('setBar', ['arg2']) + ->addMethodCall('setFoo', ['arg1']); + + $this->assertEquals([AutoconfigureRepeatedCalls::class => $expected], $container->getAutoconfiguredInstanceof()); + } + + public function testAutoconfiguredRepeatedBindingsOverwrite() + { + $container = new ContainerBuilder(); + $container->register('foo', AutoconfigureRepeatedBindings::class) + ->setAutoconfigured(true); + + (new RegisterAutoconfigureAttributesPass())->process($container); + + $expected = (new ChildDefinition('')) + ->setBindings(['$arg' => new BoundArgument('bar', false, BoundArgument::INSTANCEOF_BINDING, realpath(__DIR__.'/../Fixtures/AutoconfigureRepeatedBindings.php'))]); + + $this->assertEquals([AutoconfigureRepeatedBindings::class => $expected], $container->getAutoconfiguredInstanceof()); + } + + public function testAutoconfiguredRepeatedPropertiesOverwrite() + { + $container = new ContainerBuilder(); + $container->register('foo', AutoconfigureRepeatedProperties::class) + ->setAutoconfigured(true); + + (new RegisterAutoconfigureAttributesPass())->process($container); + + $expected = (new ChildDefinition('')) + ->setProperties([ + '$foo' => 'bar', + '$bar' => 'baz', + ]); + + $this->assertEquals([AutoconfigureRepeatedProperties::class => $expected], $container->getAutoconfiguredInstanceof()); + } + public function testMissingParent() { $container = new ContainerBuilder(); diff --git a/Tests/Fixtures/AutoconfigureRepeated.php b/Tests/Fixtures/AutoconfigureRepeated.php new file mode 100644 index 000000000..1b6bc639d --- /dev/null +++ b/Tests/Fixtures/AutoconfigureRepeated.php @@ -0,0 +1,11 @@ + 'foo'])] +#[Autoconfigure(bind: ['$arg' => 'bar'])] +class AutoconfigureRepeatedBindings +{ +} diff --git a/Tests/Fixtures/AutoconfigureRepeatedCalls.php b/Tests/Fixtures/AutoconfigureRepeatedCalls.php new file mode 100644 index 000000000..ba794a705 --- /dev/null +++ b/Tests/Fixtures/AutoconfigureRepeatedCalls.php @@ -0,0 +1,18 @@ + 'to be replaced', '$bar' => 'existing to be replaced'])] +#[Autoconfigure(properties: ['$foo' => 'bar', '$bar' => 'baz'])] +class AutoconfigureRepeatedProperties +{ +} diff --git a/Tests/Fixtures/AutoconfigureRepeatedTag.php b/Tests/Fixtures/AutoconfigureRepeatedTag.php new file mode 100644 index 000000000..671bc6074 --- /dev/null +++ b/Tests/Fixtures/AutoconfigureRepeatedTag.php @@ -0,0 +1,11 @@ + 2])] +#[AutoconfigureTag('bar')] +class AutoconfigureRepeatedTag +{ +}