From aa7282195caab5889ee067ca3fb5eda62f26ed1b Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Wed, 6 Sep 2023 00:00:45 +0700 Subject: [PATCH] [TypeDeclaration] Add return static object support on ReturnTypeFromStrictFluentReturnRector (#4916) * [TypeDeclaration] Add return static object support on ReturnTypeFromStrictFluentReturnRector * [ci-review] Rector Rectify * [ci-review] Rector Rectify * clean up * trigger CI --------- Co-authored-by: GitHub Action --- .../Fixture/return_static.php.inc | 37 +++++++++++++++++++ .../return_static_on_php74.php.inc | 37 +++++++++++++++++++ ...ReturnTypeFromStrictFluentReturnRector.php | 36 ++++++++++++++---- 3 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector/Fixture/return_static.php.inc create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector/FixturePhp74/return_static_on_php74.php.inc diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector/Fixture/return_static.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector/Fixture/return_static.php.inc new file mode 100644 index 00000000000..cac7d2f3e51 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector/Fixture/return_static.php.inc @@ -0,0 +1,37 @@ +foo = 'foo'; + + return $obj; + } +} + +?> +----- +foo = 'foo'; + + return $obj; + } +} + +?> diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector/FixturePhp74/return_static_on_php74.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector/FixturePhp74/return_static_on_php74.php.inc new file mode 100644 index 00000000000..dfc53110724 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector/FixturePhp74/return_static_on_php74.php.inc @@ -0,0 +1,37 @@ +foo = 'foo'; + + return $obj; + } +} + +?> +----- +foo = 'foo'; + + return $obj; + } +} + +?> diff --git a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector.php b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector.php index 2ca50ab7f52..858674bfed0 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromStrictFluentReturnRector.php @@ -10,6 +10,7 @@ use PHPStan\Analyser\Scope; use PHPStan\Reflection\ClassReflection; use PHPStan\Type\ObjectType; +use PHPStan\Type\StaticType; use PHPStan\Type\ThisType; use Rector\Core\Php\PhpVersionProvider; use Rector\Core\Rector\AbstractScopeAwareRector; @@ -93,6 +94,11 @@ public function refactorWithScope(Node $node, Scope $scope): ?Node } $returnType = $this->returnTypeInferer->inferFunctionLike($node); + + if ($returnType instanceof StaticType && $returnType->getStaticObjectType()->getClassName() === $classReflection->getName()) { + return $this->processAddReturnSelfOrStatic($node, $classReflection); + } + if ($returnType instanceof ObjectType && $returnType->getClassName() === $classReflection->getName()) { $node->returnType = new Name('self'); return $node; @@ -102,14 +108,30 @@ public function refactorWithScope(Node $node, Scope $scope): ?Node return null; } - if ($classReflection->isAnonymous() - || $classReflection->isFinalByKeyword() - || ! $this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::STATIC_RETURN_TYPE)) { - $node->returnType = new Name('self'); - } else { - $node->returnType = new Name('static'); + return $this->processAddReturnSelfOrStatic($node, $classReflection); + } + + private function processAddReturnSelfOrStatic( + ClassMethod $classMethod, + ClassReflection $classReflection + ): ClassMethod { + $classMethod->returnType = $this->shouldSelf($classReflection) + ? new Name('self') + : new Name('static'); + + return $classMethod; + } + + private function shouldSelf(ClassReflection $classReflection): bool + { + if ($classReflection->isAnonymous()) { + return true; + } + + if ($classReflection->isFinalByKeyword()) { + return true; } - return $node; + return ! $this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::STATIC_RETURN_TYPE); } }