10000 Add support of PHP8 static return type for withers · symfony/symfony@04fdf05 · GitHub
[go: up one dir, main page]

Skip to content

Commit 04fdf05

Browse files
committed
Add support of PHP8 static return type for withers
1 parent 71b3912 commit 04fdf05

File tree

8 files changed

+184
-1
lines changed

8 files changed

+184
-1
lines changed

.github/patch-types.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Compiler/OptionalServiceClass.php'):
2424
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ParentNotExists.php'):
2525
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/BadClasses/MissingParent.php'):
26+
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/WitherStaticReturnType.php'):
2627
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/'):
2728
case false !== strpos($file, '/src/Symfony/Component/ErrorHandler/Tests/Fixtures/'):
2829
case false !== strpos($file, '/src/Symfony/Component/PropertyInfo/Tests/Fixtures/Dummy.php'):

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ CHANGELOG
1919
* deprecated `Definition::getDeprecationMessage()`, use `Definition::getDeprecation()` instead
2020
* deprecated `Alias::getDeprecationMessage()`, use `Alias::getDeprecation()` instead
2121
* deprecated PHP-DSL's `inline()` function, use `service()` instead
22+
* added support of PHP8 static return type for withers
2223

2324
5.0.0
2425
-----

src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredMethodsPass.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ protected function processValue($value, bool $isRoot = false)
5151
while (true) {
5252
if (false !== $doc = $r->getDocComment()) {
5353
if (false !== stripos($doc, '@required') && preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@required(?:\s|\*/$)#i', $doc)) {
54-
if (preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@return\s++static[\s\*]#i', $doc)) {
54+
if ($this->isWither($reflectionMethod, $doc)) {
5555
$withers[] = [$reflectionMethod->name, [], true];
5656
} else {
5757
$value->addMethodCall($reflectionMethod->name, []);
@@ -81,4 +81,20 @@ protected function processValue($value, bool $isRoot = false)
8181

8282
return $value;
8383
}
84+
85+
private function isWither(\ReflectionMethod $reflectionMethod, string $doc): bool
86+
{
87+
$match = preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@return\s++(static|\$this)[\s\*]#i', $doc, $matches);
88+
if ($match && 'static' === $matches[1]) {
89+
return true;
90+
}
91+
92+
if ($match && '$this' === $matches[1]) {
93+
return false;
94+
}
95+
96+
$reflectionType = $reflectionMethod->hasReturnType() ? $reflectionMethod->getReturnType() : null;
97+
98+
return $reflectionType instanceof \ReflectionNamedType && 'static' === $reflectionType->getName();
99+
}
84100
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/AutowireRequiredMethodsPassTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\DependencyInjection\Compiler\AutowireRequiredMethodsPass;
1616
use Symfony\Component\DependencyInjection\Compiler\ResolveClassPass;
1717
use Symfony\Component\DependencyInjection\ContainerBuilder;
18+
use Symfony\Component\DependencyInjection\Tests\Fixtures\WitherStaticReturnType;
1819

1920
require_once __DIR__.'/../Fixtures/includes/autowiring_classes.php';
2021

@@ -99,4 +100,28 @@ public function testWitherInjection()
99100
];
100101
$this->assertSame($expected, $methodCalls);
101102
}
103+
104+
/**
105+
* @requires PHP 8
106+
*/
107+
public function testWitherWithStaticReturnTypeInjection()
108+
{
109+
$container = new ContainerBuilder();
110+
$container->register(Foo::class);
111+
112+
$container
113+
->register('wither', WitherStaticReturnType::class)
114+
->setAutowired(true);
115+
116+
(new ResolveClassPass())->process($container);
117+
(new AutowireRequiredMethodsPass())->process($container);
118+
119+
$methodCalls = $container->getDefinition('wither')->getMethodCalls();
120+
121+
$expected = [
122+
['withFoo', [], true],
123+
['setFoo', []],
124+
];
125+
$this->assertSame($expected, $methodCalls);
126+
}
102127
}

src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
use Symfony\Component\DependencyInjection\Tests\Fixtures\FooWithAbstractArgument;
4747
use Symfony\Component\DependencyInjection\Tests\Fixtures\ScalarFactory;
4848
use Symfony\Component\DependencyInjection\Tests\Fixtures\SimilarArgumentsDummy;
49+
use Symfony\Component\DependencyInjection\Tests\Fixtures\WitherStaticReturnType;
4950
use Symfony\Component\DependencyInjection\TypedReference;
5051
use Symfony\Component\ExpressionLanguage\Expression;
5152

@@ -1624,6 +1625,25 @@ public function testWither()
16241625
$this->assertInstanceOf(Foo::class, $wither->foo);
16251626
}
16261627

