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

Skip to content

Commit 5440d67

Browse files
feature #31446 [VarDumper] Output the location of calls to dump() (ktherage)
This PR was merged into the 4.4 branch. Discussion ---------- [VarDumper] Output the location of calls to dump() | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | not tested yet | Fixed tickets | #30830 | License | MIT | Doc PR | see #30830 Commits ------- f0a59d3 [VarDumper] Output the location of calls to dump()
2 parents 55843f2 + f0a59d3 commit 5440d67

File tree

7 files changed

+160
-4
lines changed

7 files changed

+160
-4
lines changed

src/Symfony/Bundle/DebugBundle/Resources/config/services.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@
4040
<argument>0</argument> <!-- flags -->
4141
</service>
4242

43+
<service id="var_dumper.contextualized_cli_dumper" class="Symfony\Component\VarDumper\Dumper\ContextualizedDumper" decorates="var_dumper.cli_dumper">
44+
<argument type="service" id="var_dumper.contextualized_cli_dumper.inner" />
45+
<argument type="collection">
46+
<argument type="service" key="source">
47+
<service class="Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider">
48+
<argument>%kernel.charset%</argument>
49+
<argument type="string">%kernel.project_dir%</argument>
50+
<argument type="service" id="debug.file_link_formatter" on-invalid="null" />
51+
</service>
52+
</argument>
53+
</argument>
54+
</service>
55+
4356
<service id="var_dumper.html_dumper" class="Symfony\Component\VarDumper\Dumper\HtmlDumper">
4457
<argument>null</argument>
4558
<argument>%kernel.charset%</argument>

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

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\VarDumper\Cloner;
1313

1414
use Symfony\Component\VarDumper\Caster\Caster;
15+
use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
1516

1617
/**
1718
* @author Nicolas Grekas <[email protected]>
@@ -24,6 +25,7 @@ class Data implements \ArrayAccess, \Countable, \IteratorAggregate
2425
private $maxDepth = 20;
2526
private $maxItemsPerDepth = -1;
2627
private $useRefHandles = -1;
28+
private $context = [];
2729

2830
/**
2931
* @param array $data An array as returned by ClonerInterface::cloneVar()
@@ -227,6 +229,17 @@ public function withRefHandles($useRefHandles)
227229
return $data;
228230
}
229231

232+
/**
233+
* @return static
234+
*/
235+
public function withContext(array $context)
236+
{
237+
$data = clone $this;
238+
$data->context = $context;
239+
240+
return $data;
241+
}
242+
230243
/**
231244
* Seeks to a specific key in nested data structures.
232245
*
@@ -281,7 +294,18 @@ public function seek($key)
281294
public function dump(DumperInterface $dumper)
282295
{
283296
$refs = [0];
284-
$this->dumpItem($dumper, new Cursor(), $refs, $this->data[$this->position][$this->key]);
297+
$cursor = new Cursor();
298+
299+
if ($cursor->attr = $this->context[SourceContextProvider::class] ?? []) {
300+
$cursor->attr['if_links'] = true;
301+
$cursor->hashType = -1;
302+
$dumper->dumpScalar($cursor, 'default', '^');
303+
$cursor->attr = ['if_links' => true];
304+
$dumper->dumpScalar($cursor, 'default', ' ');
305+
$cursor->hashType = 0;
306+
}
307+
308+
$this->dumpItem($dumper, $cursor, $refs, $this->data[$this->position][$this->key]);
285309
}
286310

287311
/**

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public function __construct($output = null, string $charset = null, int $flags =
8383
]);
8484
}
8585

86-
$this->displayOptions['fileLinkFormat'] = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f';
86+
$this->displayOptions['fileLinkFormat'] = ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f#L%l';
8787
}
8888

8989
/**
@@ -490,6 +490,8 @@ protected function style($style, $value, $attr = [])
490490
if (isset($attr['href'])) {
491491
$value = "\033]8;;{$attr['href']}\033\\{$value}\033]8;;\033\\";
492492
}
493+
} elseif ($attr['if_links'] ?? false) {
494+
return '';
493495
}
494496

495497
return $value;
@@ -548,6 +550,10 @@ protected function dumpLine($depth, $endOfValue = false)
548550

549551
protected function endValue(Cursor $cursor)
550552
{
553+
if (-1 === $cursor->hashType) {
554+
return;
555+
}
556+
551557
if (Stub::ARRAY_INDEXED === $cursor->hashType || Stub::ARRAY_ASSOC === $cursor->hashType) {
552558
if (self::DUMP_TRAILING_COMMA & $this->flags && 0 < $cursor->depth) {
553559
$this->line .= ',';
@@ -628,7 +634,7 @@ private function isWindowsTrueColor(): bool
628634
private function getSourceLink(string $file, int $line)
629635
{
630636
if ($fmt = $this->displayOptions['fileLinkFormat']) {
631-
return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : ($fmt->format($file, $line) ?: 'file://'.$file);
637+
return \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : ($fmt->format($file, $line) ?: 'file://'.$file.'#L'.$line);
632638
}
633639

634640
return false;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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\Dumper;
13+
14+
use Symfony\Component\VarDumper\Cloner\Data;
15+
use Symfony\Component\VarDumper\Dumper\ContextProvider\ContextProviderInterface;
16+
17+
/**
18+
* @author Kévin Thérage <[email protected]>
19+
*/
20+
class ContextualizedDumper implements DataDumperInterface
21+
{
22+
private $wrappedDumper;
23+
private $contextProviders;
24+
25+
/**
26+
* @param ContextProviderInterface[] $contextProviders
27+
*/
28+
public function __construct(DataDumperInterface $wrappedDumper, array $contextProviders)
29+
{
30+
$this->wrappedDumper = $wrappedDumper;
31+
$this->contextProviders = $contextProviders;
32+
}
33+
34+
public function dump(Data $data)
35+
{
36+
$context = [];
37+
foreach ($this->contextProviders as $contextProvider) {
38+
$context[\get_class($contextProvider)] = $contextProvider->getContext();
39+
}
40+
41+
$this->wrappedDumper->dump($data->withContext($context));
42+
}
43+
}

