Skip to content

Commit 0704e4e

Browse files
committed
bug symfony#54850 [VarExporter] fix ProxyHelper::generateLazyProxy() when a method returns null (nikophil)
This PR was merged into the 6.4 branch. Discussion ---------- [VarExporter] fix `ProxyHelper::generateLazyProxy()` when a method returns null | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | License | MIT When a methods has such a signature: ```php public function foo(): null ``` the method `ProxyHelper::generateLazyProxy()` produces a wrong code: ```php public function foo(): ?null ``` This PR fixes this. Commits ------- dc083fe [VarExporter] fix proxy helper when a method returns null
2 parents 3de527c + dc083fe commit 0704e4e

File tree

6 files changed

+77
-4
lines changed

6 files changed

+77
-4
lines changed

src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, arra
231231
if (isset($a[$prefix.'returnType'])) {
232232
$v = $a[$prefix.'returnType'];
233233
$v = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
234-
$a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType'] instanceof \ReflectionNamedType && $a[$prefix.'returnType']->allowsNull() && 'mixed' !== $v ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
234+
$a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType'] instanceof \ReflectionNamedType && $a[$prefix.'returnType']->allowsNull() && !\in_array($v, ['mixed', 'null'], true) ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
235235
}
236236
if (isset($a[$prefix.'class'])) {
237237
$a[$prefix.'class'] = new ClassStub($a[$prefix.'class']);
@@ -413,7 +413,7 @@ public static function getSignature(array $a)
413413
if (!$type instanceof \ReflectionNamedType) {
414414
$signature .= $type.' ';
415415
} else {
416-
if ($param->allowsNull() && 'mixed' !== $type->getName()) {
416+
if ($param->allowsNull() && !\in_array($type->getName(), ['mixed', 'null'], true)) {
417417
$signature .= '?';
418418
}
419419
$signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' ';

src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo;
1919
use Symfony\Component\VarDumper\Tests\Fixtures\LotsOfAttributes;
2020
use Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass;
21+
use Symfony\Component\VarDumper\Tests\Fixtures\Php82NullStandaloneReturnType;
2122
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionIntersectionTypeFixture;
2223
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionNamedTypeFixture;
2324
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionUnionTypeFixture;
@@ -95,7 +96,7 @@ public function testClosureCaster()
9596
$b: & 123
9697
}
9798
file: "%sReflectionCasterTest.php"
98-
line: "88 to 88"
99+
line: "%s"
99100
}
100101
EOTXT
101102
, $var
@@ -406,6 +407,26 @@ class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
406407
);
407408
}
408409

410+
/**
411+
* @requires PHP 8.2
412+
*/
413+
public function testNullReturnType()
414+
{
415+
$className = Php82NullStandaloneReturnType::class;
416+
417+
$this->assertDumpMatchesFormat(
418+
<<<EOTXT
419+
{$className}::foo(null \$bar): null {
420+
returnType: "null"
421+
this: {$className} { …}
422+
file: "%s"
423+
line: "%s"
424+
}
425+
EOTXT
426+
, (new Php82NullStandaloneReturnType())->foo(...)
427+
);
428+
}
429+
409430
public function testUnionReturnType()
410431
{
411432
$f = function (): int|float {};
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\VarDumper\Tests\Fixtures;
13+
14+
class Php82NullStandaloneReturnType
15+
{
16+
public function foo(null $bar): null
17+
{
18+
return null;
19+
}
20+
}

src/Symfony/Component/VarExporter/ProxyHelper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ public static function exportType(\ReflectionFunctionAbstract|\ReflectionPropert
311311
return '';
312312
}
313313
if (null === $glue) {
314-
return (!$noBuiltin && $type->allowsNull() && 'mixed' !== $name ? '?' : '').$types[0];
314+
return (!$noBuiltin && $type->allowsNull() && !\in_array($name, ['mixed', 'null'], true) ? '?' : '').$types[0];
315315
}
316316
sort($types);
317317

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\VarExporter\Tests\Fixtures\LazyProxy;
13+
14+
class Php82NullStandaloneReturnType
15+
{
16+
public function foo(): null
17+
{
18+
return null;
19+
}
20+
}

src/Symfony/Component/VarExporter/Tests/ProxyHelperTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\VarExporter\Exception\LogicException;
1616
use Symfony\Component\VarExporter\ProxyHelper;
17+
use Symfony\Component\VarExporter\Tests\Fixtures\LazyProxy\Php82NullStandaloneReturnType;
1718
use Symfony\Component\VarExporter\Tests\Fixtures\LazyProxy\StringMagicGetClass;
1819

1920
class ProxyHelperTest extends TestCase
@@ -188,6 +189,17 @@ public function testCannotGenerateGhostForStringMagicGet()
188189
$this->expectException(LogicException::class);
189190
ProxyHelper::generateLazyGhost(new \ReflectionClass(StringMagicGetClass::class));
190191
}
192+
193+
/**
194+
* @requires PHP 8.2
195+
*/
196+
public function testNullStandaloneReturnType()
197+
{
198+
self::assertStringContainsString(
199+
'public function foo(): null',
200+
ProxyHelper::generateLazyProxy(new \ReflectionClass(Php82NullStandaloneReturnType::class))
201+
);
202+
}
191203
}
192204

193205
abstract class TestForProxyHelper

0 commit comments

Comments
 (0)