1628+
/**
1629+
* @requires PHP 8
1630+
*/
1631+
public function testWitherWithStaticReturnType()
1632+
{
1633+
$container = new ContainerBuilder();
1634+
$container->register(Foo::class);
1635+
1636+
$container
1637+
->register('wither', WitherStaticReturnType::class)
1638+
->setPublic(true)
1639+
->setAutowired(true);
1640+
1641+
$container->compile();
1642+
1643+
$wither = $container->get('wither');
1644+
$this->assertInstanceOf(Foo::class, $wither->foo);
1645+
}
1646+
16271647
public function testAutoAliasing()
16281648
{
16291649
$container = new ContainerBuilder();

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
use Symfony\Component\DependencyInjection\Tests\Fixtures\StubbedTranslator;
4343
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestDefinition1;
4444
use Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber;
45+
use Symfony\Component\DependencyInjection\Tests\Fixtures\WitherStaticReturnType;
4546
use Symfony\Component\DependencyInjection\TypedReference;
4647
use Symfony\Component\DependencyInjection\Variable;
4748
use Symfony\Component\ExpressionLanguage\Expression;
@@ -1362,6 +1363,31 @@ public function testWither()
13621363
$this->assertInstanceOf(Foo::class, $wither->foo);
13631364
}
13641365

1366+
/**
1367+
* @requires PHP 8
1368+
*/
1369+
public function testWitherWithStaticReturnType()
1370+
{
1371+
$container = new ContainerBuilder();
1372+
$container->register(Foo::class);
1373+
1374+
$container
1375+
->register('wither', WitherStaticReturnType::class)
1376+
->setPublic(true)
1377+
->setAutowired(true);
1378+
1379+
$container->compile();
1380+
$dumper = new PhpDumper($container);
1381+
$dump = $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Service_WitherStaticReturnType']);
1382+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_wither_staticreturntype.php', $dump);
1383+
eval('?>'.$dump);
1384+
1385+
$container = new \Symfony_DI_PhpDumper_Service_WitherStaticReturnType();
1386+
1387+
$wither = $container->get('wither');
1388+
$this->assertInstanceOf(Foo::class, $wither->foo);
1389+
}
1390+
13651391
/**
13661392
* @group legacy
13671393
*/
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
class WitherStaticReturnType
6+
{
7+
public $foo;
8+
9+
/**
10+
* @required
11+
*/
12+
public function withFoo(Foo $foo): static
13+
{
14+
$new = clone $this;
15+
$new->foo = $foo;
16+
17+
return $new;
18+
}
19+
20+
/**
21+
* @required
22+
* @return $this
23+
*/
24+
public function setFoo(Foo $foo): static
25+
{
26+
$this->foo = $foo;
27+
28+
return $this;
29+
}
30+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
4+
use Symfony\Component\DependencyInjection\ContainerInterface;
5+
use Symfony\Component\DependencyInjection\Container;
6+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
7+
use Symfony\Component\DependencyInjection\Exception\LogicException;
8+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
9+
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
10+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
11+
12+
/**
13+
* @internal This class has been auto-generated by the Symfony Dependency Injection Component.
14+
*/
15+
class Symfony_DI_PhpDumper_Service_WitherStaticReturnType extends Container
16+
{
17+
protected $parameters = [];
18+
19+
public function __construct()
20+
{
21+
$this->services = $this->privates = [];
22+
$this->methodMap = [
23+
'wither' => 'getWitherService',
24+
];
25+
26+
$this->aliases = [];
27+
}
28+
29+
public function compile(): void
30+
{
31+
throw new LogicException('You cannot compile a dumped container that was already compiled.');
32+
}
33+
34+
public function isCompiled(): bool
35+
{
36+
return true;
37+
}
38+
39+
public function getRemovedIds(): array
40+
{
41+
return [
42+
'Psr\\Container\\ContainerInterface' => true,
43+
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
44+
'Symfony\\Component\\DependencyInjection\\Tests\\Compiler\\Foo' => true,
45+
];
46+
}
47+
48+
/**
49+
* Gets the public 'wither' shared autowired service.
50+
*
51+
* @return \Symfony\Component\DependencyInjection\Tests\Compiler\WitherStaticReturnType
52+
*/
53+
protected function getWitherService()
54+
{
55+
$instance = new \Symfony\Component\DependencyInjection\Tests\Compiler\WitherStaticReturnType();
56+
57+
$a = new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo();
58+
59+
$this->services['wither'] = $instance = $instance->withFoo($a);
60+
$instance->setFoo($a);
61+
62+
return $instance;
63+
}
64+
}

0 commit comments

Comments
 (0)
0