From a3d38b8e9878554ec92684f57e1bd4ccab6040b5 Mon Sep 17 00:00:00 2001 From: Leonardo Losoviz Date: Sat, 12 Dec 2020 07:32:52 +0800 Subject: [PATCH] [Downgrade PHP 7.4] Fixed bug for CovariantReturnType downgrading (#4850) --- .../DowngradeCovariantReturnTypeRector.php | 18 ++++++--- .../Fixture/iterable.php.inc | 38 +++++++++++++++++++ .../Fixture/nullable_scalar.php.inc | 20 ++++++++++ .../Fixture/self.php.inc | 38 +++++++++++++++++++ 4 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/iterable.php.inc create mode 100644 rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/nullable_scalar.php.inc create mode 100644 rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/self.php.inc diff --git a/rules/downgrade-php74/src/Rector/ClassMethod/DowngradeCovariantReturnTypeRector.php b/rules/downgrade-php74/src/Rector/ClassMethod/DowngradeCovariantReturnTypeRector.php index 290fdf6a3f6..eb2aaa28e18 100644 --- a/rules/downgrade-php74/src/Rector/ClassMethod/DowngradeCovariantReturnTypeRector.php +++ b/rules/downgrade-php74/src/Rector/ClassMethod/DowngradeCovariantReturnTypeRector.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Rector\DowngradePhp74\Rector\ClassMethod; use PhpParser\Node; +use PhpParser\Node\Name; use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\NullableType; use PhpParser\Node\Stmt\ClassMethod; @@ -13,6 +14,7 @@ use PHPStan\Analyser\Scope; use PHPStan\Reflection\ClassReflection; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\Core\Rector\AbstractRector; +use Rector\NodeTypeResolver\ClassExistenceStaticHelper; use Rector\NodeTypeResolver\Node\AttributeKey; use ReflectionMethod; use ReflectionNamedType; @@ -88,8 +90,11 @@ CODE_SAMPLE } /** @var string */ - $parentReflectionMethodClassname = $this->getDifferentReturnTypeClassnameFromAncestorClass($node); - $newType = new FullyQualified($parentReflectionMethodClassname); + $parentReflectionMethodName = $this->getDifferentReturnTypeNameFromAncestorClass($node); + // The return type name could either be a classname, without the leading "\", + // or one among the reserved identifiers ("static", "self", "iterable", etc) + // To find out which is the case, check if this name exists as a class + $newType = ClassExistenceStaticHelper::doesClassLikeExist($parentReflectionMethodName) ? new FullyQualified($parentReflectionMethodName) : new Name($parentReflectionMethodName); // Make it nullable? if ($node->returnType instanceof NullableType) { @@ -106,10 +111,10 @@ CODE_SAMPLE private function shouldRefactor(ClassMethod $classMethod): bool { - return $this->getDifferentReturnTypeClassnameFromAncestorClass($classMethod) !== null; + return $this->getDifferentReturnTypeNameFromAncestorClass($classMethod) !== null; } - private function getDifferentReturnTypeClassnameFromAncestorClass(ClassMethod $classMethod): ?string + private function getDifferentReturnTypeNameFromAncestorClass(ClassMethod $classMethod): ?string { /** @var Scope|null $scope */ $scope = $classMethod->getAttribute(AttributeKey::SCOPE); @@ -127,7 +132,9 @@ CODE_SAMPLE if ($nodeReturnType === null || $nodeReturnType instanceof UnionType) { return null; } - $nodeReturnTypeName = $this->getName($nodeReturnType); + $nodeReturnTypeName = $this->getName( + $nodeReturnType instanceof NullableType ? $nodeReturnType->type : $nodeReturnType + ); /** @var string $methodName */ $methodName = $this->getName($classMethod->name); @@ -153,7 +160,6 @@ CODE_SAMPLE if ($parentReflectionMethodReturnType === null || $parentReflectionMethodReturnType->getName() === $nodeReturnTypeName) { continue; } - // This is an ancestor class with a different return type return $parentReflectionMethodReturnType->getName(); } diff --git a/rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/iterable.php.inc b/rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/iterable.php.inc new file mode 100644 index 00000000000..918ac59efa9 --- /dev/null +++ b/rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/iterable.php.inc @@ -0,0 +1,38 @@ + +----- + diff --git a/rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/nullable_scalar.php.inc b/rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/nullable_scalar.php.inc new file mode 100644 index 00000000000..78cf8004583 --- /dev/null +++ b/rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/nullable_scalar.php.inc @@ -0,0 +1,20 @@ + diff --git a/rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/self.php.inc b/rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/self.php.inc new file mode 100644 index 00000000000..e48c5608b88 --- /dev/null +++ b/rules/downgrade-php74/tests/Rector/ClassMethod/DowngradeCovariantReturnTypeRector/Fixture/self.php.inc @@ -0,0 +1,38 @@ + +----- +