8000 [VarDumper] Casters for Generator, ReflectionGenerator and Reflection… · symfony/symfony@d6c2d75 · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d6c2d75

Browse files
[VarDumper] Casters for Generator, ReflectionGenerator and ReflectionType
1 parent dee62e7 commit d6c2d75

File tree

10 files changed

+215
-44
lines changed

10 files changed

+215
-44
lines changed

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

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
*/
2222
class ExceptionCaster
2323
{
24+
public static $srcContext = 1;
2425
public static $traceArgs = true;
2526
public static $errorTypes = array(
2627
E_DEPRECATED => 'E_DEPRECATED',
@@ -71,7 +72,7 @@ public static function castThrowingCasterException(ThrowingCasterException $e, a
7172
'file' => $b[$prefix.'file'],
7273
'line' => $b[$prefix.'line'],
7374
));
74-
$a[$xPrefix.'trace'] = new TraceStub($b[$xPrefix.'trace'], 1, false, 0, -1 - count($a[$xPrefix.'trace']->value));
75+
$a[$xPrefix.'trace'] = new TraceStub($b[$xPrefix.'trace'], false, 0, -1 - count($a[$xPrefix.'trace']->value));
7576
}
7677

7778
unset($a[$xPrefix.'previous'], $a[$prefix.'code'], $a[$prefix.'file'], $a[$prefix.'line']);
@@ -90,15 +91,15 @@ public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, $is
9091

