[VarDumper] fix dump of closures created from callables
This commit is contained in:
parent
5d1120593c
commit
1c1818b876
@ -368,6 +368,20 @@ class JsonDescriptor extends Descriptor
|
||||
if ($callable instanceof \Closure) {
|
||||
$data['type'] = 'closure';
|
||||
|
||||
$r = new \ReflectionFunction($callable);
|
||||
if (false !== strpos($r->name, '{closure}')) {
|
||||
return $data;
|
||||
}
|
||||
$data['name'] = $r->name;
|
||||
|
||||
$class = ($class = $r->getClosureThis()) ? \get_class($class) : null;
|
||||
if ($scopeClass = $r->getClosureScopeClass() ?: $class) {
|
||||
$data['class'] = $scopeClass;
|
||||
if (!$class) {
|
||||
$data['static'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
@ -354,6 +354,20 @@ class MarkdownDescriptor extends Descriptor
|
||||
if ($callable instanceof \Closure) {
|
||||
$string .= "\n- Type: `closure`";
|
||||
|
||||
$r = new \ReflectionFunction($callable);
|
||||
if (false !== strpos($r->name, '{closure}')) {
|
||||
return $this->write($string."\n");
|
||||
}
|
||||
$string .= "\n".sprintf('- Name: `%s`', $r->name);
|
||||
|
||||
$class = ($class = $r->getClosureThis()) ? \get_class($class) : null;
|
||||
if ($scopeClass = $r->getClosureScopeClass() ?: $class) {
|
||||
$string .= "\n".sprintf('- Class: `%s`', $class);
|
||||
if (!$class) {
|
||||
$string .= "\n- Static: yes";
|
||||
}
|
||||
}
|
||||
|
||||
return $this->write($string."\n");
|
||||
}
|
||||
|
||||
|
@ -56,12 +56,7 @@ class TextDescriptor extends Descriptor
|
||||
|
||||
if ($showControllers) {
|
||||
$controller = $route->getDefault('_controller');
|
||||
if ($controller instanceof \Closure) {
|
||||
$controller = 'Closure';
|
||||
} elseif (\is_object($controller)) {
|
||||
$controller = \get_class($controller);
|
||||
}
|
||||
$row[] = $controller;
|
||||
$row[] = $this->formatCallable($controller);
|
||||
}
|
||||
|
||||
$tableRows[] = $row;
|
||||
@ -474,7 +469,18 @@ class TextDescriptor extends Descriptor
|
||||
}
|
||||
|
||||
if ($callable instanceof \Closure) {
|
||||
return '\Closure()';
|
||||
$r = new \ReflectionFunction($callable);
|
||||
if (false !== strpos($r->name, '{closure}')) {
|
||||
return 'Closure()';
|
||||
}
|
||||
if ($class = $r->getClosureScopeClass()) {
|
||||
return sprintf('%s::%s()', $class, $r->name);
|
||||
}
|
||||
if ($class = $r->getClosureThis()) {
|
||||
return sprintf('%s::%s()', \get_class($class), $r->name);
|
||||
}
|
||||
|
||||
return $r->name.'()';
|
||||
}
|
||||
|
||||
if (method_exists($callable, '__invoke')) {
|
||||
|
@ -580,6 +580,20 @@ class XmlDescriptor extends Descriptor
|
||||
if ($callable instanceof \Closure) {
|
||||
$callableXML->setAttribute('type', 'closure');
|
||||
|
||||
$r = new \ReflectionFunction($callable);
|
||||
if (false !== strpos($r->name, '{closure}')) {
|
||||
return $dom;
|
||||
}
|
||||
$callableXML->setAttribute('name', $r->name);
|
||||
|
||||
$class = ($class = $r->getClosureThis()) ? \get_class($class) : null;
|
||||
if ($scopeClass = $r->getClosureScopeClass() ?: $class) {
|
||||
$callableXML->setAttribute('class', $class);
|
||||
if (!$class) {
|
||||
$callableXML->setAttribute('static', 'true');
|
||||
}
|
||||
}
|
||||
|
||||
return $dom;
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
\Closure()
|
||||
Closure()
|
||||
|
@ -6,6 +6,6 @@
|
||||
[32m Order [39m [32m Callable [39m [32m Priority [39m
|
||||
------- ------------------- ----------
|
||||
#1 global_function() 255
|
||||
#2 \Closure() -1
|
||||
#2 Closure() -1
|
||||
------- ------------------- ----------
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
[32m Order [39m [32m Callable [39m [32m Priority [39m
|
||||
------- ------------------- ----------
|
||||
#1 global_function() 255
|
||||
#2 \Closure() -1
|
||||
#2 Closure() -1
|
||||
------- ------------------- ----------
|
||||
|
||||
[33m"event2" event[39m
|
||||
|
@ -34,7 +34,6 @@ class WrappedListener
|
||||
public function __construct($listener, $name, Stopwatch $stopwatch, EventDispatcherInterface $dispatcher = null)
|
||||
{
|
||||
$this->listener = $listener;
|
||||
$this->name = $name;
|
||||
$this->stopwatch = $stopwatch;
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->called = false;
|
||||
@ -44,7 +43,17 @@ class WrappedListener
|
||||
$this->name = \is_object($listener[0]) ? \get_class($listener[0]) : $listener[0];
|
||||
$this->pretty = $this->name.'::'.$listener[1];
|
||||
} elseif ($listener instanceof \Closure) {
|
||||
$r = new \ReflectionFunction($listener);
|
||||
if (false !== strpos($r->name, '{closure}')) {
|
||||
$this->pretty = $this->name = 'closure';
|
||||
} elseif ($this->name = $r->getClosureScopeClass()) {
|
||||
$this->pretty = $this->name.'::'.$r->name;
|
||||
} elseif ($class = $r->getClosureThis()) {
|
||||
$this->name = \get_class($class);
|
||||
$this->pretty = $this->name.'::'.$r->name;
|
||||
} else {
|
||||
$this->pretty = $this->name = $r->name;
|
||||
}
|
||||
} elseif (\is_string($listener)) {
|
||||
$this->pretty = $this->name = $listener;
|
||||
} else {
|
||||
|
@ -380,12 +380,27 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
|
||||
if ($controller instanceof \Closure) {
|
||||
$r = new \ReflectionFunction($controller);
|
||||
|
||||
return array(
|
||||
$controller = array(
|
||||
'class' => $r->getName(),
|
||||
'method' => null,
|
||||
'file' => $r->getFileName(),
|
||||
'line' => $r->getStartLine(),
|
||||
);
|
||||
|
||||
if (false !== strpos($r->name, '{closure}')) {
|
||||
return $controller;
|
||||
}
|
||||
$controller['method'] = $r->name;
|
||||
|
||||
if ($class = $r->getClosureScopeClass()) {
|
||||
$controller['class'] = $class;
|
||||
} elseif ($class = $r->getClosureThis()) {
|
||||
$controller['class'] = \get_class($class);
|
||||
} else {
|
||||
return $r->name;
|
||||
}
|
||||
|
||||
return $controller;
|
||||
}
|
||||
|
||||
if (\is_object($controller)) {
|
||||
|
@ -39,6 +39,17 @@ class ReflectionCaster
|
||||
$stub->class = 'Closure'; // HHVM generates unique class names for closures
|
||||
$a = static::castFunctionAbstract($c, $a, $stub, $isNested, $filter);
|
||||
|
||||
if (false === strpos($c->name, '{closure}')) {
|
||||
if (isset($a[$prefix.'class'])) {
|
||||
$stub->class = $a[$prefix.'class']->value.'::'.$c->name;
|
||||
} elseif (isset($a[$prefix.'this'])) {
|
||||
$stub->class = $a[$prefix.'this']->class.'::'.$c->name;
|
||||
} else {
|
||||
$stub->class = $c->name;
|
||||
}
|
||||
unset($a[$prefix.'class']);
|
||||
}
|
||||
|
||||
if (isset($a[$prefix.'parameters'])) {
|
||||
foreach ($a[$prefix.'parameters']->value as &$v) {
|
||||
$param = $v;
|
||||
|
@ -85,6 +85,34 @@ EOTXT
|
||||
);
|
||||
}
|
||||
|
||||
public function testFromCallableClosureCaster()
|
||||
{
|
||||
if (\defined('HHVM_VERSION_ID')) {
|
||||
$this->markTestSkipped('Not for HHVM.');
|
||||
}
|
||||
$var = array(
|
||||
(new \ReflectionMethod($this, __FUNCTION__))->getClosure($this),
|
||||
(new \ReflectionMethod(__CLASS__, 'tearDownAfterClass'))->getClosure(),
|
||||
);
|
||||
|
||||
$this->assertDumpMatchesFormat(
|
||||
<<<EOTXT
|
||||
array:2 [
|
||||
0 => Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest::testFromCallableClosureCaster {
|
||||
this: Symfony\Component\VarDumper\Tests\Caster\ReflectionCasterTest { …}
|
||||
file: "%sReflectionCasterTest.php"
|
||||
line: "%d to %d"
|
||||
}
|
||||
1 => %sTestCase::tearDownAfterClass {
|
||||
file: "%sTestCase.php"
|
||||
line: "%d to %d"
|
||||
}
|
||||
]
|
||||
EOTXT
|
||||
, $var
|
||||
);
|
||||
}
|
||||
|
||||
public function testClosureCasterExcludingVerbosity()
|
||||
{
|
||||
$var = function () {};
|
||||
|
Reference in New Issue
Block a user