Skip to content

Commit

Permalink
feature #15837 [VarDumper] Add EnumStub for dumping virtual collectio…
Browse files Browse the repository at this point in the history
…ns 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
  • Loading branch information
fabpot committed Sep 22, 2015
2 parents b1e0bd7 + aa50596 commit fbf7351
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 33 deletions.
27 changes: 27 additions & 0 deletions src/Symfony/Component/VarDumper/Caster/EnumStub.php
@@ -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;
}
}
2 changes: 1 addition & 1 deletion src/Symfony/Component/VarDumper/Caster/PdoCaster.php
Expand Up @@ -82,7 +82,7 @@ public static function castPdo(\PDO $c, array $a, Stub $stub, $isNested)
$a += array(
$prefix.'inTransaction' => method_exists($c, 'inTransaction'),
$prefix.'errorInfo' => $c->errorInfo(),
$prefix.'attributes' => $attr,
$prefix.'attributes' => new EnumStub($attr),
);

if ($a[$prefix.'inTransaction']) {
Expand Down
3 changes: 2 additions & 1 deletion src/Symfony/Component/VarDumper/Caster/PgSqlCaster.php
Expand Up @@ -101,6 +101,7 @@ public static function castLink($link, array $a, Stub $stub, $isNested)
}

$a['param']['client_encoding'] = pg_client_encoding($link);
$a['param'] = new EnumStub($a['param']);

return $a;
}
Expand Down Expand Up @@ -145,7 +146,7 @@ public static function castResult($result, array $a, Stub $stub, $isNested)
if ('1 chars' === $field['display']) {
$field['display'] = '1 char';
}
$a['fields'][] = $field;
$a['fields'][] = new EnumStub($field);
}

return $a;
Expand Down
27 changes: 19 additions & 8 deletions src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php
Expand Up @@ -51,15 +51,15 @@ public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested)
$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);
}
}

Expand Down Expand Up @@ -128,18 +128,25 @@ public static function castFunctionAbstract(\ReflectionFunctionAbstract $c, arra
}
$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;
}

Expand Down Expand Up @@ -220,14 +227,18 @@ public static function castZendExtension(\ReflectionZendExtension $c, array $a,

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)
Expand Down
20 changes: 20 additions & 0 deletions src/Symfony/Component/VarDumper/Caster/StubCaster.php
Expand Up @@ -48,4 +48,24 @@ public static function cutInternals($obj, array $a, Stub $stub, $isNested)

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;
}
}
1 change: 1 addition & 0 deletions src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php
Expand Up @@ -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',
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Component/VarDumper/Dumper/CliDumper.php
Expand Up @@ -247,7 +247,7 @@ public function enterHash(Cursor $cursor, $type, $class, $hasChild)
$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 {
Expand Down
Expand Up @@ -29,8 +29,10 @@ public function testCastPdo()
$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);
Expand Down
Expand Up @@ -39,23 +39,41 @@ public function testReflectionCaster()
%A +name: "name"
+class: "ReflectionClass"
%A modifiers: "public"
extra: null
}
%A]
methods: array:%d [
%A
"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
);
Expand Down
14 changes: 7 additions & 7 deletions src/Symfony/Component/VarDumper/Tests/CliDumperTest.php
Expand Up @@ -84,13 +84,13 @@ class: "Symfony\Component\VarDumper\Tests\CliDumperTest"
+"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']}"
}
Expand Down
14 changes: 7 additions & 7 deletions src/Symfony/Component/VarDumper/Tests/HtmlDumperTest.php
Expand Up @@ -87,13 +87,13 @@ public function testGet()
+"<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>&amp;\$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>&amp;\$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>}
Expand Down

0 comments on commit fbf7351

Please sign in to comment.