diff --git a/config/set/downgrade-php85.php b/config/set/downgrade-php85.php index 35d04acd..8863cfd5 100644 --- a/config/set/downgrade-php85.php +++ b/config/set/downgrade-php85.php @@ -3,6 +3,7 @@ declare(strict_types=1); use Rector\Config\RectorConfig; +use Rector\DowngradePhp85\Rector\Class_\DowngradeFinalPropertyPromotionRector; use Rector\DowngradePhp85\Rector\FuncCall\DowngradeArrayFirstLastRector; use Rector\Renaming\Rector\ClassConstFetch\RenameClassConstFetchRector; use Rector\Renaming\Rector\MethodCall\RenameMethodRector; @@ -14,6 +15,7 @@ $rectorConfig->phpVersion(PhpVersion::PHP_84); $rectorConfig->rules([ DowngradeArrayFirstLastRector::class, + DowngradeFinalPropertyPromotionRector::class, ]); // https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_driver_specific_pdo_constants_and_methods diff --git a/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/DowngradeFinalPropertyPromotionRectorTest.php b/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/DowngradeFinalPropertyPromotionRectorTest.php new file mode 100644 index 00000000..c6808314 --- /dev/null +++ b/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/DowngradeFinalPropertyPromotionRectorTest.php @@ -0,0 +1,28 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/Fixture/fixture.php.inc b/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/Fixture/fixture.php.inc new file mode 100644 index 00000000..d03193fd --- /dev/null +++ b/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/Fixture/fixture.php.inc @@ -0,0 +1,28 @@ + +----- + diff --git a/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/Fixture/implicit_final_property_promotion.php b/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/Fixture/implicit_final_property_promotion.php new file mode 100644 index 00000000..c048a413 --- /dev/null +++ b/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/Fixture/implicit_final_property_promotion.php @@ -0,0 +1,25 @@ + +----- + diff --git a/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/config/configured_rule.php b/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/config/configured_rule.php new file mode 100644 index 00000000..1ba08ec3 --- /dev/null +++ b/rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(DowngradeFinalPropertyPromotionRector::class); +}; diff --git a/rules/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector.php b/rules/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector.php new file mode 100644 index 00000000..91e55a7d --- /dev/null +++ b/rules/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector.php @@ -0,0 +1,121 @@ +> + */ + public function getNodeTypes(): array + { + return [ClassMethod::class]; + } + + /** + * @param ClassMethod $node + */ + public function refactor(Node $node): ?ClassMethod + { + if (! $this->isName($node, MethodName::CONSTRUCT)) { + return null; + } + + $hasChanged = false; + foreach ($node->params as $param) { + if (! $param->isPromoted()) { + continue; + } + + if (! $this->visibilityManipulator->hasVisibility($param, Visibility::FINAL)) { + continue; + } + + $hasChanged = true; + $this->visibilityManipulator->makeNonFinal($param); + + $this->addPhpDocTag($param); + + } + + if ($hasChanged) { + return $node; + } + + return null; + } + + private function addPhpDocTag(Property|Param $node): bool + { + $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); + + if ($phpDocInfo->hasByName(self::TAGNAME)) { + return false; + } + + $phpDocInfo->addPhpDocTagNode(new PhpDocTagNode('@' . self::TAGNAME, new GenericTagValueNode(''))); + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); + return true; + } +}