From b98bbb37a1cd1b479722b5cf793a4b0fcd5b77cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Tue, 6 Aug 2019 16:55:08 +0200 Subject: [PATCH] Provide a polyfill for proxy-manager --- composer.json | 3 +- .../LazyProxy/PhpDumper/ProxyDumper.php | 4 ++ .../Legacy/ProxiedMethodReturnExpression.php | 69 +++++++++++++++++++ .../LazyProxy/PhpDumper/ProxyDumperTest.php | 10 +++ src/Symfony/Bridge/ProxyManager/composer.json | 2 +- 5 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 src/Symfony/Bridge/ProxyManager/Legacy/ProxiedMethodReturnExpression.php diff --git a/composer.json b/composer.json index 919941f984d6b..fe465e81e155e 100644 --- a/composer.json +++ b/composer.json @@ -123,7 +123,8 @@ "Symfony\\Component\\": "src/Symfony/Component/" }, "classmap": [ - "src/Symfony/Component/Intl/Resources/stubs" + "src/Symfony/Component/Intl/Resources/stubs", + "src/Symfony/Bridge/ProxyManager/Legacy/ProxiedMethodReturnExpression.php" ], "exclude-from-classmap": [ "**/Tests/" diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php index 7acc1c65420b7..844787f96832a 100644 --- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php +++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php @@ -112,6 +112,10 @@ public function getProxyCode(Definition $definition) ); } + if (version_compare(self::getProxyManagerVersion(), '2.5', '<')) { + $code = str_replace('\Closure::bind(function ', '\Closure::bind(static function ', $code); + } + return $code; } diff --git a/src/Symfony/Bridge/ProxyManager/Legacy/ProxiedMethodReturnExpression.php b/src/Symfony/Bridge/ProxyManager/Legacy/ProxiedMethodReturnExpression.php new file mode 100644 index 0000000000000..793897429f677 --- /dev/null +++ b/src/Symfony/Bridge/ProxyManager/Legacy/ProxiedMethodReturnExpression.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace ProxyManager\Generator\Util; + +use Composer\Autoload\ClassLoader; +use ReflectionMethod; +use Symfony\Component\Debug\DebugClassLoader; + +if (class_exists(\ProxyManager\Version::class) && \version_compare(\ProxyManager\Version::getVersion(), '2.5', '<')) { + /** + * Utility class to generate return expressions in method, given a method signature. + * + * This is required since return expressions may be forbidden by the method signature (void). + * + * @author Marco Pivetta + * @license MIT + */ + final class ProxiedMethodReturnExpression + { + public static function generate(string $returnedValueExpression, ?ReflectionMethod $originalMethod) : string + { + $originalReturnType = $originalMethod === null + ? null + : $originalMethod->getReturnType(); + $originalReturnTypeName = $originalReturnType === null + ? null + : $originalReturnType->getName(); + if ($originalReturnTypeName === 'void') { + return $returnedValueExpression . ";\nreturn;"; + } + return 'return ' . $returnedValueExpression . ';'; + } + } +} else { + // Fallback to the original class by unregistering this file from composer class loader + $getComposerClassLoader = static function($functionLoader) use (&$getComposerClassLoader) { + if (\is_array($functionLoader)) { + $functionLoader = $functionLoader[0]; + } + if (!\is_object($functionLoader)) { + return; + } + if ($functionLoader instanceof ClassLoader) { + return $functionLoader; + } + if ($functionLoader instanceof DebugClassLoader) { + return $getComposerClassLoader($functionLoader->getClassLoader()); + } + }; + + $classLoader = null; + while($classLoader === null && count($functions = spl_autoload_functions()) > 0) { + $classLoader = $getComposerClassLoader(\array_shift($functions)); + } + + if (null === $classLoader) { + throw new \RuntimeException('Unable to find a class loader for "%s"'); + } + + $classLoader->addClassMap([ProxiedMethodReturnExpression::class => null]); + $classLoader->loadClass(ProxiedMethodReturnExpression::class); +} diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php index 5328c9ae1227d..5f38ba99d9c2f 100644 --- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php +++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php @@ -63,6 +63,16 @@ public function testGetProxyCode() ); } + public function testGetProxyMagicCode() + { + $definition = new Definition(__CLASS__); + $definition->setLazy(true); + + $code = $this->dumper->getProxyCode($definition); + + $this->assertStringContainsString('\Closure::bind(static function (\PHPUnit\Framework\TestCase $instance) {', $code); + } + public function testDeterministicProxyCode() { $definition = new Definition(__CLASS__); diff --git a/src/Symfony/Bridge/ProxyManager/composer.json b/src/Symfony/Bridge/ProxyManager/composer.json index 8cdc45cf05e48..4adc5c063f89d 100644 --- a/src/Symfony/Bridge/ProxyManager/composer.json +++ b/src/Symfony/Bridge/ProxyManager/composer.json @@ -25,7 +25,7 @@ }, "autoload": { "psr-4": { "Symfony\\Bridge\\ProxyManager\\": "" }, - "classmap": [ "Legacy/Debug.php" ], + "classmap": [ "Legacy/ProxiedMethodReturnExpression.php" ], "exclude-from-classmap": [ "/Tests/" ]