Skip to content

Commit 0c8b91c

Browse files
[TwigBridge] add Twig dump() function + tests and fixes
1 parent c845bcd commit 0c8b91c

13 files changed

+271
-128
lines changed

Caster/ReflectionCaster.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ public static function castReflector(\Reflector $c, array $a, Stub $stub, $isNes
2929

3030
public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested)
3131
{
32+
$stub->class = 'Closure'; // HHVM generates unique class names for closures
3233
$a = static::castReflector(new \ReflectionFunction($c), $a, $stub, $isNested);
33-
unset($a["\0+\0000"], $a['name']);
34+
unset($a["\0+\0000"], $a['name'], $a["\0+\0this"], $a["\0+\0parameter"]);
3435

3536
return $a;
3637
}

Caster/ResourceCaster.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static function castCurl($h, array $a, Stub $stub, $isNested)
2828
public static function castDba($dba, array $a, Stub $stub, $isNested)
2929
{
3030
$list = dba_list();
31-
$a['file'] = $list[substr((string) $dba, 13)];
31+
$a['file'] = $list[(int) $dba];
3232

3333
return $a;
3434
}

Cloner/AbstractCloner.php

Lines changed: 60 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -21,64 +21,64 @@
2121
abstract class AbstractCloner implements ClonerInterface
2222
{
2323
public static $defaultCasters = array(
24-
'o:Symfony\Component\VarDumper\Caster\CasterStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub',
25-
26-
'o:Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure',
27-
'o:Reflector' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castReflector',
28-
29-
'o:Doctrine\Common\Persistence\ObjectManager' => 'Symfony\Component\VarDumper\Caster\StubCaster::castNestedFat',
30-
'o:Doctrine\Common\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castCommonProxy',
31-
'o:Doctrine\ORM\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castOrmProxy',
32-
'o:Doctrine\ORM\PersistentCollection' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castPersistentCollection',
33-
34-
'o:DOMException' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castException',
35-
'o:DOMStringList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
36-
'o:DOMNameList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
37-
'o:DOMImplementation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castImplementation',
38-
'o:DOMImplementationList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
39-
'o:DOMNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNode',
40-
'o:DOMNameSpaceNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNameSpaceNode',
41-
'o:DOMDocument' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocument',
42-
'o:DOMNodeList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
43-
'o:DOMNamedNodeMap' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
44-
'o:DOMCharacterData' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castCharacterData',
45-
'o:DOMAttr' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castAttr',
46-
'o:DOMElement' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castElement',
47-
'o:DOMText' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castText',
48-
'o:DOMTypeinfo' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castTypeinfo',
49-
'o:DOMDomError' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDomError',
50-
'o:DOMLocator' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLocator',
51-
'o:DOMDocumentType' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocumentType',
52-
'o:DOMNotation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNotation',
53-
'o:DOMEntity' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castEntity',
54-
'o:DOMProcessingInstruction' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castProcessingInstruction',
55-
'o:DOMXPath' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castXPath',
56-
57-
'o:ErrorException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castErrorException',
58-
'o:Exception' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castException',
59-
'o:Symfony\Component\DependencyInjection\ContainerInterface'
24+
'Symfony\Component\VarDumper\Caster\CasterStub' => 'Symfony\Component\VarDumper\Caster\StubCaster::castStub',
25+
26+
'Closure' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castClosure',
27+
'Reflector' => 'Symfony\Component\VarDumper\Caster\ReflectionCaster::castReflector',
28+
29+
'Doctrine\Common\Persistence\ObjectManager' => 'Symfony\Component\VarDumper\Caster\StubCaster::castNestedFat',
30+
'Doctrine\Common\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castCommonProxy',
31+
'Doctrine\ORM\Proxy\Proxy' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castOrmProxy',
32+
'Doctrine\ORM\PersistentCollection' => 'Symfony\Component\VarDumper\Caster\DoctrineCaster::castPersistentCollection',
33+
34+
'DOMException' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castException',
35+
'DOMStringList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
36+
'DOMNameList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
37+
'DOMImplementation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castImplementation',
38+
'DOMImplementationList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
39+
'DOMNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNode',
40+
'DOMNameSpaceNode' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNameSpaceNode',
41+
'DOMDocument' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocument',
42+
'DOMNodeList' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
43+
'DOMNamedNodeMap' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLength',
44+
'DOMCharacterData' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castCharacterData',
45+
'DOMAttr' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castAttr',
46+
'DOMElement' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castElement',
47+
'DOMText' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castText',
48+
'DOMTypeinfo' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castTypeinfo',
49+
'DOMDomError' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDomError',
50+
'DOMLocator' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castLocator',
51+
'DOMDocumentType' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castDocumentType',
52+
'DOMNotation' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castNotation',
53+
'DOMEntity' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castEntity',
54+
'DOMProcessingInstruction' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castProcessingInstruction',
55+
'DOMXPath' => 'Symfony\Component\VarDumper\Caster\DOMCaster::castXPath',
56+
57+
'ErrorException' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castErrorException',
58+
'Exception' => 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castException',
59+
'Symfony\Component\DependencyInjection\ContainerInterface'
6060
=> 'Symfony\Component\VarDumper\Caster\StubCaster::castNestedFat',
61-
'o:Symfony\Component\VarDumper\Exception\ThrowingCasterException'
61+
'Symfony\Component\VarDumper\Exception\ThrowingCasterException'
6262
=> 'Symfony\Component\VarDumper\Caster\ExceptionCaster::castThrowingCasterException',
6363

64-
'o:PDO' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdo',
65-
'o:PDOStatement' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdoStatement',
66-
67-
'o:ArrayObject' => 'Symfony\Component\VarDumper\Caster\SplCaster::castArrayObject',
68-
'o:SplDoublyLinkedList' => 'Symfony\Component\VarDumper\Caster\SplCaster::castDoublyLinkedList',
69-
'o:SplFixedArray' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFixedArray',
70-
'o:SplHeap' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap',
71-
'o:SplObjectStorage' => 'Symfony\Component\VarDumper\Caster\SplCaster::castObjectStorage',
72-
'o:SplPriorityQueue' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap',
73-
74-
'r:curl' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castCurl',
75-
'r:dba' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba',
76-
'r:dba persistent' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba',
77-
'r:gd' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castGd',
78-
'r:mysql link' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castMysqlLink',
79-
'r:process' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castProcess',
80-
'r:stream' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStream',
81-
'r:stream-context' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStreamContext',
64+
'PDO' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdo',
65+
'PDOStatement' => 'Symfony\Component\VarDumper\Caster\PdoCaster::castPdoStatement',
66+
67+
'ArrayObject' => 'Symfony\Component\VarDumper\Caster\SplCaster::castArrayObject',
68+
'SplDoublyLinkedList' => 'Symfony\Component\VarDumper\Caster\SplCaster::castDoublyLinkedList',
69+
'SplFixedArray' => 'Symfony\Component\VarDumper\Caster\SplCaster::castFixedArray',
70+
'SplHeap' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap',
71+
'SplObjectStorage' => 'Symfony\Component\VarDumper\Caster\SplCaster::castObjectStorage',
72+
'SplPriorityQueue' => 'Symfony\Component\VarDumper\Caster\SplCaster::castHeap',
73+
74+
':curl' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castCurl',
75+
':dba' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba',
76+
':dba persistent' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castDba',
77+
':gd' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castGd',
78+
':mysql link' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castMysqlLink',
79+
':process' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castProcess',
80+
':stream' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStream',
81+
':stream-context' => 'Symfony\Component\VarDumper\Caster\ResourceCaster::castStreamContext',
8282
);
8383

8484
protected $maxItems = 250;
@@ -107,8 +107,7 @@ public function __construct(array $casters = null)
107107
*
108108
* Maps resources or objects types to a callback.
109109
* Types are in the key, with a callable caster for value.
110-
* Objects class are to be prefixed with a `o:`,
111-
* resources type are to be prefixed with a `r:`,
110+
* Resource types are to be prefixed with a `:`,
112111
* see e.g. static::$defaultCasters.
113112
*
114113
* @param callable[] $casters A map of casters.
@@ -193,7 +192,7 @@ protected function castObject($obj, Stub $stub, $isNested)
193192
$class,
194193
method_exists($class, '__debugInfo'),
195194
new \ReflectionClass($class),
196-
array_reverse(array($class => $class) + class_parents($class) + class_implements($class) + array('*' => '*')),
195+
array_reverse(array($class => $class) + class_parents($class) + class_implements($class)),
197196
);
198197

