Skip to content

Commit c52b2e9

Browse files
committed
feature symfony#27768 [VarDumper] display the signature of callables (nicolas-grekas)
This PR was merged into the 4.2-dev branch. Discussion ---------- [VarDumper] display the signature of callables | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | bobthecow/psysh#218 | License | MIT | Doc PR | - E.g. ![capture d ecran de 2018-06-29 12-08-13](https://user-images.githubusercontent.com/243674/42087047-4fdc70d6-7b95-11e8-972c-216651bf7d69.png) or ![image](https://user-images.githubusercontent.com/243674/42086967-070bc960-7b95-11e8-9470-7e88f8acf12a.png) Commits ------- 73b4ac7 [VarDumper] display the signature of callables
2 parents 9bb990f + 73b4ac7 commit c52b2e9

File tree

7 files changed

+77
-13
lines changed

7 files changed

+77
-13
lines changed

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\VarDumper\Caster;
1313

14+
use Symfony\Component\VarDumper\Cloner\Stub;
15+
1416
/**
1517
* Represents a PHP class identifier.
1618
*
@@ -58,6 +60,20 @@ public function __construct(string $identifier, $callable = null)
5860
$r = new \ReflectionClass($r[0]);
5961
}
6062
}
63+
64+
if (null !== $callable && $r instanceof \ReflectionFunctionAbstract) {
65+
$s = ReflectionCaster::castFunctionAbstract($r, array(), new Stub(), true);
66+
$s = ReflectionCaster::getSignature($s);
67+
68+
if ('()' === substr($identifier, -2)) {
69+
$this->value = substr_replace($identifier, $s, -2);
70+
} else {
71+
$this->value .= $s;
72+
}
73+
if (isset($this->attr['ellipsis'])) {
74+
$this->attr['ellipsis'] += \strlen($this->value) - \strlen($identifier);
75+
}
76+
}
6177
} catch (\ReflectionException $e) {
6278
return;
6379
}
@@ -75,9 +91,9 @@ public static function wrapCallable($callable)
7591
}
7692

7793
if (!is_array($callable)) {
78-
$callable = new static($callable);
94+
$callable = new static($callable, $callable);
7995
} elseif (is_string($callable[0])) {
80-
$callable[0] = new static($callable[0]);
96+
$callable[0] = new static($callable[0], $callable);
8197
} else {
8298
$callable[1] = new static($callable[1], $callable);
8399
}

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public static function castClosure(\Closure $c, array $a, Stub $stub, $isNested,
3838

3939
$a = static::castFunctionAbstract($c, $a, $stub, $isNested, $filter);
4040

41+
$stub->class .= self::getSignature($a);
42+
4143
if (isset($a[$prefix.'parameters'])) {
4244
foreach ($a[$prefix.'parameters']->value as &$v) {
4345
$param = $v;
@@ -294,6 +296,52 @@ public static function castZendExtension(\ReflectionZendExtension $c, array $a,
294296
return $a;
295297
}
296298

299+
public static function getSignature(array $a)
300+
{
301+
$prefix = Caster::PREFIX_VIRTUAL;
302+
$signature = '';
303+
304+
if (isset($a[$prefix.'parameters'])) {
305+
foreach ($a[$prefix.'parameters']->value as $k => $param) {
306+
$signature .= ', ';
307+
if ($type = $param->getType()) {
308+
if (!$param->isOptional() && $param->allowsNull()) {
309+
$signature .= '?';
310+
}
311+
$signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' ';
312+
}
313+
$signature .= $k;
314+
315+
if (!$param->isDefaultValueAvailable()) {
316+
continue;
317+
}
318+
$v = $param->getDefaultValue();
319+
$signature .= ' = ';
320+
321+
if ($param->isDefaultValueConstant()) {
322+
$signature .= substr(strrchr('\\'.$param->getDefaultValueConstantName(), '\\'), 1);
323+
} elseif (null === $v) {
324+
$signature .= 'null';
325+
} elseif (\is_array($v)) {
326+
$signature .= $v ? '[…'.\count($v).']' : '[]';
327+
} elseif (\is_string($v)) {
328+
$signature .= 10 > \strlen($v) && false === strpos($v, '\\') ? "'{$v}'" : "'…".\strlen($v)."'";
329+
} elseif (\is_bool($v)) {
330+
$signature .= $v ? 'true' : 'false';
331+
} else {
332+
$signature .= $v;
333+
}
334+
}
335+
}
336+
$signature = '('.substr($signature, 2).')';
337+
338+
if (isset($a[$prefix.'returnType'])) {
339+
$signature .= ': '.substr(strrchr('\\'.$a[$prefix.'returnType'], '\\'), 1);
340+
}
341+
342+
return $signature;
343+
}
344+
297345
private static function addExtra(&$a, \Reflector $c)
298346
{
299347
$x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : array();

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,14 @@ public function testClosureCaster()
6868
$var = function ($x) use ($a, &$b) {};
6969

7070
$this->assertDumpMatchesFormat(
71-
<<<EOTXT
72-
Closure {
71+
<<<'EOTXT'
72+
Closure($x) {
7373
%Aparameters: {
74-
\$x: {}
74+
$x: {}
7575
}
7676
use: {
77-
\$a: 123
78-
\$b: & 123
77+
$a: 123
78+
$b: & 123
7979
}
8080
file: "%sReflectionCasterTest.php"
8181
line: "68 to 68"
@@ -90,7 +90,7 @@ public function testClosureCasterExcludingVerbosity()
9090
$var = function () {};
9191

9292
$expectedDump = <<<EOTXT
93-
Closure {
93+
Closure() {
9494
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
9595
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
9696
}
@@ -140,7 +140,7 @@ public function testReturnType()
140140

141141
$this->assertDumpMatchesFormat(
142142
<<<EOTXT
143-
Closure {
143+
Closure(): int {
144144
returnType: "int"
145145
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
146146
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public function testClassStub()
141141

142142
$expectedDump = <<<'EODUMP'
143143
<foo></foo><bar><span class=sf-dump-note>array:1</span> [<samp>
144-
<span class=sf-dump-index>0</span> => "<a href="%sFooInterface.php:10" rel="noopener noreferrer"><span class=sf-dump-str title="5 characters">hello</span></a>"
144+
<span class=sf-dump-index>0</span> => "<a href="%sFooInterface.php:10" rel="noopener noreferrer"><span class=sf-dump-str title="39 characters">hello(?stdClass $a, stdClass $b = null)</span></a>"
145145
</samp>]
146146
</bar>
147147
EODUMP;

src/Symfony/Component/VarDumper/Tests/Dumper/CliDumperTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public function testGet()
7575
+foo: "foo"
7676
+"bar": "bar"
7777
}
78-
"closure" => Closure {#%d
78+
"closure" => Closure(\$a, PDO &\$b = null) {#%d
7979
class: "Symfony\Component\VarDumper\Tests\Dumper\CliDumperTest"
8080
this: Symfony\Component\VarDumper\Tests\Dumper\CliDumperTest {#%d …}
8181
parameters: {

src/Symfony/Component/VarDumper/Tests/Dumper/HtmlDumperTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public function testGet()
7878
+<span class=sf-dump-public title="Public property">foo</span>: "<span class=sf-dump-str title="3 characters">foo</span>"
7979
+"<span class=sf-dump-public title="Runtime added dynamic property">bar</span>": "<span class=sf-dump-str title="3 characters">bar</span>"
8080
</samp>}
81-
"<span class=sf-dump-key>closure</span>" => <span class=sf-dump-note>Closure</span> {<a class=sf-dump-ref>#%d</a><samp>
81+
"<span class=sf-dump-key>closure</span>" => <span class=sf-dump-note>Closure(\$a, PDO &amp;\$b = null)</span> {<a class=sf-dump-ref>#%d</a><samp>
8282
<span class=sf-dump-meta>class</span>: "<span class=sf-dump-str title="Symfony\Component\VarDumper\Tests\Dumper\HtmlDumperTest
8383
55 characters"><span class="sf-dump-ellipsis sf-dump-ellipsis-class">Symfony\Component\VarDumper\Tests\Dumper</span><span class=sf-dump-ellipsis>\</span>HtmlDumperTest</span>"
8484
<span class=sf-dump-meta>this</span>: <abbr title="Symfony\Component\VarDumper\Tests\Dumper\HtmlDumperTest" class=sf-dump-note>HtmlDumperTest</abbr> {<a class=sf-dump-ref>#%d</a> &%s;}

src/Symfony/Component/VarDumper/Tests/Fixtures/FooInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ interface FooInterface
77
/**
88
* Hello.
99
*/
10-
public function foo();
10+
public function foo(?\stdClass $a, \stdClass $b = null);
1111
}

0 commit comments

Comments
 (0)