From ef3aa4fef7ebf03c38684b33909b3f8446324b05 Mon Sep 17 00:00:00 2001 From: Maciej Malarz Date: Mon, 28 Dec 2020 21:57:52 +0100 Subject: [PATCH 1/3] Add support for PHP 8.0 types --- .../DefaultPersistentCollectionGenerator.php | 27 +++++++++------- .../CollWithPHP80Types.php | 31 +++++++++++++++++++ ...faultPersistentCollectionGeneratorTest.php | 13 ++++++++ 3 files changed, 60 insertions(+), 11 deletions(-) create mode 100644 tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithPHP80Types.php diff --git a/lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionGenerator.php b/lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionGenerator.php index 2e956bee4a..841a50b243 100644 --- a/lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionGenerator.php +++ b/lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionGenerator.php @@ -8,9 +8,9 @@ use ReflectionClass; use ReflectionException; use ReflectionMethod; -use ReflectionNamedType; use ReflectionParameter; use ReflectionType; +use ReflectionUnionType; use const DIRECTORY_SEPARATOR; use function array_map; use function array_pop; @@ -254,15 +254,10 @@ private function getParameterType(ReflectionParameter $parameter) : string throw new ReflectionException(sprintf('Parameter "%s" has no type. Please file a bug report.', $parameter->getName())); } - $type = $parameter->getType(); - assert($type instanceof ReflectionNamedType); + $method = $parameter->getDeclaringFunction(); + assert($method instanceof ReflectionMethod); - return sprintf( - '%s%s%s', - $type->allowsNull() ? '?' : '', - $type->isBuiltin() ? '' : '\\', - $type->getName() - ); + return $this->formatType($parameter->getType(), $method, $parameter); } /** @@ -301,6 +296,15 @@ private function formatType( ReflectionMethod $method, ?ReflectionParameter $parameter = null ) : string { + if ($type instanceof ReflectionUnionType) { + return implode('|', array_map( + function (ReflectionType $unionedType) use ($method, $parameter) { + return $this->formatType($unionedType, $method, $parameter); + }, + $type->getTypes() + )); + } + $name = method_exists($type, 'getName') ? $type->getName() : (string) $type; $nameLower = strtolower($name); if ($nameLower === 'self') { @@ -314,7 +318,7 @@ private function formatType( $name = $parentClass->getName(); } - if (! $type->isBuiltin() && ! class_exists($name) && ! interface_exists($name)) { + if ($nameLower !== 'static' && ! $type->isBuiltin() && ! class_exists($name) && ! interface_exists($name)) { if ($parameter !== null) { throw PersistentCollectionException::invalidParameterTypeHint( $method->getDeclaringClass()->getName(), @@ -327,11 +331,12 @@ private function formatType( $method->getName() ); } - if (! $type->isBuiltin()) { + if ($nameLower !== 'static' && ! $type->isBuiltin()) { $name = '\\' . $name; } if ($type->allowsNull() && ($parameter === null || ! $parameter->isDefaultValueAvailable() || $parameter->getDefaultValue() !== null) + && $name !== 'mixed' ) { $name = '?' . $name; } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithPHP80Types.php b/tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithPHP80Types.php new file mode 100644 index 0000000000..394e7b9b3f --- /dev/null +++ b/tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithPHP80Types.php @@ -0,0 +1,31 @@ +dm, $this->uow); $this->assertInstanceOf(CollWithNullableReturnType::class, $coll); } + + public function testPHP80Types() + { + if (version_compare((string) phpversion(), '8.0.0', '<')) { + $this->markTestSkipped('PHP 8.0 is required to run this test'); + } + + $class = $this->generator->loadClass(CollWithPHP80Types::class, Configuration::AUTOGENERATE_EVAL); + $coll = new $class(new CollWithPHP80Types(), $this->dm, $this->uow); + $this->assertInstanceOf(CollWithPHP80Types::class, $coll); + } } From 7692b3c1d4a17a0f03019b82516c69d0d1498695 Mon Sep 17 00:00:00 2001 From: Maciej Malarz Date: Mon, 28 Dec 2020 22:53:16 +0100 Subject: [PATCH 2/3] Run static analysis on PHP 8.0 --- .github/workflows/continuous-integration.yml | 2 +- .github/workflows/static-analysis.yml | 10 ++++++++-- .../DefaultPersistentCollectionGenerator.php | 5 +++-- phpstan.neon.dist | 3 +++ 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 2be767c2bf..0e53ff5744 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -87,7 +87,7 @@ jobs: restore-keys: "php-${{ matrix.php-version }}-composer-locked-" - name: "Prepare PHP 8 dependencies" - run: "composer remove --no-update --ignore-platform-req=php --dev doctrine/coding-standard phpstan/phpstan squizlabs/php_codesniffer" + run: "composer remove --no-update --ignore-platform-req=php --dev doctrine/coding-standard squizlabs/php_codesniffer" if: "${{ matrix.php-version == '8.0' }}" - name: "Install dependencies with composer" diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index f8de45b52e..b2d757ee0c 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: php-version: - - "7.4" + - "8.0" steps: - name: "Checkout code" @@ -54,6 +54,9 @@ jobs: key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}" restore-keys: "php-${{ matrix.php-version }}-composer-locked-" + - name: "Prepare PHP 8 dependencies" + run: "composer remove --no-update --ignore-platform-req=php --dev doctrine/coding-standard squizlabs/php_codesniffer" + - name: "Install dependencies with composer" run: "composer install --no-interaction --no-progress" @@ -67,7 +70,7 @@ jobs: strategy: matrix: php-version: - - "7.4" + - "8.0" steps: - name: "Checkout code" @@ -87,6 +90,9 @@ jobs: key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}" restore-keys: "php-${{ matrix.php-version }}-composer-locked-" + - name: "Prepare PHP 8 dependencies" + run: "composer remove --no-update --ignore-platform-req=php --dev doctrine/coding-standard squizlabs/php_codesniffer" + - name: "Install dependencies with composer" run: "composer install --no-interaction --no-progress" diff --git a/lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionGenerator.php b/lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionGenerator.php index 841a50b243..9fde8237cf 100644 --- a/lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionGenerator.php +++ b/lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionGenerator.php @@ -8,6 +8,7 @@ use ReflectionClass; use ReflectionException; use ReflectionMethod; +use ReflectionNamedType; use ReflectionParameter; use ReflectionType; use ReflectionUnionType; @@ -24,7 +25,6 @@ use function interface_exists; use function is_dir; use function is_writable; -use function method_exists; use function mkdir; use function rename; use function sprintf; @@ -305,7 +305,8 @@ function (ReflectionType $unionedType) use ($method, $parameter) { )); } - $name = method_exists($type, 'getName') ? $type->getName() : (string) $type; + assert($type instanceof ReflectionNamedType); + $name = $type->getName(); $nameLower = strtolower($name); if ($nameLower === 'self') { $name = $method->getDeclaringClass()->getName(); diff --git a/phpstan.neon.dist b/phpstan.neon.dist index aee6fb665d..5121f9cb2f 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -6,3 +6,6 @@ parameters: paths: - %rootDir%/../../../benchmark - %rootDir%/../../../lib + excludes_analyse: + - lib/Doctrine/ODM/MongoDB/Aggregation/Stage/GraphLookup/Match.php + - lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Match.php From 683f3e7d5c3aea9a414af0a919778b8bc12fa49e Mon Sep 17 00:00:00 2001 From: Maciej Malarz Date: Tue, 29 Dec 2020 20:02:12 +0100 Subject: [PATCH 3/3] Work around old doctrine/coding-standard and PHP 8.0 features --- phpcs.xml.dist | 1 + 1 file changed, 1 insertion(+) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index d86d67aee9..fffade857e 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -17,6 +17,7 @@ tests/Proxies* tests/Hydrators* tests/PersistentCollections* + tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithPHP80Types.php