From aa5059634591ffd398358611e72f955d838e174e Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 19 Sep 2015 14:03:48 +0200 Subject: [PATCH] [VarDumper] Add EnumStub for dumping virtual collections with casters --- .../Component/VarDumper/Caster/EnumStub.php | 27 ++++++++++++++++ .../Component/VarDumper/Caster/PdoCaster.php | 2 +- .../VarDumper/Caster/PgSqlCaster.php | 3 +- .../VarDumper/Caster/ReflectionCaster.php | 27 +++++++++++----- .../Component/VarDumper/Caster/StubCaster.php | 20 ++++++++++++ .../VarDumper/Cloner/AbstractCloner.php | 1 + .../Component/VarDumper/Dumper/CliDumper.php | 2 +- .../VarDumper/Tests/Caster/PdoCasterTest.php | 4 ++- .../Tests/Caster/ReflectionCasterTest.php | 32 +++++++++++++++---- .../VarDumper/Tests/CliDumperTest.php | 14 ++++---- .../VarDumper/Tests/HtmlDumperTest.php | 14 ++++---- 11 files changed, 113 insertions(+), 33 deletions(-) create mode 100644 src/Symfony/Component/VarDumper/Caster/EnumStub.php diff --git a/src/Symfony/Component/VarDumper/Caster/EnumStub.php b/src/Symfony/Component/VarDumper/Caster/EnumStub.php new file mode 100644 index 000000000000..67bb2e163903 --- /dev/null +++ b/src/Symfony/Component/VarDumper/Caster/EnumStub.php @@ -0,0 +1,27 @@ + + * + * 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 + */ +class EnumStub extends Stub +{ + public function __construct(array $values) + { + $this->value = $values; + } +} diff --git a/src/Symfony/Component/VarDumper/Caster/PdoCaster.php b/src/Symfony/Component/VarDumper/Caster/PdoCaster.php index 48c5306985c0..e60b9275fd89 100644 --- a/src/Symfony/Component/VarDumper/Caster/PdoCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/PdoCaster.php @@ -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']) { diff --git a/src/Symfony/Component/VarDumper/Caster/PgSqlCaster.php b/src/Symfony/Component/VarDumper/Caster/PgSqlCaster.php index 17b86456beab..88414e4ccff2 100644 --- a/src/Symfony/Component/VarDumper/Caster/PgSqlCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/PgSqlCaster.php @@ -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; } @@ -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; diff --git a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php index 48c5fd6f3672..8cdd68aa3605 100644 --- a/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php @@ -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); } } @@ -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; } @@ -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) diff --git a/src/Symfony/Component/VarDumper/Caster/StubCaster.php b/src/Symfony/Component/VarDumper/Caster/StubCaster.php index 542f8a19f4af..0b90358726a3 100644 --- a/src/Symfony/Component/VarDumper/Caster/StubCaster.php +++ b/src/Symfony/Component/VarDumper/Caster/StubCaster.php @@ -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; + } } diff --git a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php index 9d86fd2f3664..c8f9eb625849 100644 --- a/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php +++ b/src/Symfony/Component/VarDumper/Cloner/AbstractCloner.php @@ -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', diff --git a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php index 1fcad90c8740..26414b55a8ab 100644 --- a/src/Symfony/Component/VarDumper/Dumper/CliDumper.php +++ b/src/Symfony/Component/VarDumper/Dumper/CliDumper.php @@ -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 { diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/PdoCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/PdoCasterTest.php index 445b712ec9d9..3f4f94fc3d1a 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/PdoCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/PdoCasterTest.php @@ -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); diff --git a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php index 0fcc7e26bb36..9bb18723b327 100644 --- a/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php +++ b/src/Symfony/Component/VarDumper/Tests/Caster/ReflectionCasterTest.php @@ -39,7 +39,6 @@ public function testReflectionCaster() %A +name: "name" +class: "ReflectionClass" %A modifiers: "public" - extra: null } %A] methods: array:%d [ @@ -47,15 +46,34 @@ public function testReflectionCaster() "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( + << 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']}" } diff --git a/src/Symfony/Component/VarDumper/Tests/HtmlDumperTest.php b/src/Symfony/Component/VarDumper/Tests/HtmlDumperTest.php index a6e909fb4501..9cdd096ffe51 100644 --- a/src/Symfony/Component/VarDumper/Tests/HtmlDumperTest.php +++ b/src/Symfony/Component/VarDumper/Tests/HtmlDumperTest.php @@ -87,13 +87,13 @@ public function testGet() +"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']}" }