Skip to content

Commit 1b2805a

Browse files
Merge branch '6.4' into 7.0
* 6.4: Sync .github/expected-missing-return-types.diff harden LockRegistry tests, consider PHP files only Psalm: Suppress UnusedConstructor errors [DependencyInjection] Do not add `return` in `LazyClosure` when return type of closure is `void`
2 parents 23f534e + 42b4805 commit 1b2805a

File tree

4 files changed

+47
-10
lines changed

4 files changed

+47
-10
lines changed

Argument/LazyClosure.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ public static function getCode(string $initializer, array $callable, Definition
7878
throw new RuntimeException("Cannot create lazy closure{$id} because its corresponding callable is invalid.");
7979
}
8080

81-
$code = ProxyHelper::exportSignature($r->getMethod($method), true, $args);
81+
$methodReflector = $r->getMethod($method);
82+
$code = ProxyHelper::exportSignature($methodReflector, true, $args);
8283

8384
if ($asClosure) {
8485
$code = ' { '.preg_replace('/: static$/', ': \\'.$r->name, $code);
@@ -87,7 +88,7 @@ public static function getCode(string $initializer, array $callable, Definition
8788
}
8889

8990
$code = 'new class('.$initializer.') extends \\'.self::class
90-
.$code.' { return $this->service->'.$callable[1].'('.$args.'); } '
91+
.$code.' { '.($methodReflector->hasReturnType() && 'void' === (string) $methodReflector->getReturnType() ? '' : 'return ').'$this->service->'.$callable[1].'('.$args.'); } '
9192
.'}';
9293

9394
return $asClosure ? '('.$code.')->'.$method.'(...)' : $code;

Tests/Dumper/PhpDumperTest.php

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
use Symfony\Component\DependencyInjection\Tests\Compiler\AAndIInterfaceConsumer;
4848
use Symfony\Component\DependencyInjection\Tests\Compiler\AInterface;
4949
use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;
50+
use Symfony\Component\DependencyInjection\Tests\Compiler\FooVoid;
5051
use Symfony\Component\DependencyInjection\Tests\Compiler\IInterface;
5152
use Symfony\Component\DependencyInjection\Tests\Compiler\MyCallable;
5253
use Symfony\Component\DependencyInjection\Tests\Compiler\SingleMethodInterface;
@@ -1843,12 +1844,18 @@ public function testAutowireClosure()
18431844
public function testLazyClosure()
18441845
{
18451846
$container = new ContainerBuilder();
1846-
$container->register('closure', 'Closure')
1847+
$container->register('closure1', 'Closure')
18471848
->setPublic('true')
18481849
->setFactory(['Closure', 'fromCallable'])
18491850
->setLazy(true)
18501851
->setArguments([[new Reference('foo'), 'cloneFoo']]);
1852+
$container->register('closure2', 'Closure')
1853+
->setPublic('true')
1854+
->setFactory(['Closure', 'fromCallable'])
1855+
->setLazy(true)
1856+
->setArguments([[new Reference('foo_void'), '__invoke']]);
18511857
$container->register('foo', Foo::class);
1858+
$container->register('foo_void', FooVoid::class);
18521859
$container->compile();
18531860
$dumper = new PhpDumper($container);
18541861

@@ -1859,11 +1866,18 @@ public function testLazyClosure()
18591866
$container = new \Symfony_DI_PhpDumper_Test_Lazy_Closure();
18601867

18611868
$cloned = Foo::$counter;
1862-
$this->assertInstanceOf(\Closure::class, $container->get('closure'));
1869+
$this->assertInstanceOf(\Closure::class, $container->get('closure1'));
18631870
$this->assertSame($cloned, Foo::$counter);
1864-
$this->assertInstanceOf(Foo::class, $container->get('closure')());
1871+
$this->assertInstanceOf(Foo::class, $container->get('closure1')());
18651872
$this->assertSame(1 + $cloned, Foo::$counter);
1866-
$this->assertSame(1, (new \ReflectionFunction($container->get('closure')))->getNumberOfParameters());
1873+
$this->assertSame(1, (new \ReflectionFunction($container->get('closure1')))->getNumberOfParameters());
1874+
1875+
$counter = FooVoid::$counter;
1876+
$this->assertInstanceOf(\Closure::class, $container->get('closure2'));
1877+
$this->assertSame($counter, FooVoid::$counter);
1878+
$container->get('closure2')('Hello');
1879+
$this->assertSame(1 + $counter, FooVoid::$counter);
1880+
$this->assertSame(1, (new \ReflectionFunction($container->get('closure2')))->getNumberOfParameters());
18671881
}
18681882

18691883
public function testLazyAutowireAttribute()

Tests/Fixtures/includes/autowiring_classes.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ public function cloneFoo(\stdClass $bar = null): static
2424
}
2525
}
2626

27+
class FooVoid
28+
{
29+
public static int $counter = 0;
30+
31+
public function __invoke(string $name): void
32+
{
33+
++self::$counter;
34+
}
35+
}
36+
2737
class Bar
2838
{
2939
public function __construct(Foo $foo)

Tests/Fixtures/php/lazy_closure.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ public function __construct()
2020
{
2121
$this->services = $this->privates = [];
2222
$this->methodMap = [
23-
'closure' => 'getClosureService',
23+
'closure1' => 'getClosure1Service',
24+
'closure2' => 'getClosure2Service',
2425
];
2526

2627
$this->aliases = [];
@@ -40,6 +41,7 @@ public function getRemovedIds(): array
4041
{
4142
return [
4243
'foo' => true,
44+
'foo_void' => true,
4345
];
4446
}
4547

@@ -49,12 +51,22 @@ protected function createProxy($class, \Closure $factory)
4951
}
5052

5153
/**
52-
* Gets the public 'closure' shared service.
54+
* Gets the public 'closure1' shared service.
5355
*
5456
* @return \Closure
5557
*/
56-
protected static function getClosureService($container, $lazyLoad = true)
58+
protected static function getClosure1Service($container, $lazyLoad = true)
5759
{
58-
return $container->services['closure'] = (new class(fn () => new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo()) extends \Symfony\Component\DependencyInjection\Argument\LazyClosure { public function cloneFoo(?\stdClass $bar = null): \Symfony\Component\DependencyInjection\Tests\Compiler\Foo { return $this->service->cloneFoo(...\func_get_args()); } })->cloneFoo(...);
60+
return $container->services['closure1'] = (new class(fn () => new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo()) extends \Symfony\Component\DependencyInjection\Argument\LazyClosure { public function cloneFoo(?\stdClass $bar = null): \Symfony\Component\DependencyInjection\Tests\Compiler\Foo { return $this->service->cloneFoo(...\func_get_args()); } })->cloneFoo(...);
61+
}
62+
63+
/**
64+
* Gets the public 'closure2' shared service.
65+
*
66+
* @return \Closure
67+
*/
68+
protected static function getClosure2Service($container, $lazyLoad = true)
69+
{
70+
return $container->services['closure2'] = (new class(fn () => new \Symfony\Component\DependencyInjection\Tests\Compiler\FooVoid()) extends \Symfony\Component\DependencyInjection\Argument\LazyClosure { public function __invoke(string $name): void { $this->service->__invoke(...\func_get_args()); } })->__invoke(...);
5971
}
6072
}

0 commit comments

Comments
 (0)