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