bug #40453 [VarDumper] Adds support for ReflectionUnionType to VarDumper (Michael Nelson, michaeldnelson)
This PR was squashed before being merged into the 4.4 branch.
Discussion
----------
[VarDumper] Adds support for ReflectionUnionType to VarDumper
Fixes a bug with VarDumper when dumping a ReflectionUnionType.
> PHP Error: Call to undefined method ReflectionUnionType::isBuiltin()
Notes:
* One of the existing tests relies on its position in the test file. I had to modify its expected line number.
* There is an existing trailing space around line 367 in an expected value.
I'm not sure if this was left for BC reasons but it seems like a bug if the dumper is leaving trailing spaces.
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
This commit fixes a crash when dumping ReflectionUnionType. The code is minimal but uses a few extra lines to preserve key order for bc and consistency. Additionally, there is an else condition that is currently unreachable but is defensive should they add additional subtypes of ReflectionType. Tests are included. Please let me know if you have any questions or suggestions. Thanks for Symfony it's a wonderful project.
Commits
-------
1a11491f6e
[VarDumper] Adds support for ReflectionUnionType to VarDumper
This commit is contained in:
commit
550489aa8e
@ -96,11 +96,20 @@ class ReflectionCaster
|
||||
{
|
||||
$prefix = Caster::PREFIX_VIRTUAL;
|
||||
|
||||
$a += [
|
||||
$prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : (string) $c,
|
||||
$prefix.'allowsNull' => $c->allowsNull(),
|
||||
$prefix.'isBuiltin' => $c->isBuiltin(),
|
||||
];
|
||||
if ($c instanceof \ReflectionNamedType || \PHP_VERSION_ID < 80000) {
|
||||
$a += [
|
||||
$prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : (string) $c,
|
||||
$prefix.'allowsNull' => $c->allowsNull(),
|
||||
$prefix.'isBuiltin' => $c->isBuiltin(),
|
||||
];
|
||||
} elseif ($c instanceof \ReflectionUnionType) {
|
||||
$a[$prefix.'allowsNull'] = $c->allowsNull();
|
||||
self::addMap($a, $c, [
|
||||
'types' => 'getTypes',
|
||||
]);
|
||||
} else {
|
||||
$a[$prefix.'allowsNull'] = $c->allowsNull();
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
@ -377,7 +386,7 @@ class ReflectionCaster
|
||||
}
|
||||
}
|
||||
|
||||
private static function addMap(array &$a, \Reflector $c, array $map, string $prefix = Caster::PREFIX_VIRTUAL)
|
||||
private static function addMap(array &$a, $c, array $map, string $prefix = Caster::PREFIX_VIRTUAL)
|
||||
{
|
||||
foreach ($map as $k => $m) {
|
||||
if (\PHP_VERSION_ID >= 80000 && 'isDisabled' === $k) {
|
||||
|
@ -14,8 +14,11 @@ namespace Symfony\Component\VarDumper\Tests\Caster;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\VarDumper\Caster\Caster;
|
||||
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
|
||||
use Symfony\Component\VarDumper\Tests\Fixtures\ExtendsReflectionTypeFixture;
|
||||
use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo;
|
||||
use Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass;
|
||||
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionNamedTypeFixture;
|
||||
use Symfony\Component\VarDumper\Tests\Fixtures\ReflectionUnionTypeFixture;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
@ -75,7 +78,7 @@ Closure($x) {
|
||||
$b: & 123
|
||||
}
|
||||
file: "%sReflectionCasterTest.php"
|
||||
line: "68 to 68"
|
||||
line: "71 to 71"
|
||||
}
|
||||
EOTXT
|
||||
, $var
|
||||
@ -211,6 +214,104 @@ EOTXT
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7.4
|
||||
*/
|
||||
public function testReflectionPropertyScalar()
|
||||
{
|
||||
$var = new \ReflectionProperty(ReflectionNamedTypeFixture::class, 'a');
|
||||
$this->assertDumpMatchesFormat(
|
||||
<<<'EOTXT'
|
||||
ReflectionProperty {
|
||||
+name: "a"
|
||||
+class: "Symfony\Component\VarDumper\Tests\Fixtures\ReflectionNamedTypeFixture"
|
||||
modifiers: "public"
|
||||
}
|
||||
EOTXT
|
||||
, $var
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7.4
|
||||
*/
|
||||
public function testReflectionNamedType()
|
||||
{
|
||||
$var = (new \ReflectionProperty(ReflectionNamedTypeFixture::class, 'a'))->getType();
|
||||
$this->assertDumpMatchesFormat(
|
||||
<<<'EOTXT'
|
||||
ReflectionNamedType {
|
||||
name: "int"
|
||||
allowsNull: false
|
||||
isBuiltin: true
|
||||
}
|
||||
EOTXT
|
||||
, $var
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 8
|
||||
*/
|
||||
public function testReflectionUnionType()
|
||||
{
|
||||
$var = (new \ReflectionProperty(ReflectionUnionTypeFixture::class, 'a'))->getType();
|
||||
$this->assertDumpMatchesFormat(
|
||||
<<<'EOTXT'
|
||||
ReflectionUnionType {
|
||||
allowsNull: false
|
||||
types: array:2 [
|
||||
0 => ReflectionNamedType {
|
||||
name: "string"
|
||||
allowsNull: false
|
||||
isBuiltin: true
|
||||
}
|
||||
1 => ReflectionNamedType {
|
||||
name: "int"
|
||||
allowsNull: false
|
||||
isBuiltin: true
|
||||
}
|
||||
]
|
||||
}
|
||||
EOTXT
|
||||
, $var
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 8
|
||||
*/
|
||||
public function testExtendsReflectionType()
|
||||
{
|
||||
$var = new ExtendsReflectionTypeFixture();
|
||||
$this->assertDumpMatchesFormat(
|
||||
<<<'EOTXT'
|
||||
Symfony\Component\VarDumper\Tests\Fixtures\ExtendsReflectionTypeFixture {
|
||||
allowsNull: false
|
||||
}
|
||||
EOTXT
|
||||
, $var
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP < 8
|
||||
*/
|
||||
public function testLegacyExtendsReflectionType()
|
||||
{
|
||||
$var = new ExtendsReflectionTypeFixture();
|
||||
$this->assertDumpMatchesFormat(
|
||||
<<<'EOTXT'
|
||||
Symfony\Component\VarDumper\Tests\Fixtures\ExtendsReflectionTypeFixture {
|
||||
name: "fake"
|
||||
allowsNull: false
|
||||
isBuiltin: false
|
||||
}
|
||||
EOTXT
|
||||
, $var
|
||||
);
|
||||
}
|
||||
|
||||
public function testReturnType()
|
||||
{
|
||||
$f = eval('return function ():int {};');
|
||||
|
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\VarDumper\Tests\Fixtures;
|
||||
|
||||
class ExtendsReflectionTypeFixture extends \ReflectionType
|
||||
{
|
||||
public function allowsNull(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isBuiltin(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return 'fake';
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\VarDumper\Tests\Fixtures;
|
||||
|
||||
class ReflectionNamedTypeFixture
|
||||
{
|
||||
public int $a;
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\VarDumper\Tests\Fixtures;
|
||||
|
||||
class ReflectionUnionTypeFixture
|
||||
{
|
||||
public int|string $a;
|
||||
}
|
Reference in New Issue
Block a user