9192
$a = array();
9293
$j = count($frames);
93-
if (0 > $i = $trace->offset) {
94+
if (0 > $i = $trace->sliceOffset) {
9495
$i = max(0, $j + $i);
9596
}
9697
if (!isset($trace->value[$i])) {
9798
return array();
9899
}
99100
$lastCall = isset($frames[$i]['function']) ? ' ==> '.(isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '';
100101

101-
for ($j -= $i++; isset($frames[$i]); ++$i, --$j) {
102+
for ($j += $trace->numberingOffset - $i++; isset($frames[$i]); ++$i, --$j) {
102103
$call = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[$i]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '???';
103104

104105
$a[Caster::PREFIX_VIRTUAL.$j.'. '.$call.$lastCall] = new FrameStub(
@@ -108,7 +109,6 @@ public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, $is
108109
'type' => isset($frames[$i]['type']) ? $frames[$i]['type'] : null,
109110
'function' => isset($frames[$i]['function']) ? $frames[$i]['function'] : null,
110111
) + $frames[$i - 1],
111-
$trace->srcContext,
112112
$trace->keepArgs,
113113
true
114114
);
@@ -122,12 +122,11 @@ public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, $is
122122
'type' => null,
123123
'function' => '{main}',
124124
) + $frames[$i - 1],
125-
$trace->srcContext,
126125
$trace->keepArgs,
127126
true
128127
);
129-
if (null !== $trace->length) {
130-
$a = array_slice($a, 0, $trace->length, true);
128+
if (null !== $trace->sliceLength) {
129+
$a = array_slice($a, 0, $trace->sliceLength, true);
131130
}
132131

133132
return $a;
@@ -146,8 +145,8 @@ public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $is
146145
$f['file'] = substr($f['file'], 0, -strlen($match[0]));
147146
$f['line'] = (int) $match[1];
148147
}
149-
if (file_exists($f['file']) && 0 <= $frame->srcContext) {
150-
$src[$f['file'].':'.$f['line']] = self::extractSource(explode("\n", file_get_contents($f['file'])), $f['line'], $frame->srcContext);
148+
if (file_exists($f['file']) && 0 <= self::$srcContext) {
149+
$src[$f['file'].':'.$f['line']] = self::extractSource(explode("\n", file_get_contents($f['file'])), $f['line'], self::$srcContext);
151150

152151
if (!empty($f['class']) && is_subclass_of($f['class'], 'Twig_Template') && method_exists($f['class'], 'getDebugInfo')) {
153152
$template = isset($f['object']) ? $f['object'] : new $f['class'](new \Twig_Environment(new \Twig_Loader_Filesystem()));
@@ -157,7 +156,7 @@ public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $is
157156
$templateSrc = explode("\n", method_exists($template, 'getSource') ? $template->getSource() : $template->getEnvironment()->getLoader()->getSource($templateName));
158157
$templateInfo = $template->getDebugInfo();
159158
if (isset($templateInfo[$f['line']])) {
160-
$src[$templateName.':'.$templateInfo[$f['line']]] = self::extractSource($templateSrc, $templateInfo[$f['line']], $frame->srcContext);
159+
$src[$templateName.':'.$templateInfo[$f['line']]] = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext);
161160
}
162161
} catch (\Twig_Error_Loader $e) {
163162
}
@@ -247,15 +246,29 @@ private static function filterExceptionArray($xClass, array $a, $xPrefix, $filte
247246

248247
private static function extractSource(array $srcArray, $line, $srcContext)
249248
{
250-
$src = '';
249+
$src = array();
251250

252251
for ($i = $line - 1 - $srcContext; $i <= $line - 1 + $srcContext; ++$i) {
253-
$src .= (isset($srcArray[$i]) ? $srcArray[$i] : '')."\n";
252+
$src[] = (isset($srcArray[$i]) ? $srcArray[$i] : '')."\n";
254253
}
255-
if (!$srcContext) {
256-
$src = trim($src);
254+
255+
$ltrim = 0;
256+
while (' ' === $src[0][$ltrim] || "\t" === $src[0][$ltrim]) {
257+
$i = $srcContext << 1;
258+
while ($i > 0 && $src[0][$ltrim] === $src[$i][$ltrim]) {
259+
--$i;
260+
}
261+
if ($i) {
262+
break;
263+
}
264+
++$ltrim;
265+
}
266+
if ($ltrim) {
267+
foreach ($src as $i => $line) {
268+
$src[$i] = substr($line, $ltrim);
269+
}
257270
}
258271

259-
return $src;
272+
return implode('', $src);
260273
}
261274
}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,12 @@
1818
*/
1919
class FrameStub extends EnumStub
2020
{
21-
public $srcContext;
2221
public $keepArgs;
2322
public $inTraceStub;
2423

25-
public function __construct(array $trace, $srcContext = 1, $keepArgs = true, $inTraceStub = false)
24+
public function __construct(array $frame, $keepArgs = true, $inTraceStub = false)
2625
{
27-
$this->value = $trace;
28-
$this->srcContext = $srcContext;
26+
$this->value = $frame;
2927
$this->keepArgs = $keepArgs;
3028
$this->inTraceStub = $inTraceStub;
3129
}

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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,59 @@ public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested)
7474
return $a;
7575
}
7676

77+
public static function castGenerator(\Generator $c, array $a, Stub $stub, $isNested)
78+
{
79+
return class_exists('ReflectionGenerator', false) ? self::castReflectionGenerator(new \ReflectionGenerator($c), $a, $stub, $isNested) : $a;
80+
}
81+
82+
public static function castType(\ReflectionType $c, array $a, Stub $stub, $isNested)
83+
{
84+
$prefix = Caster::PREFIX_VIRTUAL;
85+
86+
$a += array(
87+
$prefix.'type' => $c->__toString(),
88+
$prefix.'allowsNull' => $c->allowsNull(),
89+
$prefix.'isBuiltin' => $c->isBuiltin(),
90+
);
91+
92+
return $a;
93+
}
94+
95+
public static function castReflectionGenerator(\ReflectionGenerator $c, array $a, Stub $stub, $isNested)
96+
{
97+
$prefix = Caster::PREFIX_VIRTUAL;
98+
99+
if ($c->getThis()) {
100+
$a[$prefix.'this'] = new CutStub($c->getThis());
101+
}
102+
$x = $c->getFunction();
103+
$frame = array(
104+
'class' => isset($x->class) ? $x->class : null,
105+
'type' => isset($x->class) ? ($x->isStatic() ? '::' : '->') : null,
106+
'function' => $x->name,
107+
'file' => $c->getExecutingFile(),
108+
'line' => $c->getExecutingLine(),
109+
);
110+
if ($trace = $c->getTrace(DEBUG_BACKTRACE_IGNORE_ARGS)) {
111+
$x = new \ReflectionGenerator($c->getExecutingGenerator());
112+
array_unshift($trace, array(
113+
'function' => 'yield',
114+
'file' => $x->getExecutingFile(),
115+
'line' => $x->getExecutingLine() - 1,
116+
));
117+
$trace[] = $frame;
118+
$a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1);
119+
} else {
120+
$x = new FrameStub($frame, false, true);
121+
$x = ExceptionCaster::castFrameStub($x, array(), $x, true);
122+
$a[$prefix.'executing'] = new EnumStub(array(
123+
$frame['class'].$frame['type'].$frame['function'].'()' => $x[$prefix.'src'],
124+
));
125+
}
126+
127+
return $a;
128+
}
129+
77130
public static function castClass(\ReflectionClass $c, array $a, Stub $stub, $isNested, $filter = 0)
78131
{
79132
$prefix = Caster::PREFIX_VIRTUAL;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public static function castEnum(EnumStub $c, array $a, Stub $stub, $isNested)
5454
if ($isNested) {
5555
$stub->class = '';
5656
$stub->handle = 0;
57+
$stub->value = null;
5758

5859
$a = array();
5960

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,17 @@
2020
*/
2121
class TraceStub extends Stub
2222
{
23-
public $srcContext;
2423
public $keepArgs;
25-
public $offset;
26-
public $length;
24+
public $sliceOffset;
25+
public $sliceLength;
26+
public $numberingOffset;
2727

28-
public function __construct(array $trace, $srcContext = 1, $keepArgs = true, $offset = 0, $length = null)
28+
public function __construct(array $trace, $keepArgs = true, $sliceOffset = 0, $sliceLength = null, $numberingOffset = 0)
2929
{
3030
$this->value = $trace;
31-
$this->srcContext = $srcContext;
3231
$this->keepArgs = $keepArgs;
33-
$this->offset = $offset;
34-
$this->length = $length;
32+
$this->sliceOffset = $sliceOffset;
33+
$this->sliceLength = $sliceLength;
34+
$this->numberingOffset = $numberingOffset;
3535
}
3636
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ abstract class AbstractCloner implements ClonerInterface
2828
'Symfony\Component\VarDumper\Caster\EnumStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castEnum',
2929

3030
'Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure',
31+
'Generator' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castGenerator',
32+
'ReflectionType' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castType',
33+
'ReflectionGenerator' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castReflectionGenerator',
3134
'ReflectionClass' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClass',
3235
'ReflectionFunctionAbstract' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castFunctionAbstract',
3336
'ReflectionMethod' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castMethod',

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ protected function doClone($var)
149149
$stub->handle = $h;
150150
$a = $this->castObject($stub, 0 < $i);
151151
if ($v !== $stub->value) {
152-
if (Stub::TYPE_OBJECT !== $stub->type) {
152+
if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) {
153153
break;
154154
}
155155
if ($useExt) {

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

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\VarDumper\Tests\Caster;
1313

1414
use Symfony\Component\VarDumper\Test\VarDumperTestCase;
15+
use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo;
1516

1617
/**
1718
* @author Nicolas Grekas <p@tchwork.com>
@@ -72,7 +73,7 @@ public function testClosureCaster()
7273
\$b: & 123
7374
}
7475
file: "%sReflectionCasterTest.php"
75-
line: "62 to 62"
76+
line: "63 to 63"
7677
}
7778
EOTXT
7879
, $var
@@ -92,11 +93,92 @@ public function testReturnType()
9293
returnType: "int"
9394
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
9495
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
95-
file: "%sReflectionCasterTest.php(87) : eval()'d code"
96+
file: "%sReflectionCasterTest.php(88) : eval()'d code"
9697
line: "1 to 1"
9798
}
9899
EOTXT
99100
, $f
100101
);
101102
}
103+
104+
/**
105+
* @requires PHP 7.0
106+
*/
107+
public function testGenerator()
108+
{
109+
$g = new GeneratorDemo();
110+
$g = $g->baz();
111+
$r = new \ReflectionGenerator($g);
112+
113+
$xDump = <<<'EODUMP'
114+
Generator {
115+
this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …}
116+
executing: {
117+
Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo->baz(): {
118+
%sGeneratorDemo.php:14: """
119+
{\n
120+
yield from bar();\n
121+
}\n
122+
"""
123+
}
124+
}
125+
}
126+
EODUMP;
127+
128+
$this->assertDumpMatchesFormat($xDump, $g);
129+
130+
foreach ($g as $v) {
131+
break;
132+
}
133+
134+
$xDump = <<<'EODUMP'
135+
array:2 [
136+
0 => ReflectionGenerator {
137+
this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …}
138+
trace: {
139+
3. Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo() ==> yield(): {
140+
src: {
141+
%sGeneratorDemo.php:9: """
142+
{\n
143+
yield 1;\n
144+
}\n
145+
"""
146+
}
147+
}
148+
2. Symfony\Component\VarDumper\Tests\Fixtures\bar() ==> Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo(): {
149+
src: {
150+
%sGeneratorDemo.php:20: """
151+
{\n
152+
yield from GeneratorDemo::foo();\n
153+
}\n
154+
"""
155+
}
156+
}
157+
1. Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo->baz() ==> Symfony\Component\VarDumper\Tests\Fixtures\bar(): {
158+
src: {
159+
%sGeneratorDemo.php:14: """
160+
{\n
161+
yield from bar();\n
162+
}\n
163+
"""
164+
}
165+
}
166+
}
167+
}
168+
1 => Generator {
169+
executing: {
170+
Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo(): {
171+
%sGeneratorDemo.php:10: """
172+
yield 1;\n
173+
}\n
174+
\n
175+
"""
176+
}
177+
}
178+
}
179+
]
180+
EODUMP;
181+
182+
$this->assertDumpMatchesFormat($xDump, array($r, $r->getExecutingGenerator()));
183+
}
102184
}

0 commit comments

Comments
 (0)
0