From f9ee33b4e4699c62c1a96c53ca921e8454e7f12f Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Wed, 25 Aug 2021 13:48:25 +0700 Subject: [PATCH] [DowngradePhp70] Add DowngradeParentTypeDeclarationRector (#755) Co-authored-by: GitHub Action --- config/set/downgrade-php70.php | 2 + ...wngradeParentTypeDeclarationRectorTest.php | 34 +++++ .../Fixture/already_has_return_doc.php.inc | 41 ++++++ .../Fixture/fixture.php.inc | 38 ++++++ .../Fixture/in_interface.php.inc | 53 ++++++++ .../Fixture/in_trait.php.inc | 50 +++++++ .../Fixture/skip_no_parent.php.inc | 13 ++ .../config/configured_rule.php | 11 ++ .../DowngradeParentTypeDeclarationRector.php | 127 ++++++++++++++++++ 9 files changed, 369 insertions(+) create mode 100644 rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/DowngradeParentTypeDeclarationRectorTest.php create mode 100644 rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/already_has_return_doc.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/fixture.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/in_interface.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/in_trait.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/skip_no_parent.php.inc create mode 100644 rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/config/configured_rule.php create mode 100644 rules/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector.php diff --git a/config/set/downgrade-php70.php b/config/set/downgrade-php70.php index d15c1c63b34..cac6e235ccf 100644 --- a/config/set/downgrade-php70.php +++ b/config/set/downgrade-php70.php @@ -4,6 +4,7 @@ use Rector\Core\Configuration\Option; use Rector\Core\ValueObject\PhpVersion; +use Rector\DowngradePhp70\Rector\ClassMethod\DowngradeParentTypeDeclarationRector; use Rector\DowngradePhp70\Rector\ClassMethod\DowngradeSelfTypeDeclarationRector; use Rector\DowngradePhp70\Rector\Coalesce\DowngradeNullCoalesceRector; use Rector\DowngradePhp70\Rector\Declare_\DowngradeStrictTypeDeclarationRector; @@ -31,4 +32,5 @@ $services->set(DowngradeSessionStartArrayOptionsRector::class); $services->set(SplitGroupedUseImportsRector::class); $services->set(DowngradeGeneratedScalarTypesRector::class); + $services->set(DowngradeParentTypeDeclarationRector::class); }; diff --git a/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/DowngradeParentTypeDeclarationRectorTest.php b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/DowngradeParentTypeDeclarationRectorTest.php new file mode 100644 index 00000000000..8c1e579276c --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/DowngradeParentTypeDeclarationRectorTest.php @@ -0,0 +1,34 @@ +doTestFileInfo($fileInfo); + } + + /** + * @return Iterator + */ + public function provideData(): Iterator + { + return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/already_has_return_doc.php.inc b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/already_has_return_doc.php.inc new file mode 100644 index 00000000000..4d7d23200c2 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/already_has_return_doc.php.inc @@ -0,0 +1,41 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/fixture.php.inc b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/fixture.php.inc new file mode 100644 index 00000000000..1074320c9ef --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/fixture.php.inc @@ -0,0 +1,38 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/in_interface.php.inc b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/in_interface.php.inc new file mode 100644 index 00000000000..d43b91d87ac --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/in_interface.php.inc @@ -0,0 +1,53 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/in_trait.php.inc b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/in_trait.php.inc new file mode 100644 index 00000000000..247d2990177 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/in_trait.php.inc @@ -0,0 +1,50 @@ + +----- + diff --git a/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/skip_no_parent.php.inc b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/skip_no_parent.php.inc new file mode 100644 index 00000000000..fbd1754f0dc --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/Fixture/skip_no_parent.php.inc @@ -0,0 +1,13 @@ + diff --git a/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/config/configured_rule.php b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/config/configured_rule.php new file mode 100644 index 00000000000..e08ae8c9ef2 --- /dev/null +++ b/rules-tests/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector/config/configured_rule.php @@ -0,0 +1,11 @@ +services(); + $services->set(DowngradeParentTypeDeclarationRector::class); +}; diff --git a/rules/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector.php b/rules/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector.php new file mode 100644 index 00000000000..55fb3c7be53 --- /dev/null +++ b/rules/DowngradePhp70/Rector/ClassMethod/DowngradeParentTypeDeclarationRector.php @@ -0,0 +1,127 @@ +> + */ + public function getNodeTypes(): array + { + return [ClassMethod::class]; + } + + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition( + 'Remove "parent" return type, add a "@return parent" tag instead', + [ + new CodeSample( + <<<'CODE_SAMPLE' +class ParentClass +{ +} + +class SomeClass extends ParentClass +{ + public function foo(): parent + { + return $this; + } +} +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +class ParentClass +{ +} + +class SomeClass extends ParentClass +{ + /** + * @return parent + */ + public function foo() + { + return $this; + } +} +CODE_SAMPLE + ), + ] + ); + } + + /** + * @param ClassMethod $node + */ + public function refactor(Node $node): ?Node + { + if (! $node->returnType instanceof Name) { + return null; + } + + if (! $this->nodeNameResolver->isName($node->returnType, 'parent')) { + return null; + } + + $node->returnType = null; + + $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); + if ($phpDocInfo->hasByType(ReturnTagValueNode::class)) { + return $node; + } + + $parentStaticType = $this->getType($node); + + if (! $parentStaticType instanceof ParentStaticType) { + return $node; + } + + $this->phpDocTypeChanger->changeReturnType($phpDocInfo, $parentStaticType); + return $node; + } + + private function getType(ClassMethod $classMethod): ?ParentStaticType + { + $scope = $classMethod->getAttribute(AttributeKey::SCOPE); + if ($scope === null) { + // in a trait + $className = $classMethod->getAttribute(AttributeKey::CLASS_NAME); + $classReflection = $this->reflectionProvider->getClass($className); + } else { + $classReflection = $scope->getClassReflection(); + } + + if (! $classReflection instanceof ClassReflection) { + return null; + } + + return new ParentStaticType($classReflection); + } +}