8000 [VarDumper] Support for ReflectionAttribute. · symfony/symfony@6225dc2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6225dc2

Browse files
committed
[VarDumper] Support for ReflectionAttribute.
1 parent 4b3015f commit 6225dc2

File tree

6 files changed

+331
-4
lines changed

6 files changed

+331
-4
lines changed

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

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ public static function castType(\ReflectionType $c, array $a, Stub $stub, $isNes
9999
return $a;
100100
}
101101

102+
public static function castAttribute(\ReflectionAttribute $c, array $a, Stub $tsub, $isNested)
103+
{
104+
self::addMap($a, $c, [
105+
'name' => 'getName',
106+
'arguments' => 'getArguments',
107+
]);
108+
109+
return $a;
110+
}
111+
102112
public static function castReflectionGenerator(\ReflectionGenerator $c, array $a, Stub $stub, $isNested)
103113
{
104114
$prefix = Caster::PREFIX_VIRTUAL;
@@ -147,7 +157,7 @@ public static function castClass(\ReflectionClass $c, array $a, Stub $stub, $isN
147157
self::addMap($a, $c, [
148158
'extends' => 'getParentClass',
149159
'implements' => 'getInterfaceNames',
150-
'constants' => 'getConstants',
160+
'constants' => method_exists($c, 'getReflectionConstants') ? 'getReflectionConstants' : 'getConstants',
151161
]);
152162

153163
foreach ($c->getProperties() as $n) {
@@ -158,6 +168,8 @@ public static function castClass(\ReflectionClass $c, array $a, Stub $stub, $isN
158168
$a[$prefix.'methods'][$n->name] = $n;
159169
}
160170

171+
self::addAttributes($a, $c, $prefix);
172+
161173
if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
162174
self::addExtra($a, $c);
163175
}
@@ -202,6 +214,8 @@ public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, arra
202214
$a[$prefix.'parameters'] = new EnumStub($a[$prefix.'parameters']);
203215
}
204216

217+
self::addAttributes($a, $c, $prefix);
218+
205219
if ($v = $c->getStaticVariables()) {
206220
foreach ($v as $k => &$v) {
207221
if (\is_object($v)) {
@@ -224,6 +238,16 @@ public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, arra
224238
return $a;
225239
}
226240

241+
public static function castClassConstant(\ReflectionClassConstant $c, array $a, Stub $stub, $isNested)
242+
{
243+
$a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
244+
$a[Caster::PREFIX_VIRTUAL.'value'] = $c->getValue();
245+
246+
self::addAttributes($a, $c);
247+
248+
return $a;
249+
}
250+
227251
public static function castMethod(\ReflectionMethod $c, array $a, Stub $stub, $isNested)
228252
{
229253
$a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
@@ -245,6 +269,8 @@ public static function castParameter(\ReflectionParameter $c, array $a, Stub $st
245269
'allowsNull' => 'allowsNull',
246270
]);
247271

272+
self::addAttributes($a, $c, $prefix);
273+
248274
if (method_exists($c, 'getType')) {
249275
if ($v = $c->getType()) {
250276
$a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : (string) $v;
@@ -281,6 +307,8 @@ public static function castParameter(\ReflectionParameter $c, array $a, Stub $st
281307
public static function castProperty(\ReflectionProperty $c, array $a, Stub $stub, $isNested)
282308
{
283309
$a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
310+
311+
self::addAttributes($a, $c);
284312
self::addExtra($a, $c);
285313

286314
return $a;
@@ -330,7 +358,10 @@ private static function addExtra(&$a, \Reflector $c)
330358
}
331359
}
332360

333-
private static function addMap(&$a, \Reflector $c, $map, $prefix = Caster::PREFIX_VIRTUAL)
361+
/**
362+
* @param \Reflector|\ReflectionAttribute $c
363+
*/
364+
private static function addMap(array &$a, $c, $map, $prefix = Caster::PREFIX_VIRTUAL)
334365
{
335366
foreach ($map as $k => $m) {
336367
if (\PHP_VERSION_ID >= 80000 && 'isDisabled' === $k) {
@@ -342,4 +373,16 @@ private static function addMap(&$a, \Reflector $c, $map, $prefix = Caster::PREFI
342373
}
343374
}
344375
}
376+
377+
/**
378+
* @param string $prefix
379+
*/
380+
private static function addAttributes(array &$a, \Reflector $c, $prefix = Caster::PREFIX_VIRTUAL)
381+
{
382+
if (\PHP_VERSION_ID >= 80000) {
383+
foreach ($c->getAttributes() as $n) {
384+
$a[$prefix.'attributes'][] = $n;
385+
}
386+
}
387+
}
345388
}

src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ abstract class AbstractCloner implements ClonerInterface
3232
'Closure' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClosure'],
3333
'Generator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castGenerator'],
3434
'ReflectionType' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castType'],
35+
'ReflectionAttribute' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castAttribute'],
3536
'ReflectionGenerator' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castReflectionGenerator'],
3637
'ReflectionClass' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClass'],
38+
'ReflectionClassConstant' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castClassConstant'],
3739
'ReflectionFunctionAbstract' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castFunctionAbstract'],
3840
'ReflectionMethod' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castMethod'],
3941
'ReflectionParameter' => ['Symfony\Component\VarDumper\Caster\ReflectionCaster', 'castParameter'],

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

Lines changed: 192 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\VarDumper\Caster\Caster;
1616
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
1717
use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo;
18+
use Symfony\Component\VarDumper\Tests\Fixtures\LotsOfAttributes;
1819
use Symfony\Component\VarDumper\Tests\Fixtures\NotLoadableClass;
1920

2021
/**
@@ -24,8 +25,12 @@ class ReflectionCasterTest extends TestCase
2425
{
2526
use VarDumperTestTrait;
2627

27-
public function testReflectionCaster()
28+
public function testReflectionCasterPhp5()
2829
{
30+
if (\PHP_VERSION_ID >= 70100) {
31+
$this->markTestSkipped('This test requires php 7.0 or lower.');
32+
}
33+
2934
$var = new \ReflectionClass('ReflectionClass');
3035

3136
$this->assertDumpMatchesFormat(
@@ -62,6 +67,62 @@ public function testReflectionCaster()
6267
);
6368
}
6469

70+
/**
71+
* @requires PHP 7.1
72+
*/
73+
public function testReflectionCaster()
74+
{
75+
$var = new \ReflectionClass('ReflectionClass');
76+
77+
$this->assertDumpMatchesFormat(
78+
<<<'EOTXT'
79+
ReflectionClass {
80+
+name: "ReflectionClass"
81+
%Aimplements: array:%d [
82+
0 => "Reflector"
83+
%A]
84+
constants: array:3 [
85+
0 => ReflectionClassConstant {
86+
+name: "IS_IMPLICIT_ABSTRACT"
87+
+class: "ReflectionClass"
88+
modifiers: "public"
89+
value: 16
90+
}
91+
1 => ReflectionClassConstant {
92+
+name: "IS_EXPLICIT_ABSTRACT"
93+
+class: "ReflectionClass"
94+
modifiers: "public"
95+
value: %d
96+
}
97+
2 => ReflectionClassConstant {
98+
+name: "IS_FINAL"
99+
+class: "ReflectionClass"
100+
modifiers: "public"
101+
value: %d
102+
}
103+
]
104+
properties: array:%d [
105+
"name" => ReflectionProperty {
106+
%A +name: "name"
107+
+class: "ReflectionClass"
108+
%A modifiers: "public"
109+
}
110+
%A]
111+
methods: array:%d [
112+
%A
113+
"__construct" => ReflectionMethod {
114+
+name: "__construct"
115+
+class: "ReflectionClass"
116+
%A parameters: {
117+
$%s: ReflectionParameter {
118+
%A position: 0
119+
%A
120+
}
121+
EOTXT
122+
, $var
123+
);
124+
}
125+
65126
public function testClosureCaster()
66127
{
67128
$a = $b = 123;
@@ -78,7 +139,7 @@ public function testClosureCaster()
78139
\$b: & 123
79140
}
80141
file: "%sReflectionCasterTest.php"
81-
line: "68 to 68"
142+
line: "129 to 129"
82143
}
83144
EOTXT
84145
, $var
@@ -263,6 +324,135 @@ public function testGenerator()
263324
EODUMP;
264325
$this->assertDumpMatchesFormat($expectedDump, $generator);
265326
}
327+
328+
/**
329+
* @requires PHP 8
330+
*/
331+
public function testReflectionClassWithAttribute()
332+
{
333+
$var = new \ReflectionClass(LotsOfAttributes::class);
334+
335+
$this->assertDumpMatchesFormat(<<< 'EOTXT'
336+
ReflectionClass {
337+
+name: "Symfony\Component\VarDumper\Tests\Fixtures\LotsOfAttributes"
338+
%A attributes: array:1 [
339+
0 => ReflectionAttribute {
340+
name: "Symfony\Component\VarDumper\Tests\Fixtures\MyAttribute"
341+
arguments: []
342+
}
343+
]
344+
%A
345+
}
346+
EOTXT
347+
, $var);
348+
}
349+
350+
/**
351+
* @requires PHP 8
352+
*/
353+
public function testReflectionMethodWithAttribute()
354+
{
355+
$var = new \ReflectionMethod(LotsOfAttributes::class, 'someMethod');
356+
357+
$this->assertDumpMatchesFormat(<<< 'EOTXT'
358+
ReflectionMethod {
359+
+name: "someMethod"
360+
+class: "Symfony\Component\VarDumper\Tests\Fixtures\LotsOfAttributes"
361+
%A attributes: array:1 [
362+
0 => ReflectionAttribute {
363+
name: "Symfony\Component\VarDumper\Tests\Fixtures\MyAttribute"
364+
arguments: array:1 [
365+
0 => "two"
366+
]
367+
}
368+
]
369+
%A
370+
}
371+
EOTXT
372+
, $var);
373+
}
374+
375+
/**
376+
* @requires PHP 8
377+
*/
378+
public function testReflectionPropertyWithAttribute()
379+
{
380+
$var = new \ReflectionProperty(LotsOfAttributes::class, 'someProperty');
381+
382+
$this->assertDumpMatchesFormat(<<< 'EOTXT'
383+
ReflectionProperty {
384+
+name: "someProperty"
385+
+class: "Symfony\Component\VarDumper\Tests\Fixtures\LotsOfAttributes"
386+
%A attributes: array:1 [
387+
0 => ReflectionAttribute {
388+
name: "Symfony\Component\VarDumper\Tests\Fixtures\MyAttribute"
389+
arguments: array:2 [
390+
0 => "one"
391+
"extra" => "hello"
392+
]
393+
}
394+
]
395+
}
396+
EOTXT
397+
, $var);
398+
}
399+
400+
/**
401+
* @requires PHP 8
402+
*/
403+
public function testReflectionClassConstantWithAttribute()
404+
{
405+
$var = new \ReflectionClassConstant(LotsOfAttributes::class, 'SOME_CONSTANT');
406+
407+
$this->assertDumpMatchesFormat(<<< 'EOTXT'
408+
ReflectionClassConstant {
409+
+name: "SOME_CONSTANT"
410+
+class: "Symfony\Component\VarDumper\Tests\Fixtures\LotsOfAttributes"
411+
modifiers: "public"
412+
value: "some value"
413+
attributes: array:2 [
414+
0 => ReflectionAttribute {
415+
name: "Symfony\Component\VarDumper\Tests\Fixtures\RepeatableAttribute"
416+
arguments: array:1 [
417+
0 => "one"
418+
]
419+
}
420+
1 => ReflectionAttribute {
421+
name: "Symfony\Component\VarDumper\Tests\Fixtures\RepeatableAttribute"
422+
arguments: array:1 [
423+
0 => "two"
424+
]
425+
}
426+
]
427+
}
428+
EOTXT
429+
, $var);
430+
}
431+
432+
/**
433+
* @requires PHP 8
434+
*/
435+
public function testReflectionParameterWithAttribute()
436+
{
437+
$var = new \ReflectionParameter([LotsOfAttributes::class, 'someMethod'], 'someParameter');
438+
439+
$this->assertDumpMatchesFormat(<<< 'EOTXT'
440+
ReflectionParameter {
441+
+name: "someParameter"
442+
position: 0
443+
attributes: array:1 [
444+
0 => ReflectionAttribute {
445+
name: "Symfony\Component\VarDumper\Tests\Fixtures\MyAttribute"
446+
arguments: array:1 [
447+
0 => "three"
448+
]
449+
}
450+
]
451+
%A
452+
}
453+
EOTXT
454+
, $var);
455+
}
266456
}
267457

268458
function reflectionParameterFixture(NotLoadableClass $arg1 = null, $arg2)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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+
#[MyAttribute]
15+
final class LotsOfAttributes
16+
{
17+
#[RepeatableAttribute('one'), RepeatableAttribute('two')]
18+
public const SOME_CONSTANT = 'some value';
19+
20+
#[MyAttribute('one', extra: 'hello')]
21+
private string $someProperty;
22+
23+
#[MyAttribute('two')]
24+
public function someMethod(
25+
#[MyAttribute('three')] string $someParameter
26+
): void {
27+
}
28+
}

0 commit comments

Comments
 (0)
0