Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0beb598

Browse filesBrowse files
committed
feature #23967 [VarDumper] add force-collapse/expand + use it for traces (nicolas-grekas)
This PR was merged into the 3.4 branch. Discussion ---------- [VarDumper] add force-collapse/expand + use it for traces | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | not yet | Fixed tickets | - | License | MIT | Doc PR | - This improves dumping stack traces by expanding only frames that are outside of vendor dirs. Here the new CLI output (everything was expanded before): ![capture du 2017-08-24 15-24-01](https://user-images.githubusercontent.com/243674/29668407-614dfe32-88e0-11e7-85b3-8b4f774559a5.png) And here is the HTML output, with toggle-able frames: ![capture du 2017-08-24 15-24-40](https://user-images.githubusercontent.com/243674/29668410-65170c16-88e0-11e7-9388-147475a76b9f.png) Todo: - [x] make tests pass :) Commits ------- 0e2d2b8 [VarDumper] add force-collapse/expand + use it for traces
2 parents 4be4070 + 0e2d2b8 commit 0beb598
Copy full SHA for 0beb598

File tree

10 files changed

+133
-109
lines changed
Filter options

10 files changed

+133
-109
lines changed

‎src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/VarDumper/Caster/ExceptionCaster.php
+18-6Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, $is
127127
}
128128
$lastCall = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '';
129129
$frames[] = array('function' => '');
130+
$collapse = false;
130131

131132
for ($j += $trace->numberingOffset - $i++; isset($frames[$i]); ++$i, --$j) {
132133
$f = $frames[$i];
@@ -145,6 +146,13 @@ public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, $is
145146
$f = self::castFrameStub($frame, array(), $frame, true);
146147
if (isset($f[$prefix.'src'])) {
147148
foreach ($f[$prefix.'src']->value as $label => $frame) {
149+
if (0 === strpos($label, "\0~collapse=0")) {
150+
if ($collapse) {
151+
$label = substr_replace($label, '1', 11, 1);
152+
} else {
153+
$collapse = true;
154+
}
155+
}
148156
$label = substr_replace($label, "title=Stack level $j.&", 2, 0);
149157
}
150158
$f = $frames[$i - 1];
@@ -162,7 +170,7 @@ public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, $is
162170
} else {
163171
$label = substr_replace($prefix, "title=Stack level $j.", 2, 0).$lastCall;
164172
}
165-
$a[$label] = $frame;
173+
$a[substr_replace($label, sprintf('separator=%s&', $frame instanceof EnumStub ? ' ' : ':'), 2, 0)] = $frame;
166174

167175
$lastCall = $call;
168176
}
@@ -197,9 +205,10 @@ public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $is
197205
$caller = isset($f['function']) ? sprintf('in %s() on line %d', (isset($f['class']) ? $f['class'].$f['type'] : '').$f['function'], $f['line']) : null;
198206
$src = $f['line'];
199207
$srcKey = $f['file'];
200-
$ellipsis = (new LinkStub($srcKey, 0))->attr;
201-
$ellipsisTail = isset($ellipsis['ellipsis-tail']) ? $ellipsis['ellipsis-tail'] : 0;
202-
$ellipsis = isset($ellipsis['ellipsis']) ? $ellipsis['ellipsis'] : 0;
208+
$ellipsis = new LinkStub($srcKey, 0);
209+
$srcAttr = 'collapse='.(int) $ellipsis->inVendor;
210+
$ellipsisTail = isset($ellipsis->attr['ellipsis-tail']) ? $ellipsis->attr['ellipsis-tail'] : 0;
211+
$ellipsis = isset($ellipsis->attr['ellipsis']) ? $ellipsis->attr['ellipsis'] : 0;
203212

204213
if (file_exists($f['file']) && 0 <= self::$srcContext) {
205214
if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) {
@@ -225,8 +234,11 @@ public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $is
225234
$ellipsis += 1 + strlen($f['line']);
226235
}
227236
}
237+
$srcAttr .= '&separator= ';
238+
} else {
239+
$srcAttr .= '&separator=:';
228240
}
229-
$srcAttr = $ellipsis ? 'ellipsis-type=path&ellipsis='.$ellipsis.'&ellipsis-tail='.$ellipsisTail : '';
241+
$srcAttr .= $ellipsis ? '&ellipsis-type=path&ellipsis='.$ellipsis.'&ellipsis-tail='.$ellipsisTail : '';
230242
self::$framesCache[$cacheKey] = $a[$prefix.'src'] = new EnumStub(array("\0~$srcAttr\0$srcKey" => $src));
231243
}
232244
}
@@ -329,7 +341,7 @@ private static function extractSource($srcLines, $line, $srcContext, $title, $la
329341
}
330342
}
331343
$c->attr['lang'] = $lang;
332-
$srcLines[sprintf("\0~%d\0", $i + $line - $srcContext)] = $c;
344+
$srcLines[sprintf("\0~separator=› &%d\0", $i + $line - $srcContext)] = $c;
333345
}
334346

335347
return new EnumStub($srcLines);

‎src/Symfony/Component/VarDumper/Caster/LinkStub.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/VarDumper/Caster/LinkStub.php
+4-2Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919
class LinkStub extends ConstStub
2020
{
21+
public $inVendor = false;
22+
2123
private static $vendorRoots;
2224
private static $composerRoots;
2325

@@ -50,10 +52,10 @@ public function __construct($label, $line = 0, $href = null)
5052
if ($label !== $this->attr['file'] = realpath($href) ?: $href) {
5153
return;
5254
}
53-
if ($composerRoot = $this->getComposerRoot($href, $inVendor)) {
55+
if ($composerRoot = $this->getComposerRoot($href, $this->inVendor)) {
5456
$this->attr['ellipsis'] = strlen($href) - strlen($composerRoot) + 1;
5557
$this->attr['ellipsis-type'] = 'path';
56-
$this->attr['ellipsis-tail'] = 1 + ($inVendor ? 2 + strlen(implode(array_slice(explode(DIRECTORY_SEPARATOR, substr($href, 1 - $this->attr['ellipsis'])), 0, 2))) : 0);
58+
$this->attr['ellipsis-tail'] = 1 + ($this->inVendor ? 2 + strlen(implode(array_slice(explode(DIRECTORY_SEPARATOR, substr($href, 1 - $this->attr['ellipsis'])), 0, 2))) : 0);
5759
} elseif (3 < count($ellipsis = explode(DIRECTORY_SEPARATOR, $href))) {
5860
$this->attr['ellipsis'] = 2 + strlen(implode(array_slice($ellipsis, -2)));
5961
$this->attr['ellipsis-type'] = 'path';

‎src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public static function castReflectionGenerator(\ReflectionGenerator $c, array $a
122122
$function = new FrameStub($frame, false, true);
123123
$function = ExceptionCaster::castFrameStub($function, array(), $function, true);
124124
$a[$prefix.'executing'] = new EnumStub(array(
125-
$frame['class'].$frame['type'].$frame['function'].'()' => $function[$prefix.'src'],
125+
"\0~separator= \0".$frame['class'].$frame['type'].$frame['function'].'()' => $function[$prefix.'src'],
126126
));
127127
}
128128

‎src/Symfony/Component/VarDumper/Cloner/Cursor.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/VarDumper/Cloner/Cursor.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@ class Cursor
3939
public $hashCut = 0;
4040
public $stop = false;
4141
public $attr = array();
42+
public $skipChildren = false;
4243
}

‎src/Symfony/Component/VarDumper/Cloner/Data.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/VarDumper/Cloner/Data.php
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,10 +355,16 @@ private function dumpItem($dumper, $cursor, &$refs, $item)
355355
$withChildren = $children && $cursor->depth !== $this->maxDepth && $this->maxItemsPerDepth;
356356
$dumper->enterHash($cursor, $item->type, $item->class, $withChildren);
357357
if ($withChildren) {
358-
$cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->type, null !== $item->class);
358+
if ($cursor->skipChildren) {
359+
$withChildren = false;
360+
$cut = -1;
361+
} else {
362+
$cut = $this->dumpChildren($dumper, $cursor, $refs, $children, $cut, $item->type, null !== $item->class);
363+
}
359364
} elseif ($children && 0 <= $cut) {
360365
$cut += count($children);
361366
}
367+
$cursor->skipChildren = false;
362368
$dumper->leaveHash($cursor, $item->type, $item->class, $withChildren, $cut);
363369
break;
364370

‎src/Symfony/Component/VarDumper/Dumper/CliDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/VarDumper/Dumper/CliDumper.php
+32-1Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ class CliDumper extends AbstractDumper
5151
"\033" => '\e',
5252
);
5353

54+
protected $collapseNextHash = false;
55+
protected $expandNextHash = false;
56+
5457
/**
5558
* {@inheritdoc}
5659
*/
@@ -253,6 +256,11 @@ public function enterHash(Cursor $cursor, $type, $class, $hasChild)
253256
{
254257
$this->dumpKey($cursor);
255258

259+
if ($this->collapseNextHash) {
260+
$cursor->skipChildren = true;
261+
$this->collapseNextHash = $hasChild = false;
262+
}
263+
256264
$class = $this->utf8Encode($class);
257265
if (Cursor::HASH_OBJECT === $type) {
258266
$prefix = $class && 'stdClass' !== $class ? $this->style('note', $class).' {' : '{';
@@ -368,7 +376,15 @@ protected function dumpKey(Cursor $cursor)
368376
break;
369377
}
370378

371-
$this->line .= $bin.$this->style($style, $key[1], $attr).': ';
379+
if (isset($attr['collapse'])) {
380+
if ($attr['collapse']) {
381+
$this->collapseNextHash = true;
382+
} else {
383+
$this->expandNextHash = true;
384+
}
385+
}
386+
387+
$this->line .= $bin.$this->style($style, $key[1], $attr).(isset($attr['separator']) ? $attr['separator'] : ': ');
372388
} else {
373389
// This case should not happen
374390
$this->line .= '-'.$bin.'"'.$this->style('private', $key, array('class' => '')).'": ';
@@ -397,6 +413,21 @@ protected function style($style, $value, $attr = array())
397413
$this->colors = $this->supportsColors();
398414
}
399415

416+
if (isset($attr['ellipsis'], $attr['ellipsis-type'])) {
417+
$prefix = substr($value, 0, -$attr['ellipsis']);
418+
if ('cli' === PHP_SAPI && 'path' === $attr['ellipsis-type'] && isset($_SERVER[$pwd = '\\' === DIRECTORY_SEPARATOR ? 'CD' : 'PWD']) && 0 === strpos($prefix, $_SERVER[$pwd])) {
419+
$prefix = '.'.substr($prefix, strlen($_SERVER[$pwd]));
420+
}
421+
if (!empty($attr['ellipsis-tail'])) {
422+
$prefix .= substr($value, -$attr['ellipsis'], $attr['ellipsis-tail']);
423+
$value = substr($value, -$attr['ellipsis'] + $attr['ellipsis-tail']);
424+
} else {
425+
$value = substr($value, -$attr['ellipsis']);
426+
}
427+
428+
return $this->style('default', $prefix).$this->style($style, $value);
429+
}
430+
400431
$style = $this->styles[$style];
401432

402433
$map = static::$controlCharsMap;

‎src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/VarDumper/Dumper/HtmlDumper.php
+15-5Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,6 @@ function xpathString(str) {
366366
for (i = 0; i < len; ++i) {
367367
elt = t[i];
368368
if ('SAMP' == elt.tagName) {
369-
elt.className = 'sf-dump-expanded';
370369
a = elt.previousSibling || {};
371370
if ('A' != a.tagName) {
372371
a = doc.createElement('A');
@@ -384,7 +383,8 @@ function xpathString(str) {
384383
x += elt.parentNode.getAttribute('data-depth')/1;
385384
}
386385
elt.setAttribute('data-depth', x);
387-
if (x > options.maxDepth) {
386+
if (elt.className ? 'sf-dump-expanded' !== elt.className : (x > options.maxDepth)) {
387+
elt.className = 'sf-dump-expanded';
388388
toggle(a);
389389
}
390390
} else if (/\bsf-dump-ref\b/.test(elt.className) && (a = elt.getAttribute('href'))) {
@@ -728,15 +728,25 @@ public function enterHash(Cursor $cursor, $type, $class, $hasChild)
728728
{
729729
parent::enterHash($cursor, $type, $class, false);
730730

731+
if ($cursor->skipChildren) {
732+
$cursor->skipChildren = false;
733+
$eol = ' class=sf-dump-compact>';
734+
} elseif ($this->expandNextHash) {
735+
$this->expandNextHash = false;
736+
$eol = ' class=sf-dump-expanded>';
737+
} else {
738+
$eol = '>';
739+
}
740+
731741
if ($hasChild) {
742+
$this->line .= '<samp';
732743
if ($cursor->refIndex) {
733744
$r = Cursor::HASH_OBJECT !== $type ? 1 - (Cursor::HASH_RESOURCE !== $type) : 2;
734745
$r .= $r && 0 < $cursor->softRefHandle ? $cursor->softRefHandle : $cursor->refIndex;
735746

736-
$this->line .= sprintf('<samp id=%s-ref%s>', $this->dumpId, $r);
737-
} else {
738-
$this->line .= '<samp>';
747+
$this->line .= sprintf(' id=%s-ref%s', $this->dumpId, $r);
739748
}
749+
$this->line .= $eol;
740750
$this->dumpLine($cursor->depth);
741751
}
742752
}

‎src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/VarDumper/Tests/Caster/ExceptionCasterTest.php
+29-45Lines changed: 29 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,13 @@ public function testDefaultSettings()
4646
#file: "%sExceptionCasterTest.php"
4747
#line: 28
4848
trace: {
49-
%sExceptionCasterTest.php:28: {
50-
: {
51-
: return new \Exception(''.$msg);
52-
: }
53-
}
54-
%sExceptionCasterTest.php:%d: {
55-
: $ref = array('foo');
56-
: $e = $this->getTestException('foo', $ref);
57-
:
58-
arguments: {
59-
$msg: "foo"
60-
&$ref: array:1 [ …1]
61-
}
49+
%s%eTests%eCaster%eExceptionCasterTest.php:28 {
50+
› {
51+
› return new \Exception(''.$msg);
52+
› }
6253
}
54+
%s%eTests%eCaster%eExceptionCasterTest.php:40 { …}
55+
Symfony\Component\VarDumper\Tests\Caster\ExceptionCasterTest->testDefaultSettings() {}
6356
%A
6457
EODUMP;
6558

@@ -73,19 +66,13 @@ public function testSeek()
7366

7467
$expectedDump = <<<'EODUMP'
7568
{
76-
%sExceptionCasterTest.php:28: {
77-
: {
78-
: return new \Exception(''.$msg);
79-
: }
80-
}
81-
%sExceptionCasterTest.php:%d: {
82-
: {
83-
: $e = $this->getTestException(2);
84-
:
85-
arguments: {
86-
$msg: 2
87-
}
69+
%s%eTests%eCaster%eExceptionCasterTest.php:28 {
70+
› {
71+
› return new \Exception(''.$msg);
72+
› }
8873
}
74+
%s%eTests%eCaster%eExceptionCasterTest.php:65 { …}
75+
Symfony\Component\VarDumper\Tests\Caster\ExceptionCasterTest->testSeek() {}
8976
%A
9077
EODUMP;
9178

@@ -104,16 +91,13 @@ public function testNoArgs()
10491
#file: "%sExceptionCasterTest.php"
10592
#line: 28
10693
trace: {
107-
%sExceptionCasterTest.php:28: {
108-
: {
109-
: return new \Exception(''.$msg);
110-
: }
111-
}
112-
%sExceptionCasterTest.php:%d: {
113-
: {
114-
: $e = $this->getTestException(1);
115-
: ExceptionCaster::$traceArgs = false;
94+
%sExceptionCasterTest.php:28 {
95+
› {
96+
› return new \Exception(''.$msg);
97+
› }
11698
}
99+
%s%eTests%eCaster%eExceptionCasterTest.php:84 { …}
100+
Symfony\Component\VarDumper\Tests\Caster\ExceptionCasterTest->testNoArgs() {}
117101
%A
118102
EODUMP;
119103

@@ -132,8 +116,8 @@ public function testNoSrcContext()
132116
#file: "%sExceptionCasterTest.php"
133117
#line: 28
134118
trace: {
135-
%sExceptionCasterTest.php: 28
136-
%sExceptionCasterTest.php: %d
119+
%s%eTests%eCaster%eExceptionCasterTest.php:28
120+
%s%eTests%eCaster%eExceptionCasterTest.php:%d
137121
%A
138122
EODUMP;
139123

@@ -161,7 +145,7 @@ public function testHtmlDump()
161145
#<span class=sf-dump-protected title="Protected property">line</span>: <span class=sf-dump-num>28</span>
162146
<span class=sf-dump-meta>trace</span>: {<samp>
163147
<span class=sf-dump-meta title="%sExceptionCasterTest.php
164-
Stack level %d."><span class="sf-dump-ellipsis sf-dump-ellipsis-path">%s%eVarDumper</span><span class=sf-dump-ellipsis>%e</span>Tests%eCaster%eExceptionCasterTest.php</span>: <span class=sf-dump-num>28</span>
148+
Stack level %d."><span class="sf-dump-ellipsis sf-dump-ellipsis-path">%s%eVarDumper</span><span class=sf-dump-ellipsis>%e</span>Tests%eCaster%eExceptionCasterTest.php</span>:<span class=sf-dump-num>28</span>
165149
&hellip;%d
166150
</samp>}
167151
</samp>}
@@ -197,10 +181,10 @@ public function testFrameWithTwig()
197181
0 => {
198182
class: "__TwigTemplate_VarDumperFixture_u75a09"
199183
src: {
200-
%sTwig.php:1: {
201-
:
202-
: foo bar
203-
: twig source
184+
%sTwig.php:1 {
185+
186+
foo bar
187+
twig source
204188
}
205189
}
206190
}
@@ -210,10 +194,10 @@ class: "__TwigTemplate_VarDumperFixture_u75a09"
210194
%A
211195
}
212196
src: {
213-
%sExceptionCasterTest.php:2: {
214-
: foo bar
215-
: twig source
216-
:
197+
%sExceptionCasterTest.php:2 {
198+
foo bar
199+
twig source
200+
217201
}
218202
}
219203
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.