feature #15837 [VarDumper] Add EnumStub for dumping virtual collections with casters (nicolas-grekas)
This PR was merged into the 2.8 branch.
Discussion
----------
[VarDumper] Add EnumStub for dumping virtual collections with casters
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
Currently, casters may use arrays to represent a collection of virtual values. They are curently dumped the same as regular arrays, and this leads to noisy output (like the `array:%n` prefix, or the quotes around "keys").
This PR adds a new EnumStub for these situations.
Here is an example when using PdoCaster:
Before :
![before](https://cloud.githubusercontent.com/assets/243674/9976105/366a37dc-5ed8-11e5-9ee8-00a4a6b68fa9.png)
After:
![after](https://cloud.githubusercontent.com/assets/243674/9976106/3a9b78a2-5ed8-11e5-8209-1d629d3b1736.png)
Commits
-------
aa50596
[VarDumper] Add EnumStub for dumping virtual collections with casters
This commit is contained in:
commit
fbf7351c06
27
src/Symfony/Component/VarDumper/Caster/EnumStub.php
Normal file
27
src/Symfony/Component/VarDumper/Caster/EnumStub.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\VarDumper\Caster;
|
||||
|
||||
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||
|
||||
/**
|
||||
* Represents an enumeration of values.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class EnumStub extends Stub
|
||||
{
|
||||
public function __construct(array $values)
|
||||
{
|
||||
$this->value = $values;
|
||||
}
|
||||
}
|
@ -82,7 +82,7 @@ class PdoCaster
|
||||
$a += array(
|
||||
$prefix.'inTransaction' => method_exists($c, 'inTransaction'),
|
||||
$prefix.'errorInfo' => $c->errorInfo(),
|
||||
$prefix.'attributes' => $attr,
|
||||
$prefix.'attributes' => new EnumStub($attr),
|
||||
);
|
||||
|
||||
if ($a[$prefix.'inTransaction']) {
|
||||
|
@ -101,6 +101,7 @@ class PgSqlCaster
|
||||
}
|
||||
|
||||
$a['param']['client_encoding'] = pg_client_encoding($link);
|
||||
$a['param'] = new EnumStub($a['param']);
|
||||
|
||||
return $a;
|
||||
}
|
||||
@ -145,7 +146,7 @@ class PgSqlCaster
|
||||
if ('1 chars' === $field['display']) {
|
||||
$field['display'] = '1 char';
|
||||
}
|
||||
$a['fields'][] = $field;
|
||||
$a['fields'][] = new EnumStub($field);
|
||||
}
|
||||
|
||||
return $a;
|
||||
|
@ -51,15 +51,15 @@ class ReflectionCaster
|
||||
$a = static::castFunctionAbstract($c, $a, $stub, $isNested);
|
||||
|
||||
if (isset($a[$prefix.'parameters'])) {
|
||||
foreach ($a[$prefix.'parameters'] as &$v) {
|
||||
foreach ($a[$prefix.'parameters']->value as &$v) {
|
||||
$param = $v;
|
||||
$v = array();
|
||||
$v = new EnumStub(array());
|
||||
foreach (static::castParameter($param, array(), $stub, true) as $k => $param) {
|
||||
if ("\0" === $k[0]) {
|
||||
$v[substr($k, 3)] = $param;
|
||||
$v->value[substr($k, 3)] = $param;
|
||||
}
|
||||
}
|
||||
unset($v['position'], $v['isVariadic'], $v['byReference'], $v);
|
||||
unset($v->value['position'], $v->value['isVariadic'], $v->value['byReference'], $v);
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,18 +128,25 @@ class ReflectionCaster
|
||||
}
|
||||
$a[$prefix.'parameters'][$k] = $v;
|
||||
}
|
||||
if (isset($a[$prefix.'parameters'])) {
|
||||
$a[$prefix.'parameters'] = new EnumStub($a[$prefix.'parameters']);
|
||||
}
|
||||
|
||||
if ($v = $c->getStaticVariables()) {
|
||||
foreach ($v as $k => &$v) {
|
||||
$a[$prefix.'use']['$'.$k] = &$v;
|
||||
}
|
||||
unset($v);
|
||||
$a[$prefix.'use'] = new EnumStub($a[$prefix.'use']);
|
||||
}
|
||||
|
||||
if (!($filter & Caster::EXCLUDE_VERBOSE) && !$isNested) {
|
||||
self::addExtra($a, $c);
|
||||
}
|
||||
|
||||
// Added by HHVM
|
||||
unset($a[Caster::PREFIX_DYNAMIC.'static']);
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
@ -220,14 +227,18 @@ class ReflectionCaster
|
||||
|
||||
private static function addExtra(&$a, \Reflector $c)
|
||||
{
|
||||
$a = &$a[Caster::PREFIX_VIRTUAL.'extra'];
|
||||
$x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : array();
|
||||
|
||||
if (method_exists($c, 'getFileName') && $m = $c->getFileName()) {
|
||||
$a['file'] = $m;
|
||||
$a['line'] = $c->getStartLine().' to '.$c->getEndLine();
|
||||
$x['file'] = $m;
|
||||
$x['line'] = $c->getStartLine().' to '.$c->getEndLine();
|
||||
}
|
||||
|
||||
self::addMap($a, $c, self::$extraMap, '');
|
||||
self::addMap($x, $c, self::$extraMap, '');
|
||||
|
||||
if ($x) {
|
||||
$a[Caster::PREFIX_VIRTUAL.'extra'] = new EnumStub($x);
|
||||
}
|
||||
}
|
||||
|
||||
private static function addMap(&$a, \Reflector $c, $map, $prefix = Caster::PREFIX_VIRTUAL)
|
||||
|
@ -48,4 +48,24 @@ class StubCaster
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
public static function castEnum(EnumStub $c, array $a, Stub $stub, $isNested)
|
||||
{
|
||||
if ($isNested) {
|
||||
$stub->class = '';
|
||||
$stub->handle = 0;
|
||||
|
||||
$a = array();
|
||||
|
||||
if ($c->value) {
|
||||
foreach (array_keys($c->value) as $k) {
|
||||
$keys[] = Caster::PREFIX_VIRTUAL.$k;
|
||||
}
|
||||
// Preserve references with array_combine()
|
||||
$a = array_combine($keys, $c->value);
|
||||
}
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ abstract class AbstractCloner implements ClonerInterface
|
||||
'Symfony\Component\VarDumper\Caster\CutStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub',
|
||||
'Symfony\Component\VarDumper\Caster\CutArrayStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castCutArray',
|
||||
'Symfony\Component\VarDumper\Caster\ConstStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub',
|
||||
'Symfony\Component\VarDumper\Caster\EnumStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castEnum',
|
||||
|
||||
'Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure',
|
||||
'ReflectionClass' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClass',
|
||||
|
@ -247,7 +247,7 @@ class CliDumper extends AbstractDumper
|
||||
$class = $this->utf8Encode($class);
|
||||
}
|
||||
if (Cursor::HASH_OBJECT === $type) {
|
||||
$prefix = 'stdClass' !== $class ? $this->style('note', $class).' {' : '{';
|
||||
$prefix = $class && 'stdClass' !== $class ? $this->style('note', $class).' {' : '{';
|
||||
} elseif (Cursor::HASH_RESOURCE === $type) {
|
||||
$prefix = $this->style('note', $class.' resource').($hasChild ? ' {' : ' ');
|
||||
} else {
|
||||
|
@ -29,8 +29,10 @@ class PdoCasterTest extends \PHPUnit_Framework_TestCase
|
||||
$pdo->setAttribute(\PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array($pdo)));
|
||||
|
||||
$cast = PdoCaster::castPdo($pdo, array(), new Stub(), false);
|
||||
$attr = $cast["\0~\0attributes"];
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\VarDumper\Caster\EnumStub', $cast["\0~\0attributes"]);
|
||||
|
||||
$attr = $cast["\0~\0attributes"] = $cast["\0~\0attributes"]->value;
|
||||
$this->assertInstanceOf('Symfony\Component\VarDumper\Caster\ConstStub', $attr['CASE']);
|
||||
$this->assertSame('NATURAL', $attr['CASE']->class);
|
||||
$this->assertSame('BOTH', $attr['DEFAULT_FETCH_MODE']->class);
|
||||
|
@ -39,7 +39,6 @@ ReflectionClass {
|
||||
%A +name: "name"
|
||||
+class: "ReflectionClass"
|
||||
%A modifiers: "public"
|
||||
extra: null
|
||||
}
|
||||
%A]
|
||||
methods: array:%d [
|
||||
@ -47,15 +46,34 @@ ReflectionClass {
|
||||
"export" => ReflectionMethod {
|
||||
+name: "export"
|
||||
+class: "ReflectionClass"
|
||||
parameters: array:2 [
|
||||
"$%s" => ReflectionParameter {
|
||||
parameters: {
|
||||
$%s: ReflectionParameter {
|
||||
%A position: 0
|
||||
%A }
|
||||
]
|
||||
modifiers: "public static"
|
||||
}
|
||||
%A
|
||||
}
|
||||
EOTXT
|
||||
, $var
|
||||
);
|
||||
}
|
||||
|
||||
public function testClosureCaster()
|
||||
{
|
||||
$a = $b = 123;
|
||||
$var = function ($x) use ($a, &$b) {};
|
||||
|
||||
$this->assertDumpMatchesFormat(
|
||||
<<<EOTXT
|
||||
Closure {
|
||||
%Aparameters: {
|
||||
\$x: {}
|
||||
}
|
||||
use: {
|
||||
\$a: 123
|
||||
\$b: & 123
|
||||
}
|
||||
file: "%sReflectionCasterTest.php"
|
||||
line: "62 to 62"
|
||||
}
|
||||
EOTXT
|
||||
, $var
|
||||
);
|
||||
|
@ -84,13 +84,13 @@ array:24 [
|
||||
+"bar": "bar"
|
||||
}
|
||||
"closure" => Closure {{$r}{$closure54}
|
||||
parameters: array:2 [
|
||||
"\$a" => []
|
||||
"&\$b" => array:2 [
|
||||
"typeHint" => "PDO"
|
||||
"default" => null
|
||||
]
|
||||
]
|
||||
parameters: {
|
||||
\$a: {}
|
||||
&\$b: {
|
||||
typeHint: "PDO"
|
||||
default: null
|
||||
}
|
||||
}
|
||||
file: "{$var['file']}"
|
||||
line: "{$var['line']} to {$var['line']}"
|
||||
}
|
||||
|
@ -87,13 +87,13 @@ EOTXT;
|
||||
+"<span class=sf-dump-public title="Runtime added dynamic property">bar</span>": "<span class=sf-dump-str title="3 characters">bar</span>"
|
||||
</samp>}
|
||||
"<span class=sf-dump-key>closure</span>" => <span class=sf-dump-note>Closure</span> {{$r}<samp>{$closure54}
|
||||
<span class=sf-dump-meta>parameters</span>: <span class=sf-dump-note>array:2</span> [<samp>
|
||||
"<span class=sf-dump-key>\$a</span>" => []
|
||||
"<span class=sf-dump-key>&\$b</span>" => <span class=sf-dump-note>array:2</span> [<samp>
|
||||
"<span class=sf-dump-key>typeHint</span>" => "<span class=sf-dump-str title="3 characters">PDO</span>"
|
||||
"<span class=sf-dump-key>default</span>" => <span class=sf-dump-const>null</span>
|
||||
</samp>]
|
||||
</samp>]
|
||||
<span class=sf-dump-meta>parameters</span>: {<samp>
|
||||
<span class=sf-dump-meta>\$a</span>: {}
|
||||
<span class=sf-dump-meta>&\$b</span>: {<samp>
|
||||
<span class=sf-dump-meta>typeHint</span>: "<span class=sf-dump-str title="3 characters">PDO</span>"
|
||||
<span class=sf-dump-meta>default</span>: <span class=sf-dump-const>null</span>
|
||||
</samp>}
|
||||
</samp>}
|
||||
<span class=sf-dump-meta>file</span>: "<span class=sf-dump-str title="%d characters">{$var['file']}</span>"
|
||||
<span class=sf-dump-meta>line</span>: "<span class=sf-dump-str title="%d characters">{$var['line']} to {$var['line']}</span>"
|
||||
</samp>}
|
||||
|
Reference in New Issue
Block a user