[Fwb][EventDispatcher][HttpKernel] Fix getClosureScopeClass usage to describe callables
authorMaxime Steinhausser <maxime.steinhausser@gmail.com>
Sun, 11 Nov 2018 09:03:27 +0000 (10:03 +0100)
committerNicolas Grekas <nicolas.grekas@gmail.com>
Sun, 11 Nov 2018 11:01:26 +0000 (12:01 +0100)
13 files changed:
src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php
src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php
src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php
src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php
src/Symfony/Bundle/FrameworkBundle/Tests/Console/Descriptor/ObjectsProvider.php
src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.json [new file with mode: 0644]
src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.md [new file with mode: 0644]
src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.txt [new file with mode: 0644]
src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.xml [new file with mode: 0644]
src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php
src/Symfony/Component/EventDispatcher/Tests/Debug/WrappedListenerTest.php [new file with mode: 0644]
src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php
src/Symfony/Component/VarDumper/Caster/ReflectionCaster.php

index a8c2798..05238f3 100644 (file)
@@ -374,10 +374,9 @@ class JsonDescriptor extends Descriptor
             }
             $data['name'] = $r->name;
 
-            $class = ($class = $r->getClosureThis()) ? \get_class($class) : null;
-            if ($scopeClass = $r->getClosureScopeClass() ?: $class) {
-                $data['class'] = $scopeClass;
-                if (!$class) {
+            if ($class = $r->getClosureScopeClass()) {
+                $data['class'] = $class->name;
+                if (!$r->getClosureThis()) {
                     $data['static'] = true;
                 }
             }
index 2e7d072..9249ca5 100644 (file)
@@ -360,10 +360,9 @@ class MarkdownDescriptor extends Descriptor
             }
             $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) {
+            if ($class = $r->getClosureScopeClass()) {
+                $string .= "\n".sprintf('- Class: `%s`', $class->name);
+                if (!$r->getClosureThis()) {
                     $string .= "\n- Static: yes";
                 }
             }
index b381c3a..9846a9a 100644 (file)
@@ -474,10 +474,7 @@ class TextDescriptor extends Descriptor
                 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 sprintf('%s::%s()', $class->name, $r->name);
             }
 
             return $r->name.'()';
index ab74c1f..b663e76 100644 (file)
@@ -586,10 +586,9 @@ class XmlDescriptor extends Descriptor
             }
             $callableXML->setAttribute('name', $r->name);
 
-            $class = ($class = $r->getClosureThis()) ? \get_class($class) : null;
-            if ($scopeClass = $r->getClosureScopeClass() ?: $class) {
-                $callableXML->setAttribute('class', $class);
-                if (!$class) {
+            if ($class = $r->getClosureScopeClass()) {
+                $callableXML->setAttribute('class', $class->name);
+                if (!$r->getClosureThis()) {
                     $callableXML->setAttribute('static', 'true');
                 }
             }
index 3025c6b..b46e322 100644 (file)
@@ -155,7 +155,7 @@ class ObjectsProvider
 
     public static function getCallables()
     {
-        return array(
+        $callables = array(
             'callable_1' => 'array_key_exists',
             'callable_2' => array('Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\CallableClass', 'staticMethod'),
             'callable_3' => array(new CallableClass(), 'method'),
@@ -164,6 +164,12 @@ class ObjectsProvider
             'callable_6' => function () { return 'Closure'; },
             'callable_7' => new CallableClass(),
         );
+
+        if (\PHP_VERSION_ID >= 70100) {
+            $callables['callable_from_callable'] = \Closure::fromCallable(new CallableClass());
+        }
+
+        return $callables;
     }
 }
 
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.json
new file mode 100644 (file)
index 0000000..fc0b749
--- /dev/null
@@ -0,0 +1,5 @@
+{
+    "type": "closure",
+    "name": "__invoke",
+    "class": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\CallableClass"
+}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.md
new file mode 100644 (file)
index 0000000..caf4193
--- /dev/null
@@ -0,0 +1,4 @@
+
+- Type: `closure`
+- Name: `__invoke`
+- Class: `Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\CallableClass`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.txt b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.txt
new file mode 100644 (file)
index 0000000..78ef6a6
--- /dev/null
@@ -0,0 +1 @@
+Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\CallableClass::__invoke()
\ No newline at end of file
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/callable_from_callable.xml
new file mode 100644 (file)
index 0000000..1ad2ee8
--- /dev/null
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<callable type="closure" name="__invoke" class="Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\CallableClass"/>
index 9038ae7..d49f69d 100644 (file)
@@ -46,10 +46,8 @@ class WrappedListener
             $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);
+            } elseif ($class = $r->getClosureScopeClass()) {
+                $this->name = $class->name;
                 $this->pretty = $this->name.'::'.$r->name;
             } else {
                 $this->pretty = $this->name = $r->name;
diff --git a/src/Symfony/Component/EventDispatcher/Tests/Debug/WrappedListenerTest.php b/src/Symfony/Component/EventDispatcher/Tests/Debug/WrappedListenerTest.php
new file mode 100644 (file)
index 0000000..f743f14
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\EventDispatcher\Tests\Debug;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\EventDispatcher\Debug\WrappedListener;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\Stopwatch\Stopwatch;
+
+class WrappedListenerTest extends TestCase
+{
+    /**
+     * @dataProvider provideListenersToDescribe
+     */
+    public function testListenerDescription(callable $listener, $expected)
+    {
+        $wrappedListener = new WrappedListener($listener, null, $this->getMockBuilder(Stopwatch::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock());
+
+        $this->assertStringMatchesFormat($expected, $wrappedListener->getPretty());
+    }
+
+    public function provideListenersToDescribe()
+    {
+        $listeners = array(
+            array(new FooListener(), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::__invoke'),
+            array(array(new FooListener(), 'listen'), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listen'),
+            array(array('Symfony\Component\EventDispatcher\Tests\Debug\FooListener', 'listenStatic'), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listenStatic'),
+            array('var_dump', 'var_dump'),
+            array(function () {}, 'closure'),
+        );
+
+        if (\PHP_VERSION_ID >= 70100) {
+            $listeners[] = array(\Closure::fromCallable(array(new FooListener(), 'listen')), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listen');
+            $listeners[] = array(\Closure::fromCallable(array('Symfony\Component\EventDispatcher\Tests\Debug\FooListener', 'listenStatic')), 'Symfony\Component\EventDispatcher\Tests\Debug\FooListener::listenStatic');
+            $listeners[] = array(\Closure::fromCallable(function () {}), 'closure');
+        }
+
+        return $listeners;
+    }
+}
+
+class FooListener
+{
+    public function listen()
+    {
+    }
+
+    public function __invoke()
+    {
+    }
+
+    public static function listenStatic()
+    {
+    }
+}
index 2501b93..10492e4 100644 (file)
@@ -393,9 +393,7 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
             $controller['method'] = $r->name;
 
             if ($class = $r->getClosureScopeClass()) {
-                $controller['class'] = $class;
-            } elseif ($class = $r->getClosureThis()) {
-                $controller['class'] = \get_class($class);
+                $controller['class'] = $class->name;
             } else {
                 return $r->name;
             }
index a1f0a1a..9bfef06 100644 (file)
@@ -40,13 +40,7 @@ class ReflectionCaster
         $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;
-            }
+            $stub->class = isset($a[$prefix.'class']) ? $a[$prefix.'class']->value.'::'.$c->name : $c->name;
             unset($a[$prefix.'class']);
         }