feature #16325 [VarDumper] Casters for Generator, ReflectionGenerator and ReflectionType (nicolas-grekas)
This PR was merged into the 2.8 branch.
Discussion
----------
[VarDumper] Casters for Generator, ReflectionGenerator and ReflectionType
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
I had this on a local branch since a few days:
- on PHP7, using ReflectionGenerator allows dumping interesting state info about generators (see test case for example output)
- caster for ReflectionType added
- source code excerpts are now left-trimmed (see adjusted test cases)
Commits
-------
d6c2d75
[VarDumper] Casters for Generator, ReflectionGenerator and ReflectionType
This commit is contained in:
commit
973fbb310e
@ -21,6 +21,7 @@ use Symfony\Component\VarDumper\Cloner\Stub;
|
|||||||
*/
|
*/
|
||||||
class ExceptionCaster
|
class ExceptionCaster
|
||||||
{
|
{
|
||||||
|
public static $srcContext = 1;
|
||||||
public static $traceArgs = true;
|
public static $traceArgs = true;
|
||||||
public static $errorTypes = array(
|
public static $errorTypes = array(
|
||||||
E_DEPRECATED => 'E_DEPRECATED',
|
E_DEPRECATED => 'E_DEPRECATED',
|
||||||
@ -71,7 +72,7 @@ class ExceptionCaster
|
|||||||
'file' => $b[$prefix.'file'],
|
'file' => $b[$prefix.'file'],
|
||||||
'line' => $b[$prefix.'line'],
|
'line' => $b[$prefix.'line'],
|
||||||
));
|
));
|
||||||
$a[$xPrefix.'trace'] = new TraceStub($b[$xPrefix.'trace'], 1, false, 0, -1 - count($a[$xPrefix.'trace']->value));
|
$a[$xPrefix.'trace'] = new TraceStub($b[$xPrefix.'trace'], false, 0, -1 - count($a[$xPrefix.'trace']->value));
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($a[$xPrefix.'previous'], $a[$prefix.'code'], $a[$prefix.'file'], $a[$prefix.'line']);
|
unset($a[$xPrefix.'previous'], $a[$prefix.'code'], $a[$prefix.'file'], $a[$prefix.'line']);
|
||||||
@ -90,7 +91,7 @@ class ExceptionCaster
|
|||||||
|
|
||||||
$a = array();
|
$a = array();
|
||||||
$j = count($frames);
|
$j = count($frames);
|
||||||
if (0 > $i = $trace->offset) {
|
if (0 > $i = $trace->sliceOffset) {
|
||||||
$i = max(0, $j + $i);
|
$i = max(0, $j + $i);
|
||||||
}
|
}
|
||||||
if (!isset($trace->value[$i])) {
|
if (!isset($trace->value[$i])) {
|
||||||
@ -98,7 +99,7 @@ class ExceptionCaster
|
|||||||
}
|
}
|
||||||
$lastCall = isset($frames[$i]['function']) ? ' ==> '.(isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '';
|
$lastCall = isset($frames[$i]['function']) ? ' ==> '.(isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '';
|
||||||
|
|
||||||
for ($j -= $i++; isset($frames[$i]); ++$i, --$j) {
|
for ($j += $trace->numberingOffset - $i++; isset($frames[$i]); ++$i, --$j) {
|
||||||
$call = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[$i]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '???';
|
$call = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[$i]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '???';
|
||||||
|
|
||||||
$a[Caster::PREFIX_VIRTUAL.$j.'. '.$call.$lastCall] = new FrameStub(
|
$a[Caster::PREFIX_VIRTUAL.$j.'. '.$call.$lastCall] = new FrameStub(
|
||||||
@ -108,7 +109,6 @@ class ExceptionCaster
|
|||||||
'type' => isset($frames[$i]['type']) ? $frames[$i]['type'] : null,
|
'type' => isset($frames[$i]['type']) ? $frames[$i]['type'] : null,
|
||||||
'function' => isset($frames[$i]['function']) ? $frames[$i]['function'] : null,
|
'function' => isset($frames[$i]['function']) ? $frames[$i]['function'] : null,
|
||||||
) + $frames[$i - 1],
|
) + $frames[$i - 1],
|
||||||
$trace->srcContext,
|
|
||||||
$trace->keepArgs,
|
$trace->keepArgs,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@ -122,12 +122,11 @@ class ExceptionCaster
|
|||||||
'type' => null,
|
'type' => null,
|
||||||
'function' => '{main}',
|
'function' => '{main}',
|
||||||
) + $frames[$i - 1],
|
) + $frames[$i - 1],
|
||||||
$trace->srcContext,
|
|
||||||
$trace->keepArgs,
|
$trace->keepArgs,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
if (null !== $trace->length) {
|
if (null !== $trace->sliceLength) {
|
||||||
$a = array_slice($a, 0, $trace->length, true);
|
$a = array_slice($a, 0, $trace->sliceLength, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $a;
|
return $a;
|
||||||
@ -146,8 +145,8 @@ class ExceptionCaster
|
|||||||
$f['file'] = substr($f['file'], 0, -strlen($match[0]));
|
$f['file'] = substr($f['file'], 0, -strlen($match[0]));
|
||||||
$f['line'] = (int) $match[1];
|
$f['line'] = (int) $match[1];
|
||||||
}
|
}
|
||||||
if (file_exists($f['file']) && 0 <= $frame->srcContext) {
|
if (file_exists($f['file']) && 0 <= self::$srcContext) {
|
||||||
$src[$f['file'].':'.$f['line']] = self::extractSource(explode("\n", file_get_contents($f['file'])), $f['line'], $frame->srcContext);
|
$src[$f['file'].':'.$f['line']] = self::extractSource(explode("\n", file_get_contents($f['file'])), $f['line'], self::$srcContext);
|
||||||
|
|
||||||
if (!empty($f['class']) && is_subclass_of($f['class'], 'Twig_Template') && method_exists($f['class'], 'getDebugInfo')) {
|
if (!empty($f['class']) && is_subclass_of($f['class'], 'Twig_Template') && method_exists($f['class'], 'getDebugInfo')) {
|
||||||
$template = isset($f['object']) ? $f['object'] : new $f['class'](new \Twig_Environment(new \Twig_Loader_Filesystem()));
|
$template = isset($f['object']) ? $f['object'] : new $f['class'](new \Twig_Environment(new \Twig_Loader_Filesystem()));
|
||||||
@ -157,7 +156,7 @@ class ExceptionCaster
|
|||||||
$templateSrc = explode("\n", method_exists($template, 'getSource') ? $template->getSource() : $template->getEnvironment()->getLoader()->getSource($templateName));
|
$templateSrc = explode("\n", method_exists($template, 'getSource') ? $template->getSource() : $template->getEnvironment()->getLoader()->getSource($templateName));
|
||||||
$templateInfo = $template->getDebugInfo();
|
$templateInfo = $template->getDebugInfo();
|
||||||
if (isset($templateInfo[$f['line']])) {
|
if (isset($templateInfo[$f['line']])) {
|
||||||
$src[$templateName.':'.$templateInfo[$f['line']]] = self::extractSource($templateSrc, $templateInfo[$f['line']], $frame->srcContext);
|
$src[$templateName.':'.$templateInfo[$f['line']]] = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext);
|
||||||
}
|
}
|
||||||
} catch (\Twig_Error_Loader $e) {
|
} catch (\Twig_Error_Loader $e) {
|
||||||
}
|
}
|
||||||
@ -247,15 +246,29 @@ class ExceptionCaster
|
|||||||
|
|
||||||
private static function extractSource(array $srcArray, $line, $srcContext)
|
private static function extractSource(array $srcArray, $line, $srcContext)
|
||||||
{
|
{
|
||||||
$src = '';
|
$src = array();
|
||||||
|
|
||||||
for ($i = $line - 1 - $srcContext; $i <= $line - 1 + $srcContext; ++$i) {
|
for ($i = $line - 1 - $srcContext; $i <= $line - 1 + $srcContext; ++$i) {
|
||||||
$src .= (isset($srcArray[$i]) ? $srcArray[$i] : '')."\n";
|
$src[] = (isset($srcArray[$i]) ? $srcArray[$i] : '')."\n";
|
||||||
}
|
|
||||||
if (!$srcContext) {
|
|
||||||
$src = trim($src);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $src;
|
$ltrim = 0;
|
||||||
|
while (' ' === $src[0][$ltrim] || "\t" === $src[0][$ltrim]) {
|
||||||
|
$i = $srcContext << 1;
|
||||||
|
while ($i > 0 && $src[0][$ltrim] === $src[$i][$ltrim]) {
|
||||||
|
--$i;
|
||||||
|
}
|
||||||
|
if ($i) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++$ltrim;
|
||||||
|
}
|
||||||
|
if ($ltrim) {
|
||||||
|
foreach ($src as $i => $line) {
|
||||||
|
$src[$i] = substr($line, $ltrim);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode('', $src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,14 +18,12 @@ namespace Symfony\Component\VarDumper\Caster;
|
|||||||
*/
|
*/
|
||||||
class FrameStub extends EnumStub
|
class FrameStub extends EnumStub
|
||||||
{
|
{
|
||||||
public $srcContext;
|
|
||||||
public $keepArgs;
|
public $keepArgs;
|
||||||
public $inTraceStub;
|
public $inTraceStub;
|
||||||
|
|
||||||
public function __construct(array $trace, $srcContext = 1, $keepArgs = true, $inTraceStub = false)
|
public function __construct(array $frame, $keepArgs = true, $inTraceStub = false)
|
||||||
{
|
{
|
||||||
$this->value = $trace;
|
$this->value = $frame;
|
||||||
$this->srcContext = $srcContext;
|
|
||||||
$this->keepArgs = $keepArgs;
|
$this->keepArgs = $keepArgs;
|
||||||
$this->inTraceStub = $inTraceStub;
|
$this->inTraceStub = $inTraceStub;
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,59 @@ class ReflectionCaster
|
|||||||
return $a;
|
return $a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function castGenerator(\Generator $c, array $a, Stub $stub, $isNested)
|
||||||
|
{
|
||||||
|
return class_exists('ReflectionGenerator', false) ? self::castReflectionGenerator(new \ReflectionGenerator($c), $a, $stub, $isNested) : $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function castType(\ReflectionType $c, array $a, Stub $stub, $isNested)
|
||||||
|
{
|
||||||
|
$prefix = Caster::PREFIX_VIRTUAL;
|
||||||
|
|
||||||
|
$a += array(
|
||||||
|
$prefix.'type' => $c->__toString(),
|
||||||
|
$prefix.'allowsNull' => $c->allowsNull(),
|
||||||
|
$prefix.'isBuiltin' => $c->isBuiltin(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function castReflectionGenerator(\ReflectionGenerator $c, array $a, Stub $stub, $isNested)
|
||||||
|
{
|
||||||
|
$prefix = Caster::PREFIX_VIRTUAL;
|
||||||
|
|
||||||
|
if ($c->getThis()) {
|
||||||
|
$a[$prefix.'this'] = new CutStub($c->getThis());
|
||||||
|
}
|
||||||
|
$x = $c->getFunction();
|
||||||
|
$frame = array(
|
||||||
|
'class' => isset($x->class) ? $x->class : null,
|
||||||
|
'type' => isset($x->class) ? ($x->isStatic() ? '::' : '->') : null,
|
||||||
|
'function' => $x->name,
|
||||||
|
'file' => $c->getExecutingFile(),
|
||||||
|
'line' => $c->getExecutingLine(),
|
||||||
|
);
|
||||||
|
if ($trace = $c->getTrace(DEBUG_BACKTRACE_IGNORE_ARGS)) {
|
||||||
|
$x = new \ReflectionGenerator($c->getExecutingGenerator());
|
||||||
|
array_unshift($trace, array(
|
||||||
|
'function' => 'yield',
|
||||||
|
'file' => $x->getExecutingFile(),
|
||||||
|
'line' => $x->getExecutingLine() - 1,
|
||||||
|
));
|
||||||
|
$trace[] = $frame;
|
||||||
|
$a[$prefix.'trace'] = new TraceStub($trace, false, 0, -1, -1);
|
||||||
|
} else {
|
||||||
|
$x = new FrameStub($frame, false, true);
|
||||||
|
$x = ExceptionCaster::castFrameStub($x, array(), $x, true);
|
||||||
|
$a[$prefix.'executing'] = new EnumStub(array(
|
||||||
|
$frame['class'].$frame['type'].$frame['function'].'()' => $x[$prefix.'src'],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $a;
|
||||||
|
}
|
||||||
|
|
||||||
public static function castClass(\ReflectionClass $c, array $a, Stub $stub, $isNested, $filter = 0)
|
public static function castClass(\ReflectionClass $c, array $a, Stub $stub, $isNested, $filter = 0)
|
||||||
{
|
{
|
||||||
$prefix = Caster::PREFIX_VIRTUAL;
|
$prefix = Caster::PREFIX_VIRTUAL;
|
||||||
|
@ -54,6 +54,7 @@ class StubCaster
|
|||||||
if ($isNested) {
|
if ($isNested) {
|
||||||
$stub->class = '';
|
$stub->class = '';
|
||||||
$stub->handle = 0;
|
$stub->handle = 0;
|
||||||
|
$stub->value = null;
|
||||||
|
|
||||||
$a = array();
|
$a = array();
|
||||||
|
|
||||||
|
@ -20,17 +20,17 @@ use Symfony\Component\VarDumper\Cloner\Stub;
|
|||||||
*/
|
*/
|
||||||
class TraceStub extends Stub
|
class TraceStub extends Stub
|
||||||
{
|
{
|
||||||
public $srcContext;
|
|
||||||
public $keepArgs;
|
public $keepArgs;
|
||||||
public $offset;
|
public $sliceOffset;
|
||||||
public $length;
|
public $sliceLength;
|
||||||
|
public $numberingOffset;
|
||||||
|
|
||||||
public function __construct(array $trace, $srcContext = 1, $keepArgs = true, $offset = 0, $length = null)
|
public function __construct(array $trace, $keepArgs = true, $sliceOffset = 0, $sliceLength = null, $numberingOffset = 0)
|
||||||
{
|
{
|
||||||
$this->value = $trace;
|
$this->value = $trace;
|
||||||
$this->srcContext = $srcContext;
|
|
||||||
$this->keepArgs = $keepArgs;
|
$this->keepArgs = $keepArgs;
|
||||||
$this->offset = $offset;
|
$this->sliceOffset = $sliceOffset;
|
||||||
$this->length = $length;
|
$this->sliceLength = $sliceLength;
|
||||||
|
$this->numberingOffset = $numberingOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,9 @@ abstract class AbstractCloner implements ClonerInterface
|
|||||||
'Symfony\Component\VarDumper\Caster\EnumStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castEnum',
|
'Symfony\Component\VarDumper\Caster\EnumStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castEnum',
|
||||||
|
|
||||||
'Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure',
|
'Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure',
|
||||||
|
'Generator' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castGenerator',
|
||||||
|
'ReflectionType' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castType',
|
||||||
|
'ReflectionGenerator' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castReflectionGenerator',
|
||||||
'ReflectionClass' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClass',
|
'ReflectionClass' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClass',
|
||||||
'ReflectionFunctionAbstract' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castFunctionAbstract',
|
'ReflectionFunctionAbstract' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castFunctionAbstract',
|
||||||
'ReflectionMethod' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castMethod',
|
'ReflectionMethod' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castMethod',
|
||||||
|
@ -149,7 +149,7 @@ class VarCloner extends AbstractCloner
|
|||||||
$stub->handle = $h;
|
$stub->handle = $h;
|
||||||
$a = $this->castObject($stub, 0 < $i);
|
$a = $this->castObject($stub, 0 < $i);
|
||||||
if ($v !== $stub->value) {
|
if ($v !== $stub->value) {
|
||||||
if (Stub::TYPE_OBJECT !== $stub->type) {
|
if (Stub::TYPE_OBJECT !== $stub->type || null === $stub->value) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ($useExt) {
|
if ($useExt) {
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\VarDumper\Tests\Caster;
|
namespace Symfony\Component\VarDumper\Tests\Caster;
|
||||||
|
|
||||||
use Symfony\Component\VarDumper\Test\VarDumperTestCase;
|
use Symfony\Component\VarDumper\Test\VarDumperTestCase;
|
||||||
|
use Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Nicolas Grekas <p@tchwork.com>
|
* @author Nicolas Grekas <p@tchwork.com>
|
||||||
@ -72,7 +73,7 @@ Closure {
|
|||||||
\$b: & 123
|
\$b: & 123
|
||||||
}
|
}
|
||||||
file: "%sReflectionCasterTest.php"
|
file: "%sReflectionCasterTest.php"
|
||||||
line: "62 to 62"
|
line: "63 to 63"
|
||||||
}
|
}
|
||||||
EOTXT
|
EOTXT
|
||||||
, $var
|
, $var
|
||||||
@ -92,11 +93,92 @@ Closure {
|
|||||||
returnType: "int"
|
returnType: "int"
|
||||||
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
|
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
|
||||||
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
|
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
|
||||||
file: "%sReflectionCasterTest.php(87) : eval()'d code"
|
file: "%sReflectionCasterTest.php(88) : eval()'d code"
|
||||||
line: "1 to 1"
|
line: "1 to 1"
|
||||||
}
|
}
|
||||||
EOTXT
|
EOTXT
|
||||||
, $f
|
, $f
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 7.0
|
||||||
|
*/
|
||||||
|
public function testGenerator()
|
||||||
|
{
|
||||||
|
$g = new GeneratorDemo();
|
||||||
|
$g = $g->baz();
|
||||||
|
$r = new \ReflectionGenerator($g);
|
||||||
|
|
||||||
|
$xDump = <<<'EODUMP'
|
||||||
|
Generator {
|
||||||
|
this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …}
|
||||||
|
executing: {
|
||||||
|
Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo->baz(): {
|
||||||
|
%sGeneratorDemo.php:14: """
|
||||||
|
{\n
|
||||||
|
yield from bar();\n
|
||||||
|
}\n
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EODUMP;
|
||||||
|
|
||||||
|
$this->assertDumpMatchesFormat($xDump, $g);
|
||||||
|
|
||||||
|
foreach ($g as $v) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$xDump = <<<'EODUMP'
|
||||||
|
array:2 [
|
||||||
|
0 => ReflectionGenerator {
|
||||||
|
this: Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo { …}
|
||||||
|
trace: {
|
||||||
|
3. Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo() ==> yield(): {
|
||||||
|
src: {
|
||||||
|
%sGeneratorDemo.php:9: """
|
||||||
|
{\n
|
||||||
|
yield 1;\n
|
||||||
|
}\n
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2. Symfony\Component\VarDumper\Tests\Fixtures\bar() ==> Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo(): {
|
||||||
|
src: {
|
||||||
|
%sGeneratorDemo.php:20: """
|
||||||
|
{\n
|
||||||
|
yield from GeneratorDemo::foo();\n
|
||||||
|
}\n
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1. Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo->baz() ==> Symfony\Component\VarDumper\Tests\Fixtures\bar(): {
|
||||||
|
src: {
|
||||||
|
%sGeneratorDemo.php:14: """
|
||||||
|
{\n
|
||||||
|
yield from bar();\n
|
||||||
|
}\n
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1 => Generator {
|
||||||
|
executing: {
|
||||||
|
Symfony\Component\VarDumper\Tests\Fixtures\GeneratorDemo::foo(): {
|
||||||
|
%sGeneratorDemo.php:10: """
|
||||||
|
yield 1;\n
|
||||||
|
}\n
|
||||||
|
\n
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
EODUMP;
|
||||||
|
|
||||||
|
$this->assertDumpMatchesFormat($xDump, array($r, $r->getExecutingGenerator()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,45 +232,45 @@ stream resource {@{$ref}
|
|||||||
%d. __TwigTemplate_VarDumperFixture_u75a09->doDisplay() ==> new Exception(): {
|
%d. __TwigTemplate_VarDumperFixture_u75a09->doDisplay() ==> new Exception(): {
|
||||||
src: {
|
src: {
|
||||||
%sTwig.php:19: """
|
%sTwig.php:19: """
|
||||||
// line 2\\n
|
// line 2\\n
|
||||||
throw new \Exception('Foobar');\\n
|
throw new \Exception('Foobar');\\n
|
||||||
}\\n
|
}\\n
|
||||||
"""
|
"""
|
||||||
{$twig} }
|
{$twig} }
|
||||||
}
|
}
|
||||||
%d. Twig_Template->displayWithErrorHandling() ==> __TwigTemplate_VarDumperFixture_u75a09->doDisplay(): {
|
%d. Twig_Template->displayWithErrorHandling() ==> __TwigTemplate_VarDumperFixture_u75a09->doDisplay(): {
|
||||||
src: {
|
src: {
|
||||||
%sTemplate.php:%d: """
|
%sTemplate.php:%d: """
|
||||||
try {\\n
|
try {\\n
|
||||||
\$this->doDisplay(\$context, \$blocks);\\n
|
\$this->doDisplay(\$context, \$blocks);\\n
|
||||||
} catch (Twig_Error \$e) {\\n
|
} catch (Twig_Error \$e) {\\n
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%d. Twig_Template->display() ==> Twig_Template->displayWithErrorHandling(): {
|
%d. Twig_Template->display() ==> Twig_Template->displayWithErrorHandling(): {
|
||||||
src: {
|
src: {
|
||||||
%sTemplate.php:%d: """
|
%sTemplate.php:%d: """
|
||||||
{\\n
|
{\\n
|
||||||
\$this->displayWithErrorHandling(\$this->env->mergeGlobals(\$context), array_merge(\$this->blocks, \$blocks));\\n
|
\$this->displayWithErrorHandling(\$this->env->mergeGlobals(\$context), array_merge(\$this->blocks, \$blocks));\\n
|
||||||
}\\n
|
}\\n
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%d. Twig_Template->render() ==> Twig_Template->display(): {
|
%d. Twig_Template->render() ==> Twig_Template->display(): {
|
||||||
src: {
|
src: {
|
||||||
%sTemplate.php:%d: """
|
%sTemplate.php:%d: """
|
||||||
try {\\n
|
try {\\n
|
||||||
\$this->display(\$context);\\n
|
\$this->display(\$context);\\n
|
||||||
} catch (Exception \$e) {\\n
|
} catch (Exception \$e) {\\n
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
%d. %slosure%s() ==> Twig_Template->render(): {
|
%d. %slosure%s() ==> Twig_Template->render(): {
|
||||||
src: {
|
src: {
|
||||||
%sCliDumperTest.php:{$line}: """
|
%sCliDumperTest.php:{$line}: """
|
||||||
}\\n
|
}\\n
|
||||||
};'),\\n
|
};'),\\n
|
||||||
));\\n
|
));\\n
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\VarDumper\Tests\Fixtures;
|
||||||
|
|
||||||
|
class GeneratorDemo
|
||||||
|
{
|
||||||
|
public static function foo()
|
||||||
|
{
|
||||||
|
yield 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function baz()
|
||||||
|
{
|
||||||
|
yield from bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bar()
|
||||||
|
{
|
||||||
|
yield from GeneratorDemo::foo();
|
||||||
|
}
|
Reference in New Issue
Block a user