diff --git a/phpstan.neon b/phpstan.neon index d131826bcbe..b8faf77878f 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -708,3 +708,4 @@ parameters: # optional rule for PHP 8.0 - '#Register "Rector\\Php80\\Rector\\Class_\\ConstantListClassToEnumRector" service to "php80\.php" config set#' - '#Rule Rector\\Php80\\Rector\\Class_\\ConstantListClassToEnumRector must implements Rector\\VersionBonding\\Contract\\MinPhpVersionInterface#' + - '#Register "Rector\\DowngradePhp80\\Rector\\Enum_\\DowngradeEnumToConstantListClassRector" service to "downgrade\-php80\.php" config set#' diff --git a/rules-tests/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector/DowngradeEnumToConstantListClassRectorTest.php b/rules-tests/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector/DowngradeEnumToConstantListClassRectorTest.php new file mode 100644 index 00000000000..815809162c8 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector/DowngradeEnumToConstantListClassRectorTest.php @@ -0,0 +1,33 @@ +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/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector/Fixture/some_class.php.inc b/rules-tests/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector/Fixture/some_class.php.inc new file mode 100644 index 00000000000..bd6294e869f --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector/Fixture/some_class.php.inc @@ -0,0 +1,24 @@ + +----- + diff --git a/rules-tests/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector/config/configured_rule.php b/rules-tests/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector/config/configured_rule.php new file mode 100644 index 00000000000..9f634d12da1 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(DowngradeEnumToConstantListClassRector::class); +}; diff --git a/rules/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector.php b/rules/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector.php new file mode 100644 index 00000000000..7d162e27e63 --- /dev/null +++ b/rules/DowngradePhp80/Rector/Enum_/DowngradeEnumToConstantListClassRector.php @@ -0,0 +1,66 @@ +> + */ + public function getNodeTypes(): array + { + return [Enum_::class]; + } + + /** + * @param Enum_ $node + */ + public function refactor(Node $node): Class_ + { + return $this->classFromEnumFactory->createFromEnum($node); + } +} diff --git a/rules/Php81/NodeFactory/ClassFromEnumFactory.php b/rules/Php81/NodeFactory/ClassFromEnumFactory.php new file mode 100644 index 00000000000..a7566331a7b --- /dev/null +++ b/rules/Php81/NodeFactory/ClassFromEnumFactory.php @@ -0,0 +1,62 @@ +nodeNameResolver->getShortName($enum); + + $classConsts = []; + foreach ($enum->stmts as $stmt) { + if (! $stmt instanceof EnumCase) { + continue; + } + + $constValue = $this->createConstValue($stmt); + + $classConsts[] = new ClassConst([new Const_($stmt->name, $constValue)], Visibility::PUBLIC); + } + + $class = new Class_($shortClassName, [ + 'stmts' => $classConsts, + ]); + + $class->namespacedName = $enum->namespacedName; + + return $class; + } + + private function createConstValue(EnumCase $enumCase): Expr + { + if ($enumCase->expr instanceof Expr) { + return $enumCase->expr; + } + + /** @var string $enumName */ + $enumName = $this->nodeNameResolver->getName($enumCase); + + // minimal convention + $lowercasedEnumValue = strtolower($enumName); + + return new String_($lowercasedEnumValue); + } +}