From 2fcc5c3bdc099bedd5a3053bb0c9911878ab8dac Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Thu, 16 Feb 2023 18:39:07 +0100 Subject: [PATCH] [DependencyInjection] Fix dumping closure of service closure --- .../DependencyInjection/Dumper/PhpDumper.php | 4 ++++ .../Tests/Dumper/PhpDumperTest.php | 5 +++++ .../Tests/Fixtures/config/closure.expected.yml | 6 ++++++ .../Tests/Fixtures/config/closure.php | 6 +++++- .../Tests/Fixtures/php/closure.php | 14 ++++++++++++++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 074a1427f63a9..b414c13349111 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -1132,6 +1132,10 @@ private function addNewInstance(Definition $definition, string $return = '', str if (['Closure', 'fromCallable'] === $callable && [0] === array_keys($definition->getArguments())) { $callable = $definition->getArgument(0); + if ($callable instanceof ServiceClosureArgument) { + return $return.sprintf('static fn(): \Closure => %s', $this->dumpLiteralClass($this->dumpValue($callable))).$tail; + } + $arguments = ['...']; if ($callable instanceof Reference || $callable instanceof Definition) { diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 8a53d36b7d515..89be393e88e3d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -1569,6 +1569,11 @@ public function testClosure() ->setFactory(['Closure', 'fromCallable']) ->setArguments([new Reference('bar')]); $container->register('bar', 'stdClass'); + $container->register('closure_of_service_closure', 'Closure') + ->setPublic('true') + ->setFactory(['Closure', 'fromCallable']) + ->setArguments([new ServiceClosureArgument(new Reference('bar2'))]); + $container->register('bar2', 'stdClass'); $container->compile(); $dumper = new PhpDumper($container); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/closure.expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/closure.expected.yml index 2fcce6c6d7751..734df23069bd0 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/closure.expected.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/closure.expected.yml @@ -8,3 +8,9 @@ services: class: stdClass public: true properties: { foo: !service { class: Closure, arguments: [!service { class: stdClass }], factory: [Closure, fromCallable] } } + closure_of_service_closure: + class: stdClass + public: true + arguments: [!service { class: Closure, arguments: [!service_closure '@bar2'], factory: [Closure, fromCallable] }] + bar2: + class: stdClass diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/closure.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/closure.php index 4f67ba048b028..1c0d2976fe5e6 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/closure.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/closure.php @@ -9,6 +9,10 @@ public function __invoke(ContainerConfigurator $c) ->set('closure_property', 'stdClass') ->public() ->property('foo', closure(service('bar'))) - ->set('bar', 'stdClass'); + ->set('bar', 'stdClass') + ->set('closure_of_service_closure', 'stdClass') + ->public() + ->args([closure(service_closure('bar2'))]) + ->set('bar2', 'stdClass'); } }; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/closure.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/closure.php index cb9a3805400be..7d19cb5c5309e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/closure.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/closure.php @@ -21,6 +21,7 @@ public function __construct() $this->services = $this->privates = []; $this->methodMap = [ 'closure' => 'getClosureService', + 'closure_of_service_closure' => 'getClosureOfServiceClosureService', ]; $this->aliases = []; @@ -40,6 +41,7 @@ public function getRemovedIds(): array { return [ 'bar' => true, + 'bar2' => true, ]; } @@ -52,4 +54,16 @@ protected function getClosureService() { return $this->services['closure'] = (new \stdClass())->__invoke(...); } + + /** + * Gets the public 'closure_of_service_closure' shared service. + * + * @return \Closure + */ + protected function getClosureOfServiceClosureService() + { + return $this->services['closure_of_service_closure'] = static fn(): \Closure => ${($_ = #[\Closure(name: 'bar2', class: 'stdClass')] function () { + return ($this->privates['bar2'] ??= new \stdClass()); + }) && false ?: "_"}; + } }