From a527c9d9d5348e012bd24482d83a5cd643bcbc9e Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 30 Jan 2023 11:40:19 +0100 Subject: [PATCH] Fix generating return statements when magic method returns void --- .../Generator/MagicMethodGenerator.php | 10 ++++ .../MultipleProxyGenerationTest.php | 8 +-- .../ClassWithTypedMagicMethods.php | 49 +++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 tests/ProxyManagerTestAsset/ClassWithTypedMagicMethods.php diff --git a/src/ProxyManager/Generator/MagicMethodGenerator.php b/src/ProxyManager/Generator/MagicMethodGenerator.php index b6efb9b9..351295cf 100644 --- a/src/ProxyManager/Generator/MagicMethodGenerator.php +++ b/src/ProxyManager/Generator/MagicMethodGenerator.php @@ -4,6 +4,7 @@ namespace ProxyManager\Generator; +use Laminas\Code\Generator\MethodGenerator as LaminasMethodGenerator; use Laminas\Code\Generator\ParameterGenerator; use LogicException; use ReflectionClass; @@ -55,4 +56,13 @@ public function __construct(ReflectionClass $originalClass, string $name, array throw new LogicException('Unexpected ' . get_class($type)); } } + + public function setBody($body): LaminasMethodGenerator + { + if ((string) $this->getReturnType() === 'void') { + $body = preg_replace('/return ([^;]++;)/', '\1 return;', $body); + } + + return parent::setBody($body); + } } diff --git a/tests/ProxyManagerTest/Functional/MultipleProxyGenerationTest.php b/tests/ProxyManagerTest/Functional/MultipleProxyGenerationTest.php index e162dd77..ffc3ff71 100644 --- a/tests/ProxyManagerTest/Functional/MultipleProxyGenerationTest.php +++ b/tests/ProxyManagerTest/Functional/MultipleProxyGenerationTest.php @@ -15,6 +15,7 @@ use ProxyManagerTestAsset\ClassWithFinalMagicMethods; use ProxyManagerTestAsset\ClassWithFinalMethods; use ProxyManagerTestAsset\ClassWithMagicMethods; +use ProxyManagerTestAsset\ClassWithTypedMagicMethods; use ProxyManagerTestAsset\ClassWithMethodWithByRefVariadicFunction; use ProxyManagerTestAsset\ClassWithMethodWithVariadicFunction; use ProxyManagerTestAsset\ClassWithMixedProperties; @@ -60,7 +61,7 @@ final class MultipleProxyGenerationTest extends TestCase */ public function testCanGenerateMultipleDifferentProxiesForSameClass($object): void { - if (null === $object && \PHP_VERSION_ID < 70400) { + if (null === $object && PHP_VERSION_ID < 70400) { self::markTestSkipped('PHP 7.4 required.'); } @@ -116,8 +117,8 @@ public function getTestedClasses(): array [new ClassWithFinalMagicMethods()], [new ClassWithByRefMagicMethods()], [new ClassWithMixedProperties()], - [\PHP_VERSION_ID >= 70400 ? new ClassWithMixedTypedProperties() : null], - [\PHP_VERSION_ID >= 70400 ? new ClassWithMixedReferenceableTypedProperties() : null], + [PHP_VERSION_ID >= 70400 ? new ClassWithMixedTypedProperties() : null], + [PHP_VERSION_ID >= 70400 ? new ClassWithMixedReferenceableTypedProperties() : null], // [new ClassWithPublicStringTypedProperty()], // [new ClassWithPublicStringNullableTypedProperty()], [new ClassWithPrivateProperties()], @@ -139,6 +140,7 @@ public function getTestedClasses(): array if (PHP_VERSION_ID >= 80000) { $objects[] = [new ClassWithPhp80TypedMethods()]; + $objects[] = [new ClassWithTypedMagicMethods()]; } if (PHP_VERSION_ID >= 80100) { diff --git a/tests/ProxyManagerTestAsset/ClassWithTypedMagicMethods.php b/tests/ProxyManagerTestAsset/ClassWithTypedMagicMethods.php new file mode 100644 index 00000000..e77e5711 --- /dev/null +++ b/tests/ProxyManagerTestAsset/ClassWithTypedMagicMethods.php @@ -0,0 +1,49 @@ + + * @license MIT + */ +class ClassWithTypedMagicMethods +{ + public array $data = []; + + public function __set(string|int $name, mixed $value): void + { + $this->data[$name] = $value; + } + + public function __get(string|int $name): mixed + { + return $this->data[$name] ?? null; + } + + public function __isset(string|int $name): bool + { + return isset($this->data[$name]); + } + + public function __unset(string|int $name): void + { + unset($this->data[$name]); + } + + public function __sleep(): array + { + return ['data']; + } + + public function __wakeup(): void + { + } + + public function __clone(): void + { + } +}