From 3661a2d8202c265a15c91c4c08d1792b0033bdfc Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 27 Apr 2022 15:54:23 -0700 Subject: [PATCH] Fix enums and new in initializers as default values on PHP 8.1 --- .../Factory/AbstractBaseFactory.php | 2 +- src/ProxyManager/Generator/ClassGenerator.php | 37 ++++++- src/ProxyManager/Generator/ValueGenerator.php | 65 +++++++++++ .../MethodGenerator/CallInitializer.php | 3 +- .../MethodGenerator/RemoteObjectMethod.php | 26 +++-- .../FatalPreventionFunctionalTest.php | 2 +- .../MultipleProxyGenerationTest.php | 5 + .../Functional/RemoteObjectFunctionalTest.php | 22 +++- .../BaseGeneratorStrategyTest.php | 2 +- .../EvaluatingGeneratorStrategyTest.php | 2 +- .../FileWriterGeneratorStrategyTest.php | 2 +- .../AbstractProxyGeneratorTest.php | 7 +- .../AccessInterceptorScopeLocalizerTest.php | 2 +- .../MethodGenerator/CallInitializerTest.php | 102 +++++++----------- .../LazyLoadingGhostGeneratorTest.php | 2 +- .../NullObjectGeneratorTest.php | 7 +- .../RemoteObjectMethodTest.php | 27 +++-- .../RemoteObjectGeneratorTest.php | 7 +- .../ClassWithPhp81Defaults.php | 24 +++++ .../RemoteProxy/FooEnum.php | 10 ++ ...emoteServiceWithPhp81DefaultsInterface.php | 15 +++ 21 files changed, 265 insertions(+), 106 deletions(-) create mode 100644 src/ProxyManager/Generator/ValueGenerator.php create mode 100644 tests/ProxyManagerTestAsset/ClassWithPhp81Defaults.php create mode 100644 tests/ProxyManagerTestAsset/RemoteProxy/FooEnum.php create mode 100644 tests/ProxyManagerTestAsset/RemoteProxy/RemoteServiceWithPhp81DefaultsInterface.php diff --git a/src/ProxyManager/Factory/AbstractBaseFactory.php b/src/ProxyManager/Factory/AbstractBaseFactory.php index 50d7fed8..e39b0399 100644 --- a/src/ProxyManager/Factory/AbstractBaseFactory.php +++ b/src/ProxyManager/Factory/AbstractBaseFactory.php @@ -4,9 +4,9 @@ namespace ProxyManager\Factory; -use Laminas\Code\Generator\ClassGenerator; use OutOfBoundsException; use ProxyManager\Configuration; +use ProxyManager\Generator\ClassGenerator; use ProxyManager\ProxyGenerator\ProxyGeneratorInterface; use ProxyManager\Signature\Exception\InvalidSignatureException; use ProxyManager\Signature\Exception\MissingSignatureException; diff --git a/src/ProxyManager/Generator/ClassGenerator.php b/src/ProxyManager/Generator/ClassGenerator.php index fd014334..84b3f5f6 100644 --- a/src/ProxyManager/Generator/ClassGenerator.php +++ b/src/ProxyManager/Generator/ClassGenerator.php @@ -5,14 +5,47 @@ namespace ProxyManager\Generator; use Laminas\Code\Generator\ClassGenerator as LaminasClassGenerator; +use ProxyManager\Generator\ValueGenerator; +use ReflectionParameter; + +use function method_exists; /** * Class generator that ensures that interfaces/classes that are implemented/extended are FQCNs * * @internal do not use this in your code: it is only here for internal use - * @deprecated this class was in use due to parent implementation not receiving prompt bugfixes, but - * `laminas/laminas-code` is actively maintained and receives quick release iterations. */ class ClassGenerator extends LaminasClassGenerator { + public function generate(): string + { + $extendedClass = $this->getExtendedClass(); + + foreach ($this->getMethods() as $method) { + $class = $extendedClass; + + if ($class === null) { + foreach ($this->getImplementedInterfaces() as $interface) { + if (method_exists($interface, $method->getName())) { + $class = $interface; + break; + } + } + } + + if ($class === null || ! method_exists($class, $method->getName())) { + continue; + } + + foreach ($method->getParameters() as $parameter) { + $default = $parameter->getDefaultValue(); + + if ($default !== null) { + $parameter->setDefaultValue(new ValueGenerator($default, new ReflectionParameter([$class, $method->getName()], $parameter->getName()))); + } + } + } + + return parent::generate(); + } } diff --git a/src/ProxyManager/Generator/ValueGenerator.php b/src/ProxyManager/Generator/ValueGenerator.php new file mode 100644 index 00000000..5a316af5 --- /dev/null +++ b/src/ProxyManager/Generator/ValueGenerator.php @@ -0,0 +1,65 @@ + $v) { + $this->$k = $v; + } + } else { + parent::__construct($value, parent::TYPE_AUTO, parent::OUTPUT_SINGLE_LINE); + } + + $this->reflection = $reflection; + } + + public function generate(): string + { + try { + return parent::generate(); + } catch (RuntimeException $e) { + if ($this->reflection) { + $value = rtrim(substr(explode('$' . $this->reflection->name . ' = ', (string) $this->reflection, 2)[1], 0, -2)); + } else { + $value = var_export($this->value, true); + } + + return self::fixExport($value); + } + } + + private static function fixExport(string $value): string + { + $parts = preg_split('{(\'(?:[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')}', $value, -1, PREG_SPLIT_DELIM_CAPTURE); + + foreach ($parts as $i => &$part) { + if ($part !== '' && $i % 2 === 0) { + $part = preg_replace('/(?(DEFINE)(?[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+))(?getName(); $defaults = $property->getDeclaringClass()->getDefaultProperties(); - return var_export($defaults[$name] ?? null, true); + return (new ValueGenerator($defaults[$name] ?? null))->generate(); } } diff --git a/src/ProxyManager/ProxyGenerator/RemoteObject/MethodGenerator/RemoteObjectMethod.php b/src/ProxyManager/ProxyGenerator/RemoteObject/MethodGenerator/RemoteObjectMethod.php index 799a3806..fe5fd732 100644 --- a/src/ProxyManager/ProxyGenerator/RemoteObject/MethodGenerator/RemoteObjectMethod.php +++ b/src/ProxyManager/ProxyGenerator/RemoteObject/MethodGenerator/RemoteObjectMethod.php @@ -8,6 +8,7 @@ use Laminas\Code\Reflection\MethodReflection; use ProxyManager\Generator\MethodGenerator; use ProxyManager\Generator\Util\ProxiedMethodReturnExpression; +use ProxyManager\Generator\ValueGenerator; use ReflectionClass; use function count; @@ -21,10 +22,10 @@ class RemoteObjectMethod extends MethodGenerator { private const TEMPLATE = <<<'PHP' -$defaultValues = #DEFAULT_VALUES#; -$declaredParameterCount = #PARAMETER_COUNT#; +$args = \func_get_args(); -$args = \func_get_args() + $defaultValues; +switch (\func_num_args()) {#DEFAULT_VALUES# +} #PROXIED_RETURN# PHP; @@ -41,16 +42,14 @@ public static function generateMethod( . ', ' . var_export($originalMethod->getName(), true) . ', $args);' . "\n\n" . ProxiedMethodReturnExpression::generate('$return', $originalMethod); - $defaultValues = self::getDefaultValuesForMethod($originalMethod); - $declaredParameterCount = count($originalMethod->getParameters()); + $defaultValues = self::getDefaultValuesForMethod($originalMethod); $method->setBody( strtr( self::TEMPLATE, [ '#PROXIED_RETURN#' => $proxiedReturn, - '#DEFAULT_VALUES#' => var_export($defaultValues, true), - '#PARAMETER_COUNT#' => var_export($declaredParameterCount, true), + '#DEFAULT_VALUES#' => $defaultValues, ] ) ); @@ -58,14 +57,13 @@ public static function generateMethod( return $method; } - /** @psalm-return list */ - private static function getDefaultValuesForMethod(MethodReflection $originalMethod): array + private static function getDefaultValuesForMethod(MethodReflection $originalMethod): string { - $defaultValues = []; - foreach ($originalMethod->getParameters() as $parameter) { + $defaultValues = ''; + foreach ($originalMethod->getParameters() as $i => $parameter) { if ($parameter->isOptional() && $parameter->isDefaultValueAvailable()) { - /** @psalm-var int|float|bool|array|string|null */ - $defaultValues[] = $parameter->getDefaultValue(); + $default = new ValueGenerator($parameter->getDefaultValue(), $parameter); + $defaultValues .= sprintf("\n case $i: \$args[] = %s;", $default->generate()); continue; } @@ -73,7 +71,7 @@ private static function getDefaultValuesForMethod(MethodReflection $originalMeth continue; } - $defaultValues[] = null; + $defaultValues .= "\n case $i: \$args[] = null;"; } return $defaultValues; diff --git a/tests/ProxyManagerTest/Functional/FatalPreventionFunctionalTest.php b/tests/ProxyManagerTest/Functional/FatalPreventionFunctionalTest.php index f2a7dbd3..8e4f48d6 100644 --- a/tests/ProxyManagerTest/Functional/FatalPreventionFunctionalTest.php +++ b/tests/ProxyManagerTest/Functional/FatalPreventionFunctionalTest.php @@ -4,9 +4,9 @@ namespace ProxyManagerTest\Functional; -use Laminas\Code\Generator\ClassGenerator; use PHPUnit\Framework\TestCase; use ProxyManager\Exception\ExceptionInterface; +use ProxyManager\Generator\ClassGenerator; use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; use ProxyManager\Proxy\ProxyInterface; use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizerGenerator; diff --git a/tests/ProxyManagerTest/Functional/MultipleProxyGenerationTest.php b/tests/ProxyManagerTest/Functional/MultipleProxyGenerationTest.php index 5a8d223a..bccc7978 100644 --- a/tests/ProxyManagerTest/Functional/MultipleProxyGenerationTest.php +++ b/tests/ProxyManagerTest/Functional/MultipleProxyGenerationTest.php @@ -22,6 +22,7 @@ use ProxyManagerTestAsset\ClassWithMixedTypedProperties; use ProxyManagerTestAsset\ClassWithParentHint; use ProxyManagerTestAsset\ClassWithPhp80TypedMethods; +use ProxyManagerTestAsset\ClassWithPhp81Defaults; use ProxyManagerTestAsset\ClassWithPrivateProperties; use ProxyManagerTestAsset\ClassWithProtectedProperties; use ProxyManagerTestAsset\ClassWithPublicProperties; @@ -138,6 +139,10 @@ public function getTestedClasses(): array $objects[] = [new ClassWithPhp80TypedMethods()]; } + if (PHP_VERSION_ID >= 80100) { + $objects['php81defaults'] = [new ClassWithPhp81Defaults()]; + } + return $objects; } } diff --git a/tests/ProxyManagerTest/Functional/RemoteObjectFunctionalTest.php b/tests/ProxyManagerTest/Functional/RemoteObjectFunctionalTest.php index c20b9843..f277784f 100644 --- a/tests/ProxyManagerTest/Functional/RemoteObjectFunctionalTest.php +++ b/tests/ProxyManagerTest/Functional/RemoteObjectFunctionalTest.php @@ -18,12 +18,15 @@ use ProxyManagerTestAsset\OtherObjectAccessClass; use ProxyManagerTestAsset\RemoteProxy\BazServiceInterface; use ProxyManagerTestAsset\RemoteProxy\Foo; +use ProxyManagerTestAsset\RemoteProxy\FooEnum; use ProxyManagerTestAsset\RemoteProxy\FooServiceInterface; use ProxyManagerTestAsset\RemoteProxy\RemoteServiceWithDefaultsAndVariadicArguments; use ProxyManagerTestAsset\RemoteProxy\RemoteServiceWithDefaultsInterface; +use ProxyManagerTestAsset\RemoteProxy\RemoteServiceWithPhp81DefaultsInterface; use ProxyManagerTestAsset\RemoteProxy\VariadicArgumentsServiceInterface; use ProxyManagerTestAsset\VoidCounter; use ReflectionClass; +use stdClass; use function assert; use function get_class; @@ -32,6 +35,8 @@ use function ucfirst; use function uniqid; +use const PHP_VERSION_ID; + /** * Tests for {@see \ProxyManager\ProxyGenerator\RemoteObjectGenerator} produced objects * @@ -151,7 +156,7 @@ public function getProxyMethods(): array { $selfHintParam = new ClassWithSelfHint(); - return [ + $methods = [ [ FooServiceInterface::class, 'foo', @@ -273,6 +278,21 @@ public function getProxyMethods(): array 200, ], ]; + + if (PHP_VERSION_ID >= 80100) { + $methods['when using php8.1 defaults'] = [ + RemoteServiceWithPhp81DefaultsInterface::class, + 'php81Defaults', + [], + [ + FooEnum::bar, + new stdClass(), + ], + 200, + ]; + } + + return $methods; } /** diff --git a/tests/ProxyManagerTest/GeneratorStrategy/BaseGeneratorStrategyTest.php b/tests/ProxyManagerTest/GeneratorStrategy/BaseGeneratorStrategyTest.php index ac42d8e6..a9d110f7 100644 --- a/tests/ProxyManagerTest/GeneratorStrategy/BaseGeneratorStrategyTest.php +++ b/tests/ProxyManagerTest/GeneratorStrategy/BaseGeneratorStrategyTest.php @@ -4,8 +4,8 @@ namespace ProxyManagerTest\GeneratorStrategy; -use Laminas\Code\Generator\ClassGenerator; use PHPUnit\Framework\TestCase; +use ProxyManager\Generator\ClassGenerator; use ProxyManager\Generator\Util\UniqueIdentifierGenerator; use ProxyManager\GeneratorStrategy\BaseGeneratorStrategy; diff --git a/tests/ProxyManagerTest/GeneratorStrategy/EvaluatingGeneratorStrategyTest.php b/tests/ProxyManagerTest/GeneratorStrategy/EvaluatingGeneratorStrategyTest.php index 5c617423..ca554a14 100644 --- a/tests/ProxyManagerTest/GeneratorStrategy/EvaluatingGeneratorStrategyTest.php +++ b/tests/ProxyManagerTest/GeneratorStrategy/EvaluatingGeneratorStrategyTest.php @@ -4,8 +4,8 @@ namespace ProxyManagerTest\GeneratorStrategy; -use Laminas\Code\Generator\ClassGenerator; use PHPUnit\Framework\TestCase; +use ProxyManager\Generator\ClassGenerator; use ProxyManager\Generator\Util\UniqueIdentifierGenerator; use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; diff --git a/tests/ProxyManagerTest/GeneratorStrategy/FileWriterGeneratorStrategyTest.php b/tests/ProxyManagerTest/GeneratorStrategy/FileWriterGeneratorStrategyTest.php index 092d6aa1..db394281 100644 --- a/tests/ProxyManagerTest/GeneratorStrategy/FileWriterGeneratorStrategyTest.php +++ b/tests/ProxyManagerTest/GeneratorStrategy/FileWriterGeneratorStrategyTest.php @@ -4,10 +4,10 @@ namespace ProxyManagerTest\GeneratorStrategy; -use Laminas\Code\Generator\ClassGenerator; use PHPUnit\Framework\TestCase; use ProxyManager\Exception\FileNotWritableException; use ProxyManager\FileLocator\FileLocatorInterface; +use ProxyManager\Generator\ClassGenerator; use ProxyManager\Generator\Util\UniqueIdentifierGenerator; use ProxyManager\GeneratorStrategy\FileWriterGeneratorStrategy; diff --git a/tests/ProxyManagerTest/ProxyGenerator/AbstractProxyGeneratorTest.php b/tests/ProxyManagerTest/ProxyGenerator/AbstractProxyGeneratorTest.php index f1be1fff..22a70199 100644 --- a/tests/ProxyManagerTest/ProxyGenerator/AbstractProxyGeneratorTest.php +++ b/tests/ProxyManagerTest/ProxyGenerator/AbstractProxyGeneratorTest.php @@ -4,8 +4,8 @@ namespace ProxyManagerTest\ProxyGenerator; -use Laminas\Code\Generator\ClassGenerator; use PHPUnit\Framework\TestCase; +use ProxyManager\Generator\ClassGenerator; use ProxyManager\Generator\Util\UniqueIdentifierGenerator; use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; use ProxyManager\ProxyGenerator\ProxyGeneratorInterface; @@ -18,6 +18,7 @@ use ProxyManagerTestAsset\ClassWithMixedReferenceableTypedProperties; use ProxyManagerTestAsset\ClassWithMixedTypedProperties; use ProxyManagerTestAsset\ClassWithPhp80TypedMethods; +use ProxyManagerTestAsset\ClassWithPhp81Defaults; use ProxyManagerTestAsset\IterableMethodTypeHintedInterface; use ProxyManagerTestAsset\ObjectMethodTypeHintedInterface; use ProxyManagerTestAsset\ReturnTypeHintedClass; @@ -112,6 +113,10 @@ public function getTestedImplementations(): array $implementations[] = [ClassWithPhp80TypedMethods::class]; } + if (PHP_VERSION_ID >= 80100) { + $implementations['php81defaults'] = [ClassWithPhp81Defaults::class]; + } + return $implementations; } } diff --git a/tests/ProxyManagerTest/ProxyGenerator/AccessInterceptorScopeLocalizerTest.php b/tests/ProxyManagerTest/ProxyGenerator/AccessInterceptorScopeLocalizerTest.php index 45ef998f..d830bb89 100644 --- a/tests/ProxyManagerTest/ProxyGenerator/AccessInterceptorScopeLocalizerTest.php +++ b/tests/ProxyManagerTest/ProxyGenerator/AccessInterceptorScopeLocalizerTest.php @@ -4,9 +4,9 @@ namespace ProxyManagerTest\ProxyGenerator; -use Laminas\Code\Generator\ClassGenerator; use ProxyManager\Exception\InvalidProxiedClassException; use ProxyManager\Exception\UnsupportedProxiedClassException; +use ProxyManager\Generator\ClassGenerator; use ProxyManager\Proxy\AccessInterceptorInterface; use ProxyManager\ProxyGenerator\AccessInterceptorScopeLocalizerGenerator; use ProxyManager\ProxyGenerator\ProxyGeneratorInterface; diff --git a/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializerTest.php b/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializerTest.php index 63f7a01b..1e55e4cd 100644 --- a/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializerTest.php +++ b/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhost/MethodGenerator/CallInitializerTest.php @@ -116,98 +116,74 @@ public function testBodyStructureWithTypedProperties(): void $this->track = true; $this->publicUnTypedProperty = 'publicUnTypedProperty'; -$this->publicUnTypedPropertyWithoutDefaultValue = NULL; +$this->publicUnTypedPropertyWithoutDefaultValue = null; $this->publicBoolProperty = true; $this->publicNullableBoolProperty = true; -$this->publicNullableBoolPropertyWithoutDefaultValue = NULL; +$this->publicNullableBoolPropertyWithoutDefaultValue = null; $this->publicIntProperty = 123; $this->publicNullableIntProperty = 123; -$this->publicNullableIntPropertyWithoutDefaultValue = NULL; +$this->publicNullableIntPropertyWithoutDefaultValue = null; $this->publicFloatProperty = 123.456; $this->publicNullableFloatProperty = 123.456; -$this->publicNullableFloatPropertyWithoutDefaultValue = NULL; +$this->publicNullableFloatPropertyWithoutDefaultValue = null; $this->publicStringProperty = 'publicStringProperty'; $this->publicNullableStringProperty = 'publicStringProperty'; -$this->publicNullableStringPropertyWithoutDefaultValue = NULL; -$this->publicArrayProperty = array ( - 0 => 'publicArrayProperty', -); -$this->publicNullableArrayProperty = array ( - 0 => 'publicArrayProperty', -); -$this->publicNullableArrayPropertyWithoutDefaultValue = NULL; -$this->publicIterableProperty = array ( - 0 => 'publicIterableProperty', -); -$this->publicNullableIterableProperty = array ( - 0 => 'publicIterableProperty', -); -$this->publicNullableIterablePropertyWithoutDefaultValue = NULL; -$this->publicNullableObjectProperty = NULL; -$this->publicNullableClassProperty = NULL; +$this->publicNullableStringPropertyWithoutDefaultValue = null; +$this->publicArrayProperty = ['publicArrayProperty']; +$this->publicNullableArrayProperty = ['publicArrayProperty']; +$this->publicNullableArrayPropertyWithoutDefaultValue = null; +$this->publicIterableProperty = ['publicIterableProperty']; +$this->publicNullableIterableProperty = ['publicIterableProperty']; +$this->publicNullableIterablePropertyWithoutDefaultValue = null; +$this->publicNullableObjectProperty = null; +$this->publicNullableClassProperty = null; $this->protectedUnTypedProperty = 'protectedUnTypedProperty'; -$this->protectedUnTypedPropertyWithoutDefaultValue = NULL; +$this->protectedUnTypedPropertyWithoutDefaultValue = null; $this->protectedBoolProperty = true; $this->protectedNullableBoolProperty = true; -$this->protectedNullableBoolPropertyWithoutDefaultValue = NULL; +$this->protectedNullableBoolPropertyWithoutDefaultValue = null; $this->protectedIntProperty = 123; $this->protectedNullableIntProperty = 123; -$this->protectedNullableIntPropertyWithoutDefaultValue = NULL; +$this->protectedNullableIntPropertyWithoutDefaultValue = null; $this->protectedFloatProperty = 123.456; $this->protectedNullableFloatProperty = 123.456; -$this->protectedNullableFloatPropertyWithoutDefaultValue = NULL; +$this->protectedNullableFloatPropertyWithoutDefaultValue = null; $this->protectedStringProperty = 'protectedStringProperty'; $this->protectedNullableStringProperty = 'protectedStringProperty'; -$this->protectedNullableStringPropertyWithoutDefaultValue = NULL; -$this->protectedArrayProperty = array ( - 0 => 'protectedArrayProperty', -); -$this->protectedNullableArrayProperty = array ( - 0 => 'protectedArrayProperty', -); -$this->protectedNullableArrayPropertyWithoutDefaultValue = NULL; -$this->protectedIterableProperty = array ( - 0 => 'protectedIterableProperty', -); -$this->protectedNullableIterableProperty = array ( - 0 => 'protectedIterableProperty', -); -$this->protectedNullableIterablePropertyWithoutDefaultValue = NULL; -$this->protectedNullableObjectProperty = NULL; -$this->protectedNullableClassProperty = NULL; +$this->protectedNullableStringPropertyWithoutDefaultValue = null; +$this->protectedArrayProperty = ['protectedArrayProperty']; +$this->protectedNullableArrayProperty = ['protectedArrayProperty']; +$this->protectedNullableArrayPropertyWithoutDefaultValue = null; +$this->protectedIterableProperty = ['protectedIterableProperty']; +$this->protectedNullableIterableProperty = ['protectedIterableProperty']; +$this->protectedNullableIterablePropertyWithoutDefaultValue = null; +$this->protectedNullableObjectProperty = null; +$this->protectedNullableClassProperty = null; static $cacheProxyManagerTestAsset_ClassWithMixedTypedProperties; $cacheProxyManagerTestAsset_ClassWithMixedTypedProperties ?? $cacheProxyManagerTestAsset_ClassWithMixedTypedProperties = \Closure::bind(static function ($instance) { $instance->privateUnTypedProperty = 'privateUnTypedProperty'; - $instance->privateUnTypedPropertyWithoutDefaultValue = NULL; + $instance->privateUnTypedPropertyWithoutDefaultValue = null; $instance->privateBoolProperty = true; $instance->privateNullableBoolProperty = true; - $instance->privateNullableBoolPropertyWithoutDefaultValue = NULL; + $instance->privateNullableBoolPropertyWithoutDefaultValue = null; $instance->privateIntProperty = 123; $instance->privateNullableIntProperty = 123; - $instance->privateNullableIntPropertyWithoutDefaultValue = NULL; + $instance->privateNullableIntPropertyWithoutDefaultValue = null; $instance->privateFloatProperty = 123.456; $instance->privateNullableFloatProperty = 123.456; - $instance->privateNullableFloatPropertyWithoutDefaultValue = NULL; + $instance->privateNullableFloatPropertyWithoutDefaultValue = null; $instance->privateStringProperty = 'privateStringProperty'; $instance->privateNullableStringProperty = 'privateStringProperty'; - $instance->privateNullableStringPropertyWithoutDefaultValue = NULL; - $instance->privateArrayProperty = array ( - 0 => 'privateArrayProperty', -); - $instance->privateNullableArrayProperty = array ( - 0 => 'privateArrayProperty', -); - $instance->privateNullableArrayPropertyWithoutDefaultValue = NULL; - $instance->privateIterableProperty = array ( - 0 => 'privateIterableProperty', -); - $instance->privateNullableIterableProperty = array ( - 0 => 'privateIterableProperty', -); - $instance->privateNullableIterablePropertyWithoutDefaultValue = NULL; - $instance->privateNullableObjectProperty = NULL; - $instance->privateNullableClassProperty = NULL; + $instance->privateNullableStringPropertyWithoutDefaultValue = null; + $instance->privateArrayProperty = ['privateArrayProperty']; + $instance->privateNullableArrayProperty = ['privateArrayProperty']; + $instance->privateNullableArrayPropertyWithoutDefaultValue = null; + $instance->privateIterableProperty = ['privateIterableProperty']; + $instance->privateNullableIterableProperty = ['privateIterableProperty']; + $instance->privateNullableIterablePropertyWithoutDefaultValue = null; + $instance->privateNullableObjectProperty = null; + $instance->privateNullableClassProperty = null; }, null, 'ProxyManagerTestAsset\\ClassWithMixedTypedProperties'); $cacheProxyManagerTestAsset_ClassWithMixedTypedProperties($this); diff --git a/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhostGeneratorTest.php b/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhostGeneratorTest.php index d7bfa5e5..97e21d68 100644 --- a/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhostGeneratorTest.php +++ b/tests/ProxyManagerTest/ProxyGenerator/LazyLoadingGhostGeneratorTest.php @@ -4,8 +4,8 @@ namespace ProxyManagerTest\ProxyGenerator; -use Laminas\Code\Generator\ClassGenerator; use ProxyManager\Exception\InvalidProxiedClassException; +use ProxyManager\Generator\ClassGenerator; use ProxyManager\Proxy\GhostObjectInterface; use ProxyManager\ProxyGenerator\LazyLoadingGhostGenerator; use ProxyManager\ProxyGenerator\ProxyGeneratorInterface; diff --git a/tests/ProxyManagerTest/ProxyGenerator/NullObjectGeneratorTest.php b/tests/ProxyManagerTest/ProxyGenerator/NullObjectGeneratorTest.php index 86d91a0d..0fd72171 100644 --- a/tests/ProxyManagerTest/ProxyGenerator/NullObjectGeneratorTest.php +++ b/tests/ProxyManagerTest/ProxyGenerator/NullObjectGeneratorTest.php @@ -4,7 +4,7 @@ namespace ProxyManagerTest\ProxyGenerator; -use Laminas\Code\Generator\ClassGenerator; +use ProxyManager\Generator\ClassGenerator; use ProxyManager\Generator\Util\UniqueIdentifierGenerator; use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; use ProxyManager\Proxy\NullObjectInterface; @@ -19,6 +19,7 @@ use ProxyManagerTestAsset\ClassWithMixedReferenceableTypedProperties; use ProxyManagerTestAsset\ClassWithMixedTypedProperties; use ProxyManagerTestAsset\ClassWithPhp80TypedMethods; +use ProxyManagerTestAsset\ClassWithPhp81Defaults; use ReflectionClass; use ReflectionMethod; @@ -131,6 +132,10 @@ public function getTestedImplementations(): array $implementations[] = [ClassWithPhp80TypedMethods::class]; } + if (PHP_VERSION_ID >= 80100) { + $implementations[] = [ClassWithPhp81Defaults::class]; + } + return $implementations; } } diff --git a/tests/ProxyManagerTest/ProxyGenerator/RemoteObject/MethodGenerator/RemoteObjectMethodTest.php b/tests/ProxyManagerTest/ProxyGenerator/RemoteObject/MethodGenerator/RemoteObjectMethodTest.php index 7eb99087..f4849d45 100644 --- a/tests/ProxyManagerTest/ProxyGenerator/RemoteObject/MethodGenerator/RemoteObjectMethodTest.php +++ b/tests/ProxyManagerTest/ProxyGenerator/RemoteObject/MethodGenerator/RemoteObjectMethodTest.php @@ -40,13 +40,12 @@ public function testBodyStructureWithParameters(): void self::assertSame('publicByReferenceParameterMethod', $method->getName()); self::assertCount(2, $method->getParameters()); self::assertSame( - '$defaultValues = array ( - 0 => NULL, - 1 => NULL, -); -$declaredParameterCount = 2; + '$args = \func_get_args(); -$args = \func_get_args() + $defaultValues; +switch (\func_num_args()) { + case 0: $args[] = null; + case 1: $args[] = null; +} $return = $this->adapter->call(\'Laminas\\\\Code\\\\Generator\\\\PropertyGenerator\', \'publicByReferenceParameterMethod\', $args); @@ -74,12 +73,11 @@ public function testBodyStructureWithArrayParameter(): void self::assertSame('publicArrayHintedMethod', $method->getName()); self::assertCount(1, $method->getParameters()); self::assertSame( - "\$defaultValues = array ( - 0 => NULL, -); -\$declaredParameterCount = 1; + "\$args = \\func_get_args(); -\$args = \\func_get_args() + \$defaultValues; +switch (\\func_num_args()) { + case 0: \$args[] = null; +} \$return = \$this->adapter->call('Laminas\\\\Code\\\\Generator\\\\PropertyGenerator', 'publicArrayHintedMethod', \$args); @@ -107,11 +105,10 @@ public function testBodyStructureWithoutParameters(): void self::assertSame('publicMethod', $method->getName()); self::assertCount(0, $method->getParameters()); self::assertSame( - "\$defaultValues = array ( -); -\$declaredParameterCount = 0; + "\$args = \\func_get_args(); -\$args = \\func_get_args() + \$defaultValues; +switch (\\func_num_args()) { +} \$return = \$this->adapter->call('Laminas\\\\Code\\\\Generator\\\\PropertyGenerator', 'publicMethod', \$args); diff --git a/tests/ProxyManagerTest/ProxyGenerator/RemoteObjectGeneratorTest.php b/tests/ProxyManagerTest/ProxyGenerator/RemoteObjectGeneratorTest.php index 9700a024..3eedc968 100644 --- a/tests/ProxyManagerTest/ProxyGenerator/RemoteObjectGeneratorTest.php +++ b/tests/ProxyManagerTest/ProxyGenerator/RemoteObjectGeneratorTest.php @@ -4,7 +4,7 @@ namespace ProxyManagerTest\ProxyGenerator; -use Laminas\Code\Generator\ClassGenerator; +use ProxyManager\Generator\ClassGenerator; use ProxyManager\Generator\Util\UniqueIdentifierGenerator; use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; use ProxyManager\Proxy\RemoteObjectInterface; @@ -18,6 +18,7 @@ use ProxyManagerTestAsset\ClassWithMixedReferenceableTypedProperties; use ProxyManagerTestAsset\ClassWithMixedTypedProperties; use ProxyManagerTestAsset\ClassWithPhp80TypedMethods; +use ProxyManagerTestAsset\ClassWithPhp81Defaults; use ReflectionClass; use function array_diff; @@ -101,6 +102,10 @@ public function getTestedImplementations(): array $implementations[] = [ClassWithPhp80TypedMethods::class]; } + if (PHP_VERSION_ID >= 80100) { + $implementations['php81defaults'] = [ClassWithPhp81Defaults::class]; + } + return $implementations; } } diff --git a/tests/ProxyManagerTestAsset/ClassWithPhp81Defaults.php b/tests/ProxyManagerTestAsset/ClassWithPhp81Defaults.php new file mode 100644 index 00000000..c7894d7b --- /dev/null +++ b/tests/ProxyManagerTestAsset/ClassWithPhp81Defaults.php @@ -0,0 +1,24 @@ +