src/Symfony/Component/VarDumper/Tests/Cloner/VarClonerTest.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public function testMaxIntBoundary()
5353
[maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
5454
[maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
5555
[useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
56+
[context:Symfony\Component\VarDumper\Cloner\Data:private] => Array
57+
(
58+
)
59+
5660
)
5761
5862
EOTXT;
@@ -141,6 +145,10 @@ public function testClone()
141145
[maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
142146
[maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
143147
[useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
148+
[context:Symfony\Component\VarDumper\Cloner\Data:private] => Array
149+
(
150+
)
151+
144152
)
145153
146154
EOTXT;
@@ -309,6 +317,10 @@ public function testLimits()
309317
[maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
310318
[maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
311319
[useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
320+
[context:Symfony\Component\VarDumper\Cloner\Data:private] => Array
321+
(
322+
)
323+
312324
)
313325
314326
EOTXT;
@@ -327,7 +339,7 @@ public function testJsonCast()
327339
$clone = $cloner->cloneVar($data);
328340

329341
$expected = <<<'EOTXT'
330-
object(Symfony\Component\VarDumper\Cloner\Data)#%i (6) {
342+
object(Symfony\Component\VarDumper\Cloner\Data)#%d (7) {
331343
["data":"Symfony\Component\VarDumper\Cloner\Data":private]=>
332344
array(2) {
333345
[0]=>
@@ -372,6 +384,9 @@ public function testJsonCast()
372384
int(-1)
373385
["useRefHandles":"Symfony\Component\VarDumper\Cloner\Data":private]=>
374386
int(-1)
387+
["context":"Symfony\Component\VarDumper\Cloner\Data":private]=>
388+
array(0) {
389+
}
375390
}
376391

377392
EOTXT;
@@ -432,6 +447,10 @@ public function testCaster()
432447
[maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
433448
[maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
434449
[useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
450+
[context:Symfony\Component\VarDumper\Cloner\Data:private] => Array
451+
(
452+
)
453+
435454
)
436455
437456
EOTXT;
@@ -501,6 +520,10 @@ public function testPhp74()
501520
[maxDepth:Symfony\Component\VarDumper\Cloner\Data:private] => 20
502521
[maxItemsPerDepth:Symfony\Component\VarDumper\Cloner\Data:private] => -1
503522
[useRefHandles:Symfony\Component\VarDumper\Cloner\Data:private] => -1
523+
[context:Symfony\Component\VarDumper\Cloner\Data:private] => Array
524+
(
525+
)
526+
504527
)
505528

506529
EOTXT;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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\Dumper;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\VarDumper\Cloner\VarCloner;
16+
use Symfony\Component\VarDumper\Dumper\CliDumper;
17+
use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
18+
use Symfony\Component\VarDumper\Dumper\ContextualizedDumper;
19+
20+
/**
21+
* @author Kévin Thérage <[email protected]>
22+
*/
23+
class ContextualizedDumperTest extends TestCase
24+
{
25+
public function testContextualizedCliDumper()
26+
{
27+
$wrappedDumper = new CliDumper('php://output');
28+
$wrappedDumper->setColors(true);
29+
30+
$var = 'example';
31+
$href = sprintf('file://%s#L%s', __FILE__, 37);
32+
$dumper = new ContextualizedDumper($wrappedDumper, [new SourceContextProvider()]);
33+
$cloner = new VarCloner();
34+
$data = $cloner->cloneVar($var);
35+
36+
ob_start();
37+
$dumper->dump($data);
38+
$out = ob_get_clean();
39+
40+
$this->assertStringContainsString("\e]8;;{$href}\e\\\e[", $out);
41+
$this->assertStringContainsString("m{$var}\e[", $out);
42+
}
43+
}

src/Symfony/Component/VarDumper/VarDumper.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
use Symfony\Component\VarDumper\Caster\ReflectionCaster;
1515
use Symfony\Component\VarDumper\Cloner\VarCloner;
1616
use Symfony\Component\VarDumper\Dumper\CliDumper;
17+
use Symfony\Component\VarDumper\Dumper\ContextProvider\SourceContextProvider;
18+
use Symfony\Component\VarDumper\Dumper\ContextualizedDumper;
1719
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
1820

1921
// Load the global dump() function
@@ -38,6 +40,8 @@ public static function dump($var)
3840
$dumper = \in_array(\PHP_SAPI, ['cli', 'phpdbg']) ? new CliDumper() : new HtmlDumper();
3941
}
4042

43+
$dumper = new ContextualizedDumper($dumper, [new SourceContextProvider()]);
44+
4145
self::$handler = function ($var) use ($cloner, $dumper) {
4246
$dumper->dump($cloner->cloneVar($var));
4347
};

0 commit comments

Comments
 (0)