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