199198
$this->classInfo[$class] = $classInfo;
@@ -213,7 +212,7 @@ protected function castObject($obj, Stub $stub, $isNested)
213212
}
214213

215214
foreach ($classInfo[3] as $p) {
216-
if (!empty($this->casters[$p = 'o:'.strtolower($p)])) {
215+
if (!empty($this->casters[$p = strtolower($p)])) {
217216
foreach ($this->casters[$p] as $p) {
218217
$a = $this->callCaster($p, $obj, $a, $stub, $isNested);
219218
}
@@ -237,8 +236,8 @@ protected function castResource($res, Stub $stub, $isNested)
237236
$a = array();
238237
$type = $stub->class;
239238

240-
if (!empty($this->casters['r:'.$type])) {
241-
foreach ($this->casters['r:'.$type] as $c) {
239+
if (!empty($this->casters[':'.$type])) {
240+
foreach ($this->casters[':'.$type] as $c) {
242241
$a = $this->callCaster($c, $res, $a, $stub, $isNested);
243242
}
244243
}

Dumper/Cursor.php renamed to Cloner/Cursor.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Component\VarDumper\Dumper;
13-
14-
use Symfony\Component\VarDumper\Cloner\Stub;
12+
namespace Symfony\Component\VarDumper\Cloner;
1513

1614
/**
1715
* Represents the current state of a dumper while dumping.

Cloner/Data.php

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111

1212
namespace Symfony\Component\VarDumper\Cloner;
1313

14-
use Symfony\Component\VarDumper\Dumper\DumperInternalsInterface;
15-
use Symfony\Component\VarDumper\Dumper\Cursor;
16-
1714
/**
1815
* @author Nicolas Grekas <[email protected]>
1916
*/
@@ -57,21 +54,21 @@ public function getLimitedClone($maxDepth, $maxItemsPerDepth)
5754
}
5855

5956
/**
60-
* Dumps data with a DumperInternalsInterface dumper.
57+
* Dumps data with a DumperInterface dumper.
6158
*/
62-
public function dump(DumperInternalsInterface $dumper)
59+
public function dump(DumperInterface $dumper)
6360
{
6461
$refs = array(0);
6562
$this->dumpItem($dumper, new Cursor, $refs, $this->data[0][0]);
6663
}
6764

6865
/**
69-
* Breadth-first dumping of items.
66+
* Depth-first dumping of items.
7067
*
71-
* @param DumperInternalsInterface $dumper The dumper being used for dumping.
72-
* @param Cursor $cursor A cursor used for tracking dumper state position.
73-
* @param array &$refs A map of all references discovered while dumping.
74-
* @param mixed $item A Stub object or the original value being dumped.
68+
* @param DumperInterface $dumper The dumper being used for dumping.
69+
* @param Cursor $cursor A cursor used for tracking dumper state position.
70+
* @param array &$refs A map of all references discovered while dumping.
71+
* @param mixed $item A Stub object or the original value being dumped.
7572
*/
7673
private function dumpItem($dumper, $cursor, &$refs, $item)
7774
{
@@ -157,12 +154,12 @@ private function dumpItem($dumper, $cursor, &$refs, $item)
157154
/**
158155
* Dumps children of hash structures.
159156
*
160-
* @param DumperInternalsInterface $dumper
161-
* @param Cursor $parentCursor The cursor of the parent hash.
162-
* @param array &$refs A map of all references discovered while dumping.
163-
* @param array $children The children to dump.
164-
* @param int $hashCut The number of items removed from the original hash.
165-
* @param string $hashType A Cursor::HASH_* const.
157+
* @param DumperInterface $dumper
158+
* @param Cursor $parentCursor The cursor of the parent hash.
159+
* @param array &$refs A map of all references discovered while dumping.
160+
* @param array $children The children to dump.
161+
* @param int $hashCut The number of items removed from the original hash.
162+
* @param string $hashType A Cursor::HASH_* const.
166163
*
167164
* @return int The final number of removed items.
168165
*/

Dumper/DumperInternalsInterface.php renamed to Cloner/DumperInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Component\VarDumper\Dumper;
12+
namespace Symfony\Component\VarDumper\Cloner;
1313

1414
/**
1515
* DumperInterface used by Data objects.
1616
*
1717
* @author Nicolas Grekas <[email protected]>
1818
*/
19-
interface DumperInternalsInterface
19+
interface DumperInterface
2020
{
2121
/**
2222
* Dumps a scalar value.

Dumper/AbstractDumper.php

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212
namespace Symfony\Component\VarDumper\Dumper;
1313

1414
use Symfony\Component\VarDumper\Cloner\Data;
15+
use Symfony\Component\VarDumper\Cloner\DumperInterface;
1516

1617
/**
1718
* Abstract mechanism for dumping a Data object.
1819
*
1920
* @author Nicolas Grekas <[email protected]>
2021
*/
21-
abstract class AbstractDumper implements DataDumperInterface, DumperInternalsInterface
22+
abstract class AbstractDumper implements DataDumperInterface, DumperInterface
2223
{
2324
public static $defaultOutputStream = 'php://output';
2425

@@ -87,14 +88,22 @@ public function setIndentPad($pad)
8788
*/
8889
public function dump(Data $data, $lineDumper = null)
8990
{
90-
$this->decimalPoint = (string) 0.5;
91-
$this->decimalPoint = $this->decimalPoint[1];
92-
$dumper = clone $this;
91+
$exception = null;
92+
if ($lineDumper) {
93+
$prevLineDumper = $this->setLineDumper($lineDumper);
94+
}
95+
try {
96+
$data->dump($this);
97+
$this->dumpLine(-1);
98+
} catch (\Exception $exception) {
99+
// Re-thrown below
100+
}
93101
if ($lineDumper) {
94-
$dumper->setLineDumper($lineDumper);
102+
$this->setLineDumper($prevLineDumper);
103+
}
104+
if (null !== $exception) {
105+
throw $exception;
95106
}
96-
$data->dump($dumper);
97-
$dumper->dumpLine(false);
98107
}
99108

100109
/**
@@ -116,7 +125,7 @@ protected function dumpLine($depth)
116125
*/
117126
protected function echoLine($line, $depth)
118127
{
119-
if (false !== $depth) {
128+
if (-1 !== $depth) {
120129
fwrite($this->outputStream, str_repeat($this->indentPad, $depth).$line."\n");
121130
}
122131
}

Dumper/CliDumper.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\VarDumper\Dumper;
1313

1414
use Symfony\Component\VarDumper\Cloner\Data;
15+
use Symfony\Component\VarDumper\Cloner\Cursor;
1516

1617
/**
1718
* CliDumper dumps variables for command line output.

0 commit comments

Comments
 (0)