Skip to content

Commit

Permalink
[VarDumper] enhance dumping refs
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-grekas committed Oct 17, 2014
1 parent 8e42756 commit 3c401af
Show file tree
Hide file tree
Showing 13 changed files with 380 additions and 367 deletions.
12 changes: 6 additions & 6 deletions src/Symfony/Bridge/Twig/Tests/Extension/DumpExtensionTest.php
Expand Up @@ -86,20 +86,20 @@ public function getDumpArgs()
{
return array(
array(array(), array(), '', false),
array(array(), array(), "<pre class=sf-dump>[]\n</pre><script>Sfdump.instrument()</script>\n"),
array(array(), array(), "<pre class=sf-dump id=sf-dump data-indent-pad=\" \">[]\n</pre><script>Sfdump(\"sf-dump\")</script>\n"),
array(
array(),
array(123, 456),
"<pre class=sf-dump><span class=sf-dump-num>123</span>\n</pre><script>Sfdump.instrument()</script>\n"
."<pre class=sf-dump><span class=sf-dump-num>456</span>\n</pre><script>Sfdump.instrument()</script>\n",
"<pre class=sf-dump id=sf-dump data-indent-pad=\" \"><span class=sf-dump-num>123</span>\n</pre><script>Sfdump(\"sf-dump\")</script>\n"
."<pre class=sf-dump id=sf-dump data-indent-pad=\" \"><span class=sf-dump-num>456</span>\n</pre><script>Sfdump(\"sf-dump\")</script>\n",
),
array(
array('foo' => 'bar'),
array(),
"<pre class=sf-dump><span class=sf-dump-note>array:1</span> [<span name=sf-dump-child>\n"
"<pre class=sf-dump id=sf-dump data-indent-pad=\" \"><span class=sf-dump-note>array:1</span> [<samp>\n"
." \"<span class=sf-dump-meta>foo</span>\" => \"<span class=sf-dump-str>bar</span>\"\n"
."</span>]\n"
."</pre><script>Sfdump.instrument()</script>\n",
."</samp>]\n"
."</pre><script>Sfdump(\"sf-dump\")</script>\n",
),
);
}
Expand Down
Expand Up @@ -35,10 +35,11 @@ public function testDump()
$dump = $collector->getDumps('html');
$this->assertTrue(isset($dump[0]['data']));
$dump[0]['data'] = preg_replace('/^.*?<pre/', '<pre', $dump[0]['data']);
$dump[0]['data'] = preg_replace('/sf-dump-\d+/', 'sf-dump', $dump[0]['data']);

$xDump = array(
array(
'data' => "<pre class=sf-dump><span class=sf-dump-num>123</span>\n</pre><script>Sfdump.instrument()</script>\n",
'data' => "<pre class=sf-dump id=sf-dump data-indent-pad=\" \"><span class=sf-dump-num>123</span>\n</pre><script>Sfdump(\"sf-dump\")</script>\n",
'name' => 'DumpDataCollectorTest.php',
'file' => __FILE__,
'line' => $line,
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/VarDumper/Caster/CasterStub.php
Expand Up @@ -41,6 +41,7 @@ public function __construct($value, $class = '')
case 'resource':
case 'unknown type':
$this->type = self::TYPE_RESOURCE;
$this->handle = (int) $value;
$this->class = @get_resource_type($value);
$this->cut = -1;
break;
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/VarDumper/Caster/StubCaster.php
Expand Up @@ -26,6 +26,7 @@ public static function castStub(CasterStub $c, array $a, Stub $stub, $isNested)
$stub->type = $c->type;
$stub->class = $c->class;
$stub->value = $c->value;
$stub->handle = $c->handle;
$stub->cut = $c->cut;

return array();
Expand Down
10 changes: 7 additions & 3 deletions src/Symfony/Component/VarDumper/Cloner/Cursor.php
Expand Up @@ -24,9 +24,13 @@ class Cursor
const HASH_RESOURCE = Stub::TYPE_RESOURCE;

public $depth = 0;
public $refIndex = false;
public $softRefTo = false;
public $hardRefTo = false;
public $refIndex = 0;
public $softRefTo = 0;
public $softRefCount = 0;
public $softRefHandle = 0;
public $hardRefTo = 0;
public $hardRefCount = 0;
public $hardRefHandle = 0;
public $hashType;
public $hashKey;
public $hashIndex = 0;
Expand Down
58 changes: 27 additions & 31 deletions src/Symfony/Component/VarDumper/Cloner/Data.php
Expand Up @@ -59,7 +59,7 @@ public function getLimitedClone($maxDepth, $maxItemsPerDepth)
public function dump(DumperInterface $dumper)
{
$refs = array(0);
$this->dumpItem($dumper, new Cursor, $refs, $this->data[0][0]);
$this->dumpItem($dumper, new Cursor(), $refs, $this->data[0][0]);
}

/**
Expand All @@ -72,40 +72,41 @@ public function dump(DumperInterface $dumper)
*/
private function dumpItem($dumper, $cursor, &$refs, $item)
{
$cursor->refIndex = $cursor->softRefTo = $cursor->hardRefTo = false;
$cursor->refIndex = 0;
$cursor->softRefTo = $cursor->softRefHandle = $cursor->softRefCount = 0;
$cursor->hardRefTo = $cursor->hardRefHandle = $cursor->hardRefCount = 0;
$firstSeen = true;

if (!$item instanceof Stub) {
$type = gettype($item);
} elseif (Stub::TYPE_REF === $item->type) {
if ($item->ref) {
if (isset($refs[$r = $item->ref])) {
$cursor->hardRefTo = $refs[$r];
if ($item->handle) {
if (!isset($refs[$r = $item->handle - (PHP_INT_MAX >> 1)])) {
$cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0];
} else {
$cursor->refIndex = $refs[$r] = ++$refs[0];
$firstSeen = false;
}
$cursor->hardRefTo = $refs[$r];
$cursor->hardRefHandle = $item->handle;
$cursor->hardRefCount = $item->refCount;
}
$type = $item->class ?: gettype($item->value);
$item = $item->value;
}
if ($item instanceof Stub) {
if ($item->ref) {
if (isset($refs[$r = $item->ref])) {
if (Stub::TYPE_ARRAY === $item->type) {
if (false === $cursor->hardRefTo) {
$cursor->hardRefTo = $refs[$r];
}
} elseif (false === $cursor->softRefTo) {
$cursor->softRefTo = $refs[$r];
}
} elseif (false !== $cursor->refIndex) {
$refs[$r] = $cursor->refIndex;
if ($item->refCount) {
if (!isset($refs[$r = $item->handle])) {
$cursor->refIndex = $refs[$r] = $cursor->refIndex ?: ++$refs[0];
} else {
$cursor->refIndex = $refs[$r] = ++$refs[0];
$firstSeen = false;
}
$cursor->softRefTo = $refs[$r];
}
$cursor->softRefHandle = $item->handle;
$cursor->softRefCount = $item->refCount;
$cut = $item->cut;

if ($item->position && false === $cursor->softRefTo && false === $cursor->hardRefTo) {
if ($item->position && $firstSeen) {
$children = $this->data[$item->position];

if ($cursor->stop) {
Expand All @@ -123,29 +124,24 @@ private function dumpItem($dumper, $cursor, &$refs, $item)
break;

case Stub::TYPE_ARRAY:
$dumper->enterArray($cursor, $item->value, Stub::ARRAY_INDEXED === $item->class, (bool) $children);
$dumper->enterHash($cursor, $item->class, $item->value, (bool) $children);
$cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->class);
$dumper->leaveArray($cursor, $item->value, Stub::ARRAY_INDEXED === $item->class, (bool) $children, $cut);
$dumper->leaveHash($cursor, $item->class, $item->value, (bool) $children, $cut);
break;

case Stub::TYPE_OBJECT:
$dumper->enterObject($cursor, $item->class, (bool) $children);
$cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, Cursor::HASH_OBJECT);
$dumper->leaveObject($cursor, $item->class, (bool) $children, $cut);
break;

case Stub::TYPE_RESOURCE:
$dumper->enterResource($cursor, $item->class, (bool) $children);
$cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, Cursor::HASH_RESOURCE);
$dumper->leaveResource($cursor, $item->class, (bool) $children, $cut);
$dumper->enterHash($cursor, $item->type, $item->class, (bool) $children);
$cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->type);
$dumper->leaveHash($cursor, $item->type, $item->class, (bool) $children, $cut);
break;

default:
throw new \RuntimeException(sprintf('Unexpected Stub type: %s', $item->type));
}
} elseif ('array' === $type) {
$dumper->enterArray($cursor, 0, true, 0, 0);
$dumper->leaveArray($cursor, 0, true, 0, 0);
$dumper->enterHash($cursor, Cursor::HASH_INDEXED, 0, false);
$dumper->leaveHash($cursor, Cursor::HASH_INDEXED, 0, false, 0);
} else {
$dumper->dumpScalar($cursor, $type, $item);
}
Expand Down
60 changes: 11 additions & 49 deletions src/Symfony/Component/VarDumper/Cloner/DumperInterface.php
Expand Up @@ -38,61 +38,23 @@ public function dumpScalar(Cursor $cursor, $type, $value);
public function dumpString(Cursor $cursor, $str, $bin, $cut);

/**
* Dumps while entering an array.
* Dumps while entering an hash.
*
* @param Cursor $cursor The Cursor position in the dump.
* @param int $count The number of items in the original array.
* @param bool $indexed When the array is indexed or associative.
* @param bool $hasChild When the dump of the array has child item.
* @param int $type A Cursor::HASH_* const for the type of hash.
* @param string $class The object class, resource type or array count.
* @param bool $hasChild When the dump of the hash has child item.
*/
public function enterArray(Cursor $cursor, $count, $indexed, $hasChild);
public function enterHash(Cursor $cursor, $type, $class, $hasChild);

/**
* Dumps while leaving an array.
* Dumps while leaving an hash.
*
* @param Cursor $cursor The Cursor position in the dump.
* @param int $count The number of items in the original array.
* @param bool $indexed Whether the array is indexed or associative.
* @param bool $hasChild When the dump of the array has child item.
* @param int $cut The number of items the array has been cut by.
* @param int $type A Cursor::HASH_* const for the type of hash.
* @param string $class The object class, resource type or array count.
* @param bool $hasChild When the dump of the hash has child item.
* @param int $cut The number of items the hash has been cut by.
*/
public function leaveArray(Cursor $cursor, $count, $indexed, $hasChild, $cut);

/**
* Dumps while entering an object.
*
* @param Cursor $cursor The Cursor position in the dump.
* @param string $class The class of the object.
* @param bool $hasChild When the dump of the object has child item.
*/
public function enterObject(Cursor $cursor, $class, $hasChild);

/**
* Dumps while leaving an object.
*
* @param Cursor $cursor The Cursor position in the dump.
* @param string $class The class of the object.
* @param bool $hasChild When the dump of the object has child item.
* @param int $cut The number of items the object has been cut by.
*/
public function leaveObject(Cursor $cursor, $class, $hasChild, $cut);

/**
* Dumps while entering a resource.
*
* @param Cursor $cursor The Cursor position in the dump.
* @param string $res The resource type.
* @param bool $hasChild When the dump of the resource has child item.
*/
public function enterResource(Cursor $cursor, $res, $hasChild);

/**
* Dumps while leaving a resource.
*
* @param Cursor $cursor The Cursor position in the dump.
* @param string $res The resource type.
* @param bool $hasChild When the dump of the resource has child item.
* @param int $cut The number of items the resource has been cut by.
*/
public function leaveResource(Cursor $cursor, $res, $hasChild, $cut);
public function leaveHash(Cursor $cursor, $type, $class, $hasChild, $cut);
}
3 changes: 2 additions & 1 deletion src/Symfony/Component/VarDumper/Cloner/Stub.php
Expand Up @@ -34,6 +34,7 @@ class Stub
public $class = '';
public $value;
public $cut = 0;
public $ref = 0;
public $handle = 0;
public $refCount = 0;
public $position = 0;
}

0 comments on commit 3c401af

Please sign in to comment.