[VarDumper] display the signature of callables
This commit is contained in:
parent
0e9ded3188
commit
73b4ac78c0
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\VarDumper\Caster;
|
namespace Symfony\Component\VarDumper\Caster;
|
||||||
|
|
||||||
|
use Symfony\Component\VarDumper\Cloner\Stub;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a PHP class identifier.
|
* Represents a PHP class identifier.
|
||||||
*
|
*
|
||||||
@ -58,6 +60,20 @@ class ClassStub extends ConstStub
|
|||||||
$r = new \ReflectionClass($r[0]);
|
$r = new \ReflectionClass($r[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null !== $callable && $r instanceof \ReflectionFunctionAbstract) {
|
||||||
|
$s = ReflectionCaster::castFunctionAbstract($r, array(), new Stub(), true);
|
||||||
|
$s = ReflectionCaster::getSignature($s);
|
||||||
|
|
||||||
|
if ('()' === substr($identifier, -2)) {
|
||||||
|
$this->value = substr_replace($identifier, $s, -2);
|
||||||
|
} else {
|
||||||
|
$this->value .= $s;
|
||||||
|
}
|
||||||
|
if (isset($this->attr['ellipsis'])) {
|
||||||
|
$this->attr['ellipsis'] += \strlen($this->value) - \strlen($identifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (\ReflectionException $e) {
|
} catch (\ReflectionException $e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -75,9 +91,9 @@ class ClassStub extends ConstStub
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!is_array($callable)) {
|
if (!is_array($callable)) {
|
||||||
$callable = new static($callable);
|
$callable = new static($callable, $callable);
|
||||||
} elseif (is_string($callable[0])) {
|
} elseif (is_string($callable[0])) {
|
||||||
$callable[0] = new static($callable[0]);
|
$callable[0] = new static($callable[0], $callable);
|
||||||
} else {
|
} else {
|
||||||
$callable[1] = new static($callable[1], $callable);
|
$callable[1] = new static($callable[1], $callable);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,8 @@ class ReflectionCaster
|
|||||||
|
|
||||||
$a = static::castFunctionAbstract($c, $a, $stub, $isNested, $filter);
|
$a = static::castFunctionAbstract($c, $a, $stub, $isNested, $filter);
|
||||||
|
|
||||||
|
$stub->class .= self::getSignature($a);
|
||||||
|
|
||||||
if (isset($a[$prefix.'parameters'])) {
|
if (isset($a[$prefix.'parameters'])) {
|
||||||
foreach ($a[$prefix.'parameters']->value as &$v) {
|
foreach ($a[$prefix.'parameters']->value as &$v) {
|
||||||
$param = $v;
|
$param = $v;
|
||||||
@ -294,6 +296,52 @@ class ReflectionCaster
|
|||||||
return $a;
|
return $a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getSignature(array $a)
|
||||||
|
{
|
||||||
|
$prefix = Caster::PREFIX_VIRTUAL;
|
||||||
|
$signature = '';
|
||||||
|
|
||||||
|
if (isset($a[$prefix.'parameters'])) {
|
||||||
|
foreach ($a[$prefix.'parameters']->value as $k => $param) {
|
||||||
|
$signature .= ', ';
|
||||||
|
if ($type = $param->getType()) {
|
||||||
|
if (!$param->isOptional() && $param->allowsNull()) {
|
||||||
|
$signature .= '?';
|
||||||
|
}
|
||||||
|
$signature .= substr(strrchr('\\'.$type->getName(), '\\'), 1).' ';
|
||||||
|
}
|
||||||
|
$signature .= $k;
|
||||||
|
|
||||||
|
if (!$param->isDefaultValueAvailable()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$v = $param->getDefaultValue();
|
||||||
|
$signature .= ' = ';
|
||||||
|
|
||||||
|
if ($param->isDefaultValueConstant()) {
|
||||||
|
$signature .= substr(strrchr('\\'.$param->getDefaultValueConstantName(), '\\'), 1);
|
||||||
|
} elseif (null === $v) {
|
||||||
|
$signature .= 'null';
|
||||||
|
} elseif (\is_array($v)) {
|
||||||
|
$signature .= $v ? '[…'.\count($v).']' : '[]';
|
||||||
|
} elseif (\is_string($v)) {
|
||||||
|
$signature .= 10 > \strlen($v) && false === strpos($v, '\\') ? "'{$v}'" : "'…".\strlen($v)."'";
|
||||||
|
} elseif (\is_bool($v)) {
|
||||||
|
$signature .= $v ? 'true' : 'false';
|
||||||
|
} else {
|
||||||
|
$signature .= $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$signature = '('.substr($signature, 2).')';
|
||||||
|
|
||||||
|
if (isset($a[$prefix.'returnType'])) {
|
||||||
|
$signature .= ': '.substr(strrchr('\\'.$a[$prefix.'returnType'], '\\'), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $signature;
|
||||||
|
}
|
||||||
|
|
||||||
private static function addExtra(&$a, \Reflector $c)
|
private static function addExtra(&$a, \Reflector $c)
|
||||||
{
|
{
|
||||||
$x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : array();
|
$x = isset($a[Caster::PREFIX_VIRTUAL.'extra']) ? $a[Caster::PREFIX_VIRTUAL.'extra']->value : array();
|
||||||
|
@ -68,14 +68,14 @@ EOTXT
|
|||||||
$var = function ($x) use ($a, &$b) {};
|
$var = function ($x) use ($a, &$b) {};
|
||||||
|
|
||||||
$this->assertDumpMatchesFormat(
|
$this->assertDumpMatchesFormat(
|
||||||
<<<EOTXT
|
<<<'EOTXT'
|
||||||
Closure {
|
Closure($x) {
|
||||||
%Aparameters: {
|
%Aparameters: {
|
||||||
\$x: {}
|
$x: {}
|
||||||
}
|
}
|
||||||
use: {
|
use: {
|
||||||
\$a: 123
|
$a: 123
|
||||||
\$b: & 123
|
$b: & 123
|
||||||
}
|
}
|
||||||
file: "%sReflectionCasterTest.php"
|
file: "%sReflectionCasterTest.php"
|
||||||
line: "68 to 68"
|
line: "68 to 68"
|
||||||
@ -90,7 +90,7 @@ EOTXT
|
|||||||
$var = function () {};
|
$var = function () {};
|
||||||
|
|
||||||
$expectedDump = <<<EOTXT
|
$expectedDump = <<<EOTXT
|
||||||
Closure {
|
Closure() {
|
||||||
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
|
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
|
||||||
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
|
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
|
||||||
}
|
}
|
||||||
@ -140,7 +140,7 @@ EOTXT
|
|||||||
|
|
||||||
$this->assertDumpMatchesFormat(
|
$this->assertDumpMatchesFormat(
|
||||||
<<<EOTXT
|
<<<EOTXT
|
||||||
Closure {
|
Closure(): int {
|
||||||
returnType: "int"
|
returnType: "int"
|
||||||
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
|
class: "Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest"
|
||||||
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
|
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
|
||||||
|
@ -141,7 +141,7 @@ EODUMP;
|
|||||||
|
|
||||||
$expectedDump = <<<'EODUMP'
|
$expectedDump = <<<'EODUMP'
|
||||||
<foo></foo><bar><span class=sf-dump-note>array:1</span> [<samp>
|
<foo></foo><bar><span class=sf-dump-note>array:1</span> [<samp>
|
||||||
<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>"
|
<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>"
|
||||||
</samp>]
|
</samp>]
|
||||||
</bar>
|
</bar>
|
||||||
EODUMP;
|
EODUMP;
|
||||||
|
@ -75,7 +75,7 @@ array:24 [
|
|||||||
+foo: "foo"
|
+foo: "foo"
|
||||||
+"bar": "bar"
|
+"bar": "bar"
|
||||||
}
|
}
|
||||||
"closure" => Closure {#%d
|
"closure" => Closure(\$a, PDO &\$b = null) {#%d
|
||||||
class: "Symfony\Component\VarDumper\Tests\Dumper\CliDumperTest"
|
class: "Symfony\Component\VarDumper\Tests\Dumper\CliDumperTest"
|
||||||
this: Symfony\Component\VarDumper\Tests\Dumper\CliDumperTest {#%d …}
|
this: Symfony\Component\VarDumper\Tests\Dumper\CliDumperTest {#%d …}
|
||||||
parameters: {
|
parameters: {
|
||||||
|
@ -78,7 +78,7 @@ class HtmlDumperTest extends TestCase
|
|||||||
+<span class=sf-dump-public title="Public property">foo</span>: "<span class=sf-dump-str title="3 characters">foo</span>"
|
+<span class=sf-dump-public title="Public property">foo</span>: "<span class=sf-dump-str title="3 characters">foo</span>"
|
||||||
+"<span class=sf-dump-public title="Runtime added dynamic property">bar</span>": "<span class=sf-dump-str title="3 characters">bar</span>"
|
+"<span class=sf-dump-public title="Runtime added dynamic property">bar</span>": "<span class=sf-dump-str title="3 characters">bar</span>"
|
||||||
</samp>}
|
</samp>}
|
||||||
"<span class=sf-dump-key>closure</span>" => <span class=sf-dump-note>Closure</span> {<a class=sf-dump-ref>#%d</a><samp>
|
"<span class=sf-dump-key>closure</span>" => <span class=sf-dump-note>Closure(\$a, PDO &\$b = null)</span> {<a class=sf-dump-ref>#%d</a><samp>
|
||||||
<span class=sf-dump-meta>class</span>: "<span class=sf-dump-str title="Symfony\Component\VarDumper\Tests\Dumper\HtmlDumperTest
|
<span class=sf-dump-meta>class</span>: "<span class=sf-dump-str title="Symfony\Component\VarDumper\Tests\Dumper\HtmlDumperTest
|
||||||
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>"
|
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>"
|
||||||
<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;}
|
<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;}
|
||||||
|
@ -7,5 +7,5 @@ interface FooInterface
|
|||||||
/**
|
/**
|
||||||
* Hello.
|
* Hello.
|
||||||
*/
|
*/
|
||||||
public function foo();
|
public function foo(?\stdClass $a, \stdClass $b = null);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user