Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /*
|
Chris@0
|
4 * This file is part of the Symfony package.
|
Chris@0
|
5 *
|
Chris@0
|
6 * (c) Fabien Potencier <fabien@symfony.com>
|
Chris@0
|
7 *
|
Chris@0
|
8 * For the full copyright and license information, please view the LICENSE
|
Chris@0
|
9 * file that was distributed with this source code.
|
Chris@0
|
10 */
|
Chris@0
|
11
|
Chris@0
|
12 namespace Symfony\Component\VarDumper\Caster;
|
Chris@0
|
13
|
Chris@0
|
14 use Symfony\Component\VarDumper\Cloner\Stub;
|
Chris@0
|
15
|
Chris@0
|
16 /**
|
Chris@0
|
17 * Casts Reflector related classes to array representation.
|
Chris@0
|
18 *
|
Chris@0
|
19 * @author Nicolas Grekas <p@tchwork.com>
|
Chris@0
|
20 */
|
Chris@0
|
21 class ReflectionCaster
|
Chris@0
|
22 {
|
Chris@17
|
23 private static $extraMap = [
|
Chris@0
|
24 'docComment' => 'getDocComment',
|
Chris@0
|
25 'extension' => 'getExtensionName',
|
Chris@0
|
26 'isDisabled' => 'isDisabled',
|
Chris@0
|
27 'isDeprecated' => 'isDeprecated',
|
Chris@0
|
28 'isInternal' => 'isInternal',
|
Chris@0
|
29 'isUserDefined' => 'isUserDefined',
|
Chris@0
|
30 'isGenerator' => 'isGenerator',
|
Chris@0
|
31 'isVariadic' => 'isVariadic',
|
Chris@17
|
32 ];
|
Chris@0
|
33
|
Chris@0
|
34 public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested, $filter = 0)
|
Chris@0
|
35 {
|
Chris@0
|
36 $prefix = Caster::PREFIX_VIRTUAL;
|
Chris@0
|
37 $c = new \ReflectionFunction($c);
|
Chris@0
|
38
|
Chris@0
|
39 $stub->class = 'Closure'; // HHVM generates unique class names for closures
|
Chris@0
|
40 $a = static::castFunctionAbstract($c, $a, $stub, $isNested, $filter);
|
Chris@0
|
41
|
Chris@17
|
42 if (false === strpos($c->name, '{closure}')) {
|
Chris@17
|
43 $stub->class = isset($a[$prefix.'class']) ? $a[$prefix.'class']->value.'::'.$c->name : $c->name;
|
Chris@17
|
44 unset($a[$prefix.'class']);
|
Chris@17
|
45 }
|
Chris@17
|
46
|
Chris@0
|
47 if (isset($a[$prefix.'parameters'])) {
|
Chris@0
|
48 foreach ($a[$prefix.'parameters']->value as &$v) {
|
Chris@0
|
49 $param = $v;
|
Chris@17
|
50 $v = new EnumStub([]);
|
Chris@17
|
51 foreach (static::castParameter($param, [], $stub, true) as $k => $param) {
|
Chris@0
|
52 if ("\0" === $k[0]) {
|
Chris@0
|
53 $v->value[substr($k, 3)] = $param;
|
Chris@0
|
54 }
|
Chris@0
|
55 }
|
Chris@0
|
56 unset($v->value['position'], $v->value['isVariadic'], $v->value['byReference'], $v);
|
Chris@0
|
57 }
|
Chris@0
|
58 }
|
Chris@0
|
59
|
Chris@0
|
60 if (!($filter & Caster::EXCLUDE_VERBOSE) && $f = $c->getFileName()) {
|
Chris@0
|
61 $a[$prefix.'file'] = new LinkStub($f, $c->getStartLine());
|
Chris@0
|
62 $a[$prefix.'line'] = $c->getStartLine().' to '.$c->getEndLine();
|
Chris@0
|
63 }
|
Chris@0
|
64
|
Chris@0
|
65 $prefix = Caster::PREFIX_DYNAMIC;
|
Chris@0
|
66 unset($a['name'], $a[$prefix.'this'], $a[$prefix.'parameter'], $a[Caster::PREFIX_VIRTUAL.'extra']);
|
Chris@0
|
67
|
Chris@0
|
68 return $a;
|
Chris@0
|
69 }
|
Chris@0
|
70
|
Chris@0
|
71 public static function castGenerator(\Generator $c, array $a, Stub $stub, $isNested)
|
Chris@0
|
72 {
|
Chris@0
|
73 if (!class_exists('ReflectionGenerator', false)) {
|
Chris@0
|
74 return $a;
|
Chris@0
|
75 }
|
Chris@0
|
76
|
Chris@0
|
77 // Cannot create ReflectionGenerator based on a terminated Generator
|
Chris@0
|
78 try {
|
Chris@0
|
79 $reflectionGenerator = new \ReflectionGenerator($c);
|
Chris@0
|
80 } catch (\Exception $e) {
|
Chris@0
|
81 $a[Caster::PREFIX_VIRTUAL.'closed'] = true;
|
Chris@0
|
82
|
Chris@0
|
83 return $a;
|
Chris@0
|
84 }
|
Chris@0
|
85
|
Chris@0
|
86 return self::castReflectionGenerator($reflectionGenerator, $a, $stub, $isNested);
|
Chris@0
|
87 }
|
Chris@0
|
88
|
Chris@0
|
89 public static function castType(\ReflectionType $c, array $a, Stub $stub, $isNested)
|
Chris@0
|
90 {
|
Chris@0
|
91 $prefix = Caster::PREFIX_VIRTUAL;
|
Chris@0
|
92
|
Chris@17
|
93 $a += [
|
Chris@0
|
94 $prefix.'name' => $c instanceof \ReflectionNamedType ? $c->getName() : $c->__toString(),
|
Chris@0
|
95 $prefix.'allowsNull' => $c->allowsNull(),
|
Chris@0
|
96 $prefix.'isBuiltin' => $c->isBuiltin(),
|
Chris@17
|
97 ];
|
Chris@0
|
98
|
Chris@0
|
99 return $a;
|
Chris@0
|
100 }
|
Chris@0
|
101
|
Chris@0
|
102 public static function castReflectionGenerator(\ReflectionGenerator $c, array $a, Stub $stub, $isNested)
|
Chris@0
|
103 {
|
Chris@0
|
104 $prefix = Caster::PREFIX_VIRTUAL;
|
Chris@0
|
105
|
Chris@0
|
106 if ($c->getThis()) {
|
Chris@0
|
107 $a[$prefix.'this'] = new CutStub($c->getThis());
|
Chris@0
|
108 }
|
Chris@0
|
109 $function = $c->getFunction();
|
Chris@17
|
110 $frame = [
|
Chris@0
|
111 'class' => isset($function->class) ? $function->class : null,
|
Chris@0
|
112 'type' => isset($function->class) ? ($function->isStatic() ? '::' : '->') : null,
|
Chris@0
|
113 'function' => $function->name,
|
Chris@0
|
114 'file' => $c->getExecutingFile(),
|
Chris@0
|
115 'line' => $c->getExecutingLine(),
|
Chris@17
|
116 ];
|
Chris@0
|
117 if ($trace = $c->getTrace(DEBUG_BACKTRACE_IGNORE_ARGS)) {
|
Chris@0
|
118 $function = new \ReflectionGenerator($c->getExecutingGenerator());
|
Chris@17
|
119 array_unshift($trace, [
|
Chris@0
|
120 'function' => 'yield',
|
Chris@0
|
121 'file' => $function->getExecutingFile(),
|
Chris@0
|
122 'line' => $function->getExecutingLine() - 1,
|
Chris@17
|
123 ]);
|
Chris@0
|
124 $trace[] = $frame;
|
Chris@0
|
125 $a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1);
|
Chris@0
|
126 } else {
|
Chris@0
|
127 $function = new FrameStub($frame, false, true);
|
Chris@17
|
128 $function = ExceptionCaster::castFrameStub($function, [], $function, true);
|
Chris@17
|
129 $a[$prefix.'executing'] = new EnumStub([
|
Chris@12
|
130 "\0~separator= \0".$frame['class'].$frame['type'].$frame['function'].'()' => $function[$prefix.'src'],
|
Chris@17
|
131 ]);
|
Chris@0
|
132 }
|
Chris@0
|
133
|
Chris@0
|
134 $a[Caster::PREFIX_VIRTUAL.'closed'] = false;
|
Chris@0
|
135
|
Chris@0
|
136 return $a;
|
Chris@0
|
137 }
|
Chris@0
|
138
|
Chris@0
|
139 public static function castClass(\ReflectionClass $c, array $a, Stub $stub, $isNested, $filter = 0)
|
Chris@0
|
140 {
|
Chris@0
|
141 $prefix = Caster::PREFIX_VIRTUAL;
|
Chris@0
|
142
|
Chris@0
|
143 if ($n = \Reflection::getModifierNames($c->getModifiers())) {
|
Chris@0
|
144 $a[$prefix.'modifiers'] = implode(' ', $n);
|
Chris@0
|
145 }
|
Chris@0
|
146
|
Chris@17
|
147 self::addMap($a, $c, [
|
Chris@0
|
148 'extends' => 'getParentClass',
|
Chris@0
|
149 'implements' => 'getInterfaceNames',
|
Chris@0
|
150 'constants' => 'getConstants',
|
Chris@17
|
151 ]);
|
Chris@0
|
152
|
Chris@0
|
153 foreach ($c->getProperties() as $n) {
|
Chris@0
|
154 $a[$prefix.'properties'][$n->name] = $n;
|
Chris@0
|
155 }
|
Chris@0
|
156
|
Chris@0
|
157 foreach ($c->getMethods() as $n) {
|
Chris@0
|
158 $a[$prefix.'methods'][$n->name] = $n;
|
Chris@0
|
159 }
|
Chris@0
|
160
|
Chris@0
|
161 if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
|
Chris@0
|
162 self::addExtra($a, $c);
|
Chris@0
|
163 }
|
Chris@0
|
164
|
Chris@0
|
165 return $a;
|
Chris@0
|
166 }
|
Chris@0
|
167
|
Chris@0
|
168 public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, array $a, Stub $stub, $isNested, $filter = 0)
|
Chris@0
|
169 {
|
Chris@0
|
170 $prefix = Caster::PREFIX_VIRTUAL;
|
Chris@0
|
171
|
Chris@17
|
172 self::addMap($a, $c, [
|
Chris@0
|
173 'returnsReference' => 'returnsReference',
|
Chris@0
|
174 'returnType' => 'getReturnType',
|
Chris@0
|
175 'class' => 'getClosureScopeClass',
|
Chris@0
|
176 'this' => 'getClosureThis',
|
Chris@17
|
177 ]);
|
Chris@0
|
178
|
Chris@0
|
179 if (isset($a[$prefix.'returnType'])) {
|
Chris@0
|
180 $v = $a[$prefix.'returnType'];
|
Chris@0
|
181 $v = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString();
|
Chris@17
|
182 $a[$prefix.'returnType'] = new ClassStub($a[$prefix.'returnType']->allowsNull() ? '?'.$v : $v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
|
Chris@0
|
183 }
|
Chris@0
|
184 if (isset($a[$prefix.'class'])) {
|
Chris@0
|
185 $a[$prefix.'class'] = new ClassStub($a[$prefix.'class']);
|
Chris@0
|
186 }
|
Chris@0
|
187 if (isset($a[$prefix.'this'])) {
|
Chris@0
|
188 $a[$prefix.'this'] = new CutStub($a[$prefix.'this']);
|
Chris@0
|
189 }
|
Chris@0
|
190
|
Chris@0
|
191 foreach ($c->getParameters() as $v) {
|
Chris@0
|
192 $k = '$'.$v->name;
|
Chris@0
|
193 if (method_exists($v, 'isVariadic') && $v->isVariadic()) {
|
Chris@0
|
194 $k = '...'.$k;
|
Chris@0
|
195 }
|
Chris@0
|
196 if ($v->isPassedByReference()) {
|
Chris@0
|
197 $k = '&'.$k;
|
Chris@0
|
198 }
|
Chris@0
|
199 $a[$prefix.'parameters'][$k] = $v;
|
Chris@0
|
200 }
|
Chris@0
|
201 if (isset($a[$prefix.'parameters'])) {
|
Chris@0
|
202 $a[$prefix.'parameters'] = new EnumStub($a[$prefix.'parameters']);
|
Chris@0
|
203 }
|
Chris@0
|
204
|
Chris@0
|
205 if ($v = $c->getStaticVariables()) {
|
Chris@0
|
206 foreach ($v as $k => &$v) {
|
Chris@17
|
207 if (\is_object($v)) {
|
Chris@0
|
208 $a[$prefix.'use']['$'.$k] = new CutStub($v);
|
Chris@0
|
209 } else {
|
Chris@0
|
210 $a[$prefix.'use']['$'.$k] = &$v;
|
Chris@0
|
211 }
|
Chris@0
|
212 }
|
Chris@0
|
213 unset($v);
|
Chris@0
|
214 $a[$prefix.'use'] = new EnumStub($a[$prefix.'use']);
|
Chris@0
|
215 }
|
Chris@0
|
216
|
Chris@0
|
217 if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
|
Chris@0
|
218 self::addExtra($a, $c);
|
Chris@0
|
219 }
|
Chris@0
|
220
|
Chris@0
|
221 // Added by HHVM
|
Chris@0
|
222 unset($a[Caster::PREFIX_DYNAMIC.'static']);
|
Chris@0
|
223
|
Chris@0
|
224 return $a;
|
Chris@0
|
225 }
|
Chris@0
|
226
|
Chris@0
|
227 public static function castMethod(\ReflectionMethod $c, array $a, Stub $stub, $isNested)
|
Chris@0
|
228 {
|
Chris@0
|
229 $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
|
Chris@0
|
230
|
Chris@0
|
231 return $a;
|
Chris@0
|
232 }
|
Chris@0
|
233
|
Chris@0
|
234 public static function castParameter(\ReflectionParameter $c, array $a, Stub $stub, $isNested)
|
Chris@0
|
235 {
|
Chris@0
|
236 $prefix = Caster::PREFIX_VIRTUAL;
|
Chris@0
|
237
|
Chris@0
|
238 // Added by HHVM
|
Chris@0
|
239 unset($a['info']);
|
Chris@0
|
240
|
Chris@17
|
241 self::addMap($a, $c, [
|
Chris@0
|
242 'position' => 'getPosition',
|
Chris@0
|
243 'isVariadic' => 'isVariadic',
|
Chris@0
|
244 'byReference' => 'isPassedByReference',
|
Chris@0
|
245 'allowsNull' => 'allowsNull',
|
Chris@17
|
246 ]);
|
Chris@0
|
247
|
Chris@0
|
248 if (method_exists($c, 'getType')) {
|
Chris@0
|
249 if ($v = $c->getType()) {
|
Chris@0
|
250 $a[$prefix.'typeHint'] = $v instanceof \ReflectionNamedType ? $v->getName() : $v->__toString();
|
Chris@0
|
251 }
|
Chris@0
|
252 } elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $c, $v)) {
|
Chris@0
|
253 $a[$prefix.'typeHint'] = $v[1];
|
Chris@0
|
254 }
|
Chris@0
|
255
|
Chris@0
|
256 if (isset($a[$prefix.'typeHint'])) {
|
Chris@0
|
257 $v = $a[$prefix.'typeHint'];
|
Chris@17
|
258 $a[$prefix.'typeHint'] = new ClassStub($v, [class_exists($v, false) || interface_exists($v, false) || trait_exists($v, false) ? $v : '', '']);
|
Chris@0
|
259 } else {
|
Chris@0
|
260 unset($a[$prefix.'allowsNull']);
|
Chris@0
|
261 }
|
Chris@0
|
262
|
Chris@0
|
263 try {
|
Chris@0
|
264 $a[$prefix.'default'] = $v = $c->getDefaultValue();
|
Chris@0
|
265 if (method_exists($c, 'isDefaultValueConstant') && $c->isDefaultValueConstant()) {
|
Chris@0
|
266 $a[$prefix.'default'] = new ConstStub($c->getDefaultValueConstantName(), $v);
|
Chris@0
|
267 }
|
Chris@0
|
268 if (null === $v) {
|
Chris@0
|
269 unset($a[$prefix.'allowsNull']);
|
Chris@0
|
270 }
|
Chris@0
|
271 } catch (\ReflectionException $e) {
|
Chris@0
|
272 if (isset($a[$prefix.'typeHint']) && $c->allowsNull() && !class_exists('ReflectionNamedType', false)) {
|
Chris@0
|
273 $a[$prefix.'default'] = null;
|
Chris@0
|
274 unset($a[$prefix.'allowsNull']);
|
Chris@0
|
275 }
|
Chris@0
|
276 }
|
Chris@0
|
277
|
Chris@0
|
278 return $a;
|
Chris@0
|
279 }
|
Chris@0
|
280
|
Chris@0
|
281 public static function castProperty(\ReflectionProperty $c, array $a, Stub $stub, $isNested)
|
Chris@0
|
282 {
|
Chris@0
|
283 $a[Caster::PREFIX_VIRTUAL.'modifiers'] = implode(' ', \Reflection::getModifierNames($c->getModifiers()));
|
Chris@0
|
284 self::addExtra($a, $c);
|
Chris@0
|
285
|
Chris@0
|
286 return $a;
|
Chris@0
|
287 }
|
Chris@0
|
288
|
Chris@0
|
289 public static function castExtension(\ReflectionExtension $c, array $a, Stub $stub, $isNested)
|
Chris@0
|
290 {
|
Chris@17
|
291 self::addMap($a, $c, [
|
Chris@0
|
292 'version' => 'getVersion',
|
Chris@0
|
293 'dependencies' => 'getDependencies',
|
Chris@0
|
294 'iniEntries' => 'getIniEntries',
|
Chris@0
|
295 'isPersistent' => 'isPersistent',
|
Chris@0
|
296 'isTemporary' => 'isTemporary',
|
Chris@0
|
297 'constants' => 'getConstants',
|
Chris@0
|
298 'functions' => 'getFunctions',
|
Chris@0
|
299 'classes' => 'getClasses',
|
Chris@17
|
300 ]);
|
Chris@0
|
301
|
Chris@0
|
302 return $a;
|
Chris@0
|
303 }
|
Chris@0
|
304
|
Chris@0
|
305 public static function castZendExtension(\ReflectionZendExtension $c, array $a, Stub $stub, $isNested)
|
Chris@0
|
306 {
|
Chris@17
|
307 self::addMap($a, $c, [
|
Chris@0
|
308 'version' => 'getVersion',
|
Chris@0
|
309 'author' => 'getAuthor',
|
Chris@0
|
310 'copyright' => 'getCopyright',
|
Chris@0
|
311 'url' => 'getURL',
|
Chris@17
|
312 ]);
|
Chris@0
|
313
|
Chris@0
|
314 return $a;
|
Chris@0
|
315 }
|
Chris@0
|
316
|
Chris@0
|
317 private static function addExtra(&$a, \Reflector $c)
|
Chris@0
|
318 {
|
Chris@17
|
319 $x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : [];
|
Chris@0
|
320
|
Chris@0
|
321 if (method_exists($c, 'getFileName') && $m = $c->getFileName()) {
|
Chris@0
|
322 $x['file'] = new LinkStub($m, $c->getStartLine());
|
Chris@0
|
323 $x['line'] = $c->getStartLine().' to '.$c->getEndLine();
|
Chris@0
|
324 }
|
Chris@0
|
325
|
Chris@0
|
326 self::addMap($x, $c, self::$extraMap, '');
|
Chris@0
|
327
|
Chris@0
|
328 if ($x) {
|
Chris@0
|
329 $a[Caster::PREFIX_VIRTUAL.'extra'] = new EnumStub($x);
|
Chris@0
|
330 }
|
Chris@0
|
331 }
|
Chris@0
|
332
|
Chris@0
|
333 private static function addMap(&$a, \Reflector $c, $map, $prefix = Caster::PREFIX_VIRTUAL)
|
Chris@0
|
334 {
|
Chris@0
|
335 foreach ($map as $k => $m) {
|
Chris@0
|
336 if (method_exists($c, $m) && false !== ($m = $c->$m()) && null !== $m) {
|
Chris@0
|
337 $a[$prefix.$k] = $m instanceof \Reflector ? $m->name : $m;
|
Chris@0
|
338 }
|
Chris@0
|
339 }
|
Chris@0
|
340 }
|
Chris@0
|
341 }
|