Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f9d22ec

Browse files
[VarDumper] Add casters for Reflection* classes
1 parent 8bee26f commit f9d22ec

File tree

6 files changed

+654
-25
lines changed

6 files changed

+654
-25
lines changed

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

Lines changed: 205 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,221 @@
2020
*/
2121
class ReflectionCaster
2222
{
23+
private static $extraMap = array(
24+
'docComment' => 'getDocComment',
25+
'extension' => 'getExtensionName',
26+
'isDisabled' => 'isDisabled',
27+
'isDeprecated' => 'isDeprecated',
28+
'isInternal' => 'isInternal',
29+
'isUserDefined' => 'isUserDefined',
30+
'isGenerator' => 'isGenerator',
31+
'isVariadic' => 'isVariadic',
32+
);
33+
34+
/**
35+
* @deprecated since Symfony 2.7, to be removed in 3.0.
36+
*/
2337
public static function castReflector(\Reflector $c, array $a, Stub $stub, $isNested)
2438
{
25-
$a["\0~\0reflection"] = $c->__toString();
39+
trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
40+
$a[Caster::PREFIX_VIRTUAL.'reflection'] = $c->__toString();
2641

2742
return $a;
2843
}
2944

3045
public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested)
3146
{
47+
$p = Caster::PREFIX_VIRTUAL;
48+
$c = new \ReflectionFunction($c);
49+
3250
$stub->class = 'Closure'; // HHVM generates unique class names for closures
33-
$a = static::castReflector(new \ReflectionFunction($c), $a, $stub, $isNested);
34-
unset($a["\0+\0000"], $a['name'], $a["\0+\0this"], $a["\0+\0parameter"]);
51+
$a = static::castFunctionAbstract($c, $a, $stub, $isNested);
52+
53+
if (isset($a[$p.'parameters'])) {
54+
foreach ($a[$p.'parameters'] as &$v) {
55+
$param = $v;
56+
$v = array();
57+
foreach (static::castParameter($param, array(), $stub, true) as $k => $param) {
58+
if ("\0" === $k[0]) {
59+
$v[substr($k, 3)] = $param;
60+
}
61+
}
62+
unset($v['position'], $v['isVariadic'], $v['byReference'], $v);
63+
}
64+
}
65+
66+
if ($f = $c->getFileName()) {
67+
$a[$p.'file'] = $f;
68+
$a[$p.'line'] = $c->getStartLine().' to '.$c->getEndLine();
69+
}
70+
71+
$p = Caster::PREFIX_DYNAMIC;
72+
unset($a['name'], $a[$p.'0'], $a[$p.'this'], $a[$p.'parameter'], $a[Caster::PREFIX_VIRTUAL.'extra']);
73+
74+
return $a;
75+
}
76+
77+
public static function castClass(\ReflectionClass $c, array $a, Stub $stub, $isNested, $filter = 0)
78+
{
79+
$p = Caster::PREFIX_VIRTUAL;
80+
81+
if ($n = \Reflection::getModifierNames($c->getModifiers())) {
82+
$a[$p.'modifiers'] = implode(' ', $n);
83+
}
84+
85+
self::addMap($a, $c, array(
86+
'extends' => 'getParentClass',
87+
'implements' => 'getInterfaceNames',
88+
'constants' => 'getConstants',
89+
));
90+
91+
foreach ($c->getProperties() as $n) {
92+
$a[$p.'properties'][$n->name] = $n;
93+
}
94+
95+
foreach ($c->getMethods() as $n) {
96+
$a[$p.'methods'][$n->name] = $n;
97+
}
98+
99+
if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
100+
self::addExtra($a, $c);
101+
}
35102

36103
return $a;
37104
}
105+
106+
public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, array $a, Stub $stub, $isNested, $filter = 0)
107+
{
108+
$p = Caster::PREFIX_VIRTUAL;
109+
110+
self::addMap($a, $c, array(
111+
'returnsReference' => 'returnsReference',
112+
'class' => 'getClosureScopeClass',
113+
'this' => 'getClosureThis',
114+
));
115+
116+
if (isset($a[$p.'this'])) {
117+
$a[$p.'this'] = new CutStub($a[$p.'this']);
118+
}
119+
120+
foreach ($c->getParameters() as $v) {
121+
$k = '$'.$v->name;
122+
if ($v->isPassedByReference()) {
123+
$k = '&'.$k;
124+
}
125+
if (method_exists($v, 'isVariadic') && $v->isVariadic()) {
126+
$k = '...'.$k;
127+
}
128+
$a[$p.'parameters'][$k] = $v;
129+
}
130+
131+
if ($v = $c->getStaticVariables()) {
132+
foreach ($v as $k => &$v) {
133+
$a[$p.'use']['$'.$k] =& $v;
134+
}
135+
unset($v);
136+
}
137+
138+
if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
139+
self::addExtra($a, $c);
140+
}
141+
142+
return $a;
143+
}
144+
145+
public static function castMethod(\ReflectionMethod $c, array $a, Stub $stub, $isNested)
146+
{
147+
$a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
148+
149+
return $a;
150+
}
151+
152+
public static function castParameter(\ReflectionParameter $c, array $a, Stub $stub, $isNested)
153+
{
154+
$p = Caster::PREFIX_VIRTUAL;
155+
156+
self::addMap($a, $c, array(
157+
'position' => 'getPosition',
158+
'isVariadic' => 'isVariadic',
159+
'byReference' => 'isPassedByReference',
160+
));
161+
162+
try {
163+
if ($c->isArray()) {
164+
$a[$p.'typeHint'] = 'array';
165+
} elseif (method_exists($c, 'isCallable') && $c->isCallable()) {
166+
$a[$p.'typeHint'] = 'callable';
167+
} elseif ($v = $c->getClass()) {
168+
$a[$p.'typeHint'] = $v->name;
169+
}
170+
} catch (\ReflectionException $e) {
171+
}
172+
173+
try {
174+
$a[$p.'default'] = $v = $c->getDefaultValue();
175+
if (method_exists($c, 'isDefaultValueConstant') && $c->isDefaultValueConstant()) {
176+
$a[$p.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v);
177+
}
178+
} catch (\ReflectionException $e) {
179+
}
180+
181+
return $a;
182+
}
183+
184+
public static function castProperty(\ReflectionProperty $c, array $a, Stub $stub, $isNested)
185+
{
186+
$a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
187+
self::addExtra($a, $c);
188+
189+
return $a;
190+
}
191+
192+
public static function castExtension(\ReflectionExtension $c, array $a, Stub $stub, $isNested)
193+
{
194+
self::addMap($a, $c, array(
195+
'version' => 'getVersion',
196+
'dependencies' => 'getDependencies',
197+
'iniEntries' => 'getIniEntries',
198+
'isPersistent' => 'isPersistent',
199+
'isTemporary' => 'isTemporary',
200+
'constants' => 'getConstants',
201+
'functions' => 'getFunctions',
202+
'classes' => 'getClasses',
203+
));
204+
205+
return $a;
206+
}
207+
208+
public static function castZendExtension(\ReflectionZendExtension $c, array $a, Stub $stub, $isNested)
209+
{
210+
self::addMap($a, $c, array(
211+
'version' => 'getVersion',
212+
'author' => 'getAuthor',
213+
'copyright' => 'getCopyright',
214+
'url' => 'getURL',
215+
));
216+
217+
return $a;
218+
}
219+
220+
private static function addExtra(&$a, \Reflector $c)
221+
{
222+
$a =& $a[Caster::PREFIX_VIRTUAL.'extra'];
223+
224+
if (method_exists($c, 'getFileName') && $m = $c->getFileName()) {
225+
$a['file'] = $m;
226+
$a['line'] = $c->getStartLine().' to '.$c->getEndLine();
227+
}
228+
229+
self::addMap($a, $c, self::$extraMap, '');
230+
}
231+
232+
private static function addMap(&$a, \Reflector $c, $map, $p = Caster::PREFIX_VIRTUAL)
233+
{
234+
foreach ($map as $k => $m) {
235+
if (method_exists($c, $m) && false !== ($m = $c->$m()) && null !== $m) {
236+
$a[$p.$k] = $m instanceof \Reflector ? $m->name : $m;
237+
}
238+
}
239+
}
38240
}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,13 @@ abstract class AbstractCloner implements ClonerInterface
2525
'Symfony\Component\VarDumper\Caster\ConstStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub',
2626

2727
'Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure',
28-
'Reflector' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castReflector',
28+
'ReflectionClass' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClass',
29+
'ReflectionFunctionAbstract' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castFunctionAbstract',
30+
'ReflectionMethod' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castMethod',
31+
'ReflectionParameter' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castParameter',
32+
'ReflectionProperty' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castProperty',
33+
'ReflectionExtension' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castExtension',
34+
'ReflectionZendExtension' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castZendExtension',
2935

3036
'Doctrine\Common\Persistence\ObjectManager' => 'Symfony\Component\VarDumper\Caster\StubCaster::cutInternals',
3137
'Doctrine\Common\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castCommonProxy',
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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\Caster;
13+
14+
use Symfony\Component\VarDumper\Cloner\VarCloner;
15+
use Symfony\Component\VarDumper\Dumper\CliDumper;
16+
use Symfony\Component\VarDumper\Test\VarDumperTestCase;
17+
18+
/**
19+
* @author Nicolas Grekas <[email protected]>
20+
*/
21+
class ReflectionCasterTest extends VarDumperTestCase
22+
{
23+
public function testReflectionCaster()
24+
{
25+
$var = new \ReflectionClass('ReflectionClass');
26+
27+
$fixture = file_get_contents(__DIR__.'/../Fixtures/reflection-class.dump');
28+
$this->assertDumpEquals($fixture, $var);
29+
}
30+
}

src/Symfony/Component/VarDumper/Tests/CliDumperTest.php

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ public function testGet()
3838
ob_start();
3939
$dumper->dump($data);
4040
$out = ob_get_clean();
41-
$closureLabel = PHP_VERSION_ID >= 50400 ? 'public method' : 'function';
4241
$out = preg_replace('/[ \t]+$/m', '', $out);
4342
$intMax = PHP_INT_MAX;
4443
$res1 = (int) $var['res'];
@@ -76,16 +75,17 @@ public function testGet()
7675
+"bar": "bar"
7776
}
7877
"closure" => Closure {#%d
79-
reflection: """
80-
Closure [ <user> {$closureLabel} Symfony\Component\VarDumper\Tests\Fixture\{closure} ] {
81-
@@ {$var['file']} {$var['line']} - {$var['line']}
82-
83-
- Parameters [2] {
84-
Parameter #0 [ <required> \$a ]
85-
Parameter #1 [ <optional> PDO or NULL &\$b = NULL ]
86-
}
87-
}
88-
"""
78+
class: "Symfony\Component\VarDumper\Tests\CliDumperTest"
79+
this: Symfony\Component\VarDumper\Tests\CliDumperTest {#%d …}
80+
parameters: array:2 [
81+
"\$a" => []
82+
"&\$b" => array:2 [
83+
"typeHint" => "PDO"
84+
"default" => null
85+
]
86+
]
87+
file: "{$var['file']}"
88+
line: "{$var['line']} to {$var['line']}"
8989
}
9090
"line" => {$var['line']}
9191
"nobj" => array:1 [

0 commit comments

Comments
 (0)