diff --git a/CHANGELOG.md b/CHANGELOG.md index 48bea85..7f6db4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## 6.12.2 + +### Changed + +- Simplify implementation of `Enum::fromKey` to native enum with dynamic class const fetch + ## 6.12.1 ### Fixed diff --git a/Makefile b/Makefile index a127196..a721bc9 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,9 @@ it: fix stan test docs ## Run the commonly used targets help: ## Displays this list of targets with descriptions @grep --extended-regexp '^[a-zA-Z0-9_-]+:.*?## .*$$' $(firstword $(MAKEFILE_LIST)) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' +.PHONY: setup +setup: vendor ## Set up the project + .PHONY: fix fix: vendor ## Apply automatic code fixes # TODO fix PHP Fatal error: Class PhpCsFixer\Fixer\Operator\AssignNullCoalescingToCoalesceEqualFixer contains 4 abstract methods and must therefore be declared abstract or implement the remaining methods (PhpCsFixer\Fixer\FixerInterface::isRisky, PhpCsFixer\Fixer\FixerInterface::fix, PhpCsFixer\Fixer\FixerInterface::getName, ...) in /home/bfranke/projects/laravel-enum/vendor/friendsofphp/php-cs-fixer/src/Fixer/Operator/AssignNullCoalescingToCoalesceEqualFixer.php on line 24 @@ -24,5 +27,5 @@ docs: ## Generate documentation vendor: composer.json composer validate --strict - composer install + composer update composer normalize diff --git a/composer.json b/composer.json index fab8562..320700f 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,7 @@ "phpstan/phpstan": "^1.12.19 || ^2.1.6", "phpstan/phpstan-mockery": "^1.1.3 || ^2", "phpstan/phpstan-phpunit": "^1.4.2 || ^2.0.4", - "phpunit/phpunit": "^9.5.21 || ^10.5.45 || ^11.5.10 || ^12.0.5", + "phpunit/phpunit": "^9.5.21 || ^10.5.45 || ^11.5.10", "rector/rector": "^1.2.10 || ^2.0.9", "symplify/rule-doc-generator": "^11.2 || ^12.2.5" }, diff --git a/src/Rector/ToNativeUsagesRector.php b/src/Rector/ToNativeUsagesRector.php index f99a7a5..d1ba80a 100644 --- a/src/Rector/ToNativeUsagesRector.php +++ b/src/Rector/ToNativeUsagesRector.php @@ -277,6 +277,10 @@ protected function refactorFromKey(StaticCall $call): ?Node $class = $call->class; if ($class instanceof Name) { $makeFromKey = function (Expr $key) use ($class): Expr { + if (version_compare(PHP_VERSION, '8.3.0', '>=')) { + return $this->createEnumCaseAccess($class, $key); + } + $paramName = lcfirst($class->getLast()); $paramVariable = new Variable($paramName); @@ -1061,11 +1065,11 @@ protected function refactorArrowFunction(ArrowFunction $arrowFunction): ?ArrowFu return null; } - protected function createEnumCaseAccess(Name $class, string $constName): ClassConstFetch + protected function createEnumCaseAccess(Name $class, Expr|string $name): ClassConstFetch { return new ClassConstFetch( $class, - $constName, + $name, [self::CONVERTED_INSTANTIATION => true], ); } diff --git a/tests/Rector/ToNativeImplementationRectorTest.php b/tests/Rector/ToNativeImplementationRectorTest.php index 942bd6a..f24a1b3 100644 --- a/tests/Rector/ToNativeImplementationRectorTest.php +++ b/tests/Rector/ToNativeImplementationRectorTest.php @@ -15,7 +15,7 @@ public function test(string $filePath): void $this->doTestFile($filePath); } - /** @return iterable */ + /** @return iterable */ public static function provideData(): iterable { return self::yieldFilesFromDirectory(__DIR__ . '/Implementation'); diff --git a/tests/Rector/ToNativeUsagesRectorTest.php b/tests/Rector/ToNativeUsagesRectorTest.php index fdfda94..9a47eb6 100644 --- a/tests/Rector/ToNativeUsagesRectorTest.php +++ b/tests/Rector/ToNativeUsagesRectorTest.php @@ -15,10 +15,25 @@ public function test(string $filePath): void $this->doTestFile($filePath); } - /** @return iterable */ + /** @return iterable */ public static function provideData(): iterable { - return self::yieldFilesFromDirectory(__DIR__ . '/Usages'); + foreach (self::yieldFilesFromDirectory(__DIR__ . '/Usages') as $fileArray) { + [$file] = $fileArray; + + // See https://wiki.php.net/rfc/dynamic_class_constant_fetch + if (version_compare(PHP_VERSION, '8.3.0', '<')) { + if ($file === __DIR__ . '/Usages/fromKey.dynamic_class_constant_fetch.php.inc') { + continue; + } + } else { + if ($file === __DIR__ . '/Usages/fromKey.php.inc') { + continue; + } + } + + yield $fileArray; + } } public function provideConfigFilePath(): string diff --git a/tests/Rector/Usages/fromKey.dynamic_class_constant_fetch.php.inc b/tests/Rector/Usages/fromKey.dynamic_class_constant_fetch.php.inc new file mode 100644 index 0000000..40c52e6 --- /dev/null +++ b/tests/Rector/Usages/fromKey.dynamic_class_constant_fetch.php.inc @@ -0,0 +1,15 @@ + UserType::{$key}; diff --git a/tests/Rector/Usages/fromKey.php.inc b/tests/Rector/Usages/fromKey.php.inc index 8c7e11f..7cd350d 100644 --- a/tests/Rector/Usages/fromKey.php.inc +++ b/tests/Rector/Usages/fromKey.php.inc @@ -3,6 +3,7 @@ use BenSampo\Enum\Tests\Enums\UserType; UserType::fromKey('foo'); +UserType::fromKey($key); UserType::fromKey(...); ----- $userType->name === 'foo')); +Illuminate\Support\Arr::first(array_filter(UserType::cases(), fn(UserType $userType): bool => $userType->name === $key)); static fn(string $key): UserType => Illuminate\Support\Arr::first(array_filter(UserType::cases(), fn(UserType $userType): bool => $userType->name === $key));