Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8eb252e

Browse files
[VarDumper] Enhance dumping arguments in stack traces
1 parent 4fbf80d commit 8eb252e

File tree

4 files changed

+187
-19
lines changed

4 files changed

+187
-19
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\VarDumper\Caster;
13+
14+
use Symfony\Component\VarDumper\Cloner\Stub;
15+
16+
/**
17+
* Represents a list of function arguments.
18+
*
19+
* @author Nicolas Grekas <[email protected]>
20+
*/
21+
class ArgsStub extends EnumStub
22+
{
23+
private static $parameters = array();
24+
25+
public function __construct(array $values, $function, $class)
26+
{
27+
list($variadic, $params) = self::getParameters($function, $class);
28+
29+
foreach ($values as $k => $v) {
30+
if (!is_scalar($v) && !$v instanceof Stub) {
31+
$values[$k] = new CutStub($v);
32+
}
33+
}
34+
if (null === $params) {
35+
parent::__construct($values, false);
36+
37+
return;
38+
}
39+
if (count($values) < count($params)) {
40+
$params = array_slice($params, 0, count($values));
41+
} elseif (count($values) > count($params)) {
42+
$values[] = new EnumStub(array_splice($values, count($params)), false);
43+
$params[] = $variadic;
44+
}
45+
if (array('...') === $params) {
46+
$this->dumpKeys = false;
47+
$this->value = $values[0]->value;
48+
} else {
49+
$this->value = array_combine($params, $values);
50+
}
51+
}
52+
53+
private static function getParameters($function, $class)
54+
{
55+
if (isset(self::$parameters[$k = $class.'::'.$function])) {
56+
return self::$parameters[$k];
57+
}
58+
59+
try {
60+
$r = null !== $class ? new \ReflectionMethod($class, $function) : new \ReflectionFunction($function);
61+
} catch (\ReflectionException $e) {
62+
return array(null, null);
63+
}
64+
65+
$variadic = '...';
66+
$params = array();
67+
foreach ($r->getParameters() as $v) {
68+
$k = '$'.$v->name;
69+
if ($v->isPassedByReference()) {
70+
$k = '&'.$k;
71+
}
72+
if (method_exists($v, 'isVariadic') && $v->isVariadic()) {
73+
$variadic .= $k;
74+
} else {
75+
$params[] = $k;
76+
}
77+
}
78+
79+
return self::$parameters[$k] = array($variadic, $params);
80+
}
81+
}

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

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,7 @@ public static function castThrowingCasterException(ThrowingCasterException $e, a
6767

6868
if (isset($a[$xPrefix.'previous'], $a[$xPrefix.'trace'])) {
6969
$b = (array) $a[$xPrefix.'previous'];
70-
array_unshift($b[$xPrefix.'trace'], array(
71-
'function' => 'new '.get_class($a[$xPrefix.'previous']),
72-
'file' => $b[$prefix.'file'],
73-
'line' => $b[$prefix.'line'],
74-
));
70+
self::traceUnshift($b[$xPrefix.'trace'], get_class($a[$xPrefix.'previous']), $b[$prefix.'file'], $b[$prefix.'line']);
7571
$a[$xPrefix.'trace'] = new TraceStub($b[$xPrefix.'trace'], false, 0, -1 - count($a[$xPrefix.'trace']->value));
7672
}
7773

@@ -121,8 +117,8 @@ public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, $is
121117
foreach ($f[$prefix.'src']->value as $label => $frame) {
122118
$label = substr_replace($label, "title=Stack level $j.&", 2, 0);
123119
}
124-
if (isset($f[$prefix.'args']) && $frame instanceof EnumStub) {
125-
$frame->value['args'] = $f[$prefix.'args'];
120+
if (isset($f[$prefix.'arguments']) && $frame instanceof EnumStub) {
121+
$frame->value['arguments'] = $f[$prefix.'arguments'];
126122
}
127123
}
128124
$a[$label] = $frame;
@@ -192,8 +188,8 @@ public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $is
192188
unset($a[$k]);
193189
}
194190
}
195-
if ($frame->keepArgs && isset($f['args'])) {
196-
$a[$prefix.'args'] = new EnumStub($f['args'], false);
191+
if ($frame->keepArgs && !empty($f['args'])) {
192+
$a[$prefix.'arguments'] = new ArgsStub($f['args'], $f['function'], $f['class']);
197193
}
198194

199195
return $a;
@@ -209,11 +205,7 @@ private static function filterExceptionArray($xClass, array $a, $xPrefix, $filte
209205
}
210206

211207
if (!($filter & Caster::EXCLUDE_VERBOSE)) {
212-
array_unshift($trace, array(
213-
'function' => $xClass ? 'new '.$xClass : null,
214-
'file' => $a[Caster::PREFIX_PROTECTED.'file'],
215-
'line' => $a[Caster::PREFIX_PROTECTED.'line'],
216-
));
208+
self::traceUnshift($trace, $xClass, $a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line']);
217209
$a[$xPrefix.'trace'] = new TraceStub($trace, self::$traceArgs);
218210
}
219211
if (empty($a[$xPrefix.'previous'])) {
@@ -224,6 +216,18 @@ private static function filterExceptionArray($xClass, array $a, $xPrefix, $filte
224216
return $a;
225217
}
226218

219+
private static function traceUnshift(&$trace, $class, $file, $line)
220+
{
221+
if (isset($trace[0]['file'], $trace[0]['line']) && $trace[0]['file'] === $file && $trace[0]['line'] === $line) {
222+
return;
223+
}
224+
array_unshift($trace, array(
225+
'function' => $class ? 'new '.$class : null,
226+
'file' => $file,
227+
'line' => $line,
228+
));
229+
}
230+
227231
private static function extractSource(array $srcArray, $line, $srcContext, $title, $lang, $file = null)
228232
{
229233
$src = array();

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ protected function tearDown()
3333

3434
public function testDefaultSettings()
3535
{
36-
$e = $this->getTestException(1);
36+
$e = $this->getTestException($this);
3737

3838
$expectedDump = <<<'EODUMP'
3939
Exception {
@@ -49,10 +49,10 @@ public function testDefaultSettings()
4949
}
5050
%sExceptionCasterTest.php:%d: {
5151
: {
52-
: $e = $this->getTestException(1);
52+
: $e = $this->getTestException($this);
5353
:
54-
args: {
55-
1
54+
arguments: {
55+
Symfony\Component\VarDumper\Tests\Caster\ExceptionCasterTest {#1 …}
5656
}
5757
}
5858
%A
@@ -76,7 +76,7 @@ public function testSeek()
7676
: {
7777
: $e = $this->getTestException(2);
7878
:
79-
args: {
79+
arguments: {
8080
2
8181
}
8282
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\VarDumper\Tests\Caster;
13+
14+
use Symfony\Component\VarDumper\Caster\ArgsStub;
15+
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
16+
17+
class StubCasterTest extends \PHPUnit_Framework_TestCase
18+
{
19+
use VarDumperTestTrait;
20+
21+
public function testArgsStubWithDefaults($foo = 234, $bar = 456)
22+
{
23+
$args = array(new ArgsStub(array(123), __FUNCTION__, __CLASS__));
24+
25+
$expectedDump = <<<'EODUMP'
26+
array:1 [
27+
0 => {
28+
$foo: 123
29+
}
30+
]
31+
EODUMP;
32+
33+
$this->assertDumpMatchesFormat($expectedDump, $args);
34+
}
35+
36+
public function testArgsStubWithExtraArgs($foo = 234)
37+
{
38+
$args = array(new ArgsStub(array(123, 456), __FUNCTION__, __CLASS__));
39+
40+
$expectedDump = <<<'EODUMP'
41+
array:1 [
42+
0 => {
43+
$foo: 123
44+
...: {
45+
456
46+
}
47+
}
48+
]
49+
EODUMP;
50+
51+
$this->assertDumpMatchesFormat($expectedDump, $args);
52+
}
53+
54+
public function testArgsStubNoParamWithExtraArgs()
55+
{
56+
$args = array(new ArgsStub(array(123), __FUNCTION__, __CLASS__));
57+
58+
$expectedDump = <<<'EODUMP'
59+
array:1 [
60+
0 => {
61+
123
62+
}
63+
]
64+
EODUMP;
65+
66+
$this->assertDumpMatchesFormat($expectedDump, $args);
67+
}
68+
69+
public function testArgsStubWithClosure()
70+
{
71+
$args = array(new ArgsStub(array(123), '{closure}', null));
72+
73+
$expectedDump = <<<'EODUMP'
74+
array:1 [
75+
0 => {
76+
123
77+
}
78+
]
79+
EODUMP;
80+
81+
$this->assertDumpMatchesFormat($expectedDump, $args);
82+
}
83+
}

0 commit comments

Comments
 (0)