-
-
Notifications
You must be signed in to change notification settings - Fork 333
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactors Spatie enum method calls to native enums (#3226)
Co-authored-by: jools <julien.dephix.nagoya@accopilot.com>
- Loading branch information
1 parent
ac2f853
commit 384e84a
Showing
9 changed files
with
327 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
...ll/SpatieEnumMethodCallToEnumConstRector/Fixture/name_or_getName_to_name_property.php.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
namespace Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Fixture; | ||
|
||
use \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector; | ||
|
||
final class NameOrGetNameToNameProperty | ||
{ | ||
public function run($value) | ||
{ | ||
$archivedName = \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::archived()->getName(); | ||
$draftName = SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::draft()->name; | ||
} | ||
} | ||
|
||
?> | ||
----- | ||
<?php | ||
|
||
namespace Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Fixture; | ||
|
||
use \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector; | ||
|
||
final class NameOrGetNameToNameProperty | ||
{ | ||
public function run($value) | ||
{ | ||
$archivedName = \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::ARCHIVED->name; | ||
$draftName = \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::DRAFT->name; | ||
} | ||
} | ||
|
||
?> |
33 changes: 33 additions & 0 deletions
33
...atieEnumMethodCallToEnumConstRector/Fixture/static_method_call_to_static_property.php.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
namespace Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Fixture; | ||
|
||
use \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector; | ||
|
||
final class StaticMethodCallToStaticProperty | ||
{ | ||
public function run($value) | ||
{ | ||
$archived = \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::archived(); | ||
$published = SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::published(); | ||
} | ||
} | ||
|
||
?> | ||
----- | ||
<?php | ||
|
||
namespace Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Fixture; | ||
|
||
use \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector; | ||
|
||
final class StaticMethodCallToStaticProperty | ||
{ | ||
public function run($value) | ||
{ | ||
$archived = \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::ARCHIVED; | ||
$published = \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::PUBLISHED; | ||
} | ||
} | ||
|
||
?> |
33 changes: 33 additions & 0 deletions
33
...SpatieEnumMethodCallToEnumConstRector/Fixture/value_or_getValue_to_value_property.php.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
namespace Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Fixture; | ||
|
||
use \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector; | ||
|
||
final class ValueOrGetValueToValueProperty | ||
{ | ||
public function run($value) | ||
{ | ||
$archivedName = \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::archived()->getValue(); | ||
$draftName = SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::draft()->value; | ||
} | ||
} | ||
|
||
?> | ||
----- | ||
<?php | ||
|
||
namespace Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Fixture; | ||
|
||
use \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector; | ||
|
||
final class ValueOrGetValueToValueProperty | ||
{ | ||
public function run($value) | ||
{ | ||
$archivedName = \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::ARCHIVED->value; | ||
$draftName = \Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Source\StatusEnum::DRAFT->value; | ||
} | ||
} | ||
|
||
?> |
16 changes: 16 additions & 0 deletions
16
...tests/Php81/Rector/MethodCall/SpatieEnumMethodCallToEnumConstRector/Source/StatusEnum.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector\Source; | ||
|
||
use Spatie\Enum\Enum; | ||
|
||
/** | ||
* @method static self draft() | ||
* @method static self published() | ||
* @method static self archived() | ||
*/ | ||
class StatusEnum extends Enum | ||
{ | ||
} |
29 changes: 29 additions & 0 deletions
29
...dCall/SpatieEnumMethodCallToEnumConstRector/SpatieEnumMethodCallToEnumConstRectorTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Tests\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector; | ||
|
||
use Iterator; | ||
use Rector\Testing\PHPUnit\AbstractRectorTestCase; | ||
|
||
final class SpatieEnumMethodCallToEnumConstRectorTest extends AbstractRectorTestCase | ||
{ | ||
/** | ||
* @dataProvider provideData() | ||
*/ | ||
public function test(string $filePath): void | ||
{ | ||
$this->doTestFile($filePath); | ||
} | ||
|
||
public function provideData(): Iterator | ||
{ | ||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); | ||
} | ||
|
||
public function provideConfigFilePath(): string | ||
{ | ||
return __DIR__ . '/config/configured_rule.php'; | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
.../Php81/Rector/MethodCall/SpatieEnumMethodCallToEnumConstRector/config/configured_rule.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
use Rector\Config\RectorConfig; | ||
use Rector\Php81\Rector\MethodCall\SpatieEnumMethodCallToEnumConstRector; | ||
|
||
return static function (RectorConfig $rectorConfig): void { | ||
$rectorConfig->rule(SpatieEnumMethodCallToEnumConstRector::class); | ||
}; |
151 changes: 151 additions & 0 deletions
151
rules/Php81/Rector/MethodCall/SpatieEnumMethodCallToEnumConstRector.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Rector\Php81\Rector\MethodCall; | ||
|
||
use PhpParser\Node; | ||
use PhpParser\Node\Expr; | ||
use PhpParser\Node\Expr\MethodCall; | ||
use PhpParser\Node\Expr\PropertyFetch; | ||
use PhpParser\Node\Expr\StaticCall; | ||
use PHPStan\Type\ObjectType; | ||
use Rector\Core\Rector\AbstractRector; | ||
use Rector\Core\ValueObject\PhpVersionFeature; | ||
use Rector\VersionBonding\Contract\MinPhpVersionInterface; | ||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; | ||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; | ||
|
||
/** | ||
* @changelog https://wiki.php.net/rfc/enumerations | ||
* | ||
* @see \Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\MyCLabsMethodCallToEnumConstRectorTest | ||
*/ | ||
final class SpatieEnumMethodCallToEnumConstRector extends AbstractRector implements MinPhpVersionInterface | ||
{ | ||
private const SPATIE_FQN = 'Spatie\Enum\Enum'; | ||
|
||
/** | ||
* @var string[] | ||
*/ | ||
private const ENUM_METHODS = ['from', 'values', 'keys', 'isValid', 'search', 'toArray', 'assertValidValue']; | ||
|
||
public function getRuleDefinition(): RuleDefinition | ||
{ | ||
return new RuleDefinition('Refactor Spatie enum method calls', [ | ||
new CodeSample( | ||
<<<'CODE_SAMPLE' | ||
$value1 = SomeEnum::SOME_CONSTANT()->getValue(); | ||
$value2 = SomeEnum::SOME_CONSTANT()->value; | ||
$name1 = SomeEnum::SOME_CONSTANT()->getName(); | ||
$name2 = SomeEnum::SOME_CONSTANT()->name; | ||
CODE_SAMPLE | ||
, | ||
<<<'CODE_SAMPLE' | ||
$value1 = SomeEnum::SOME_CONSTANT->value; | ||
$value2 = SomeEnum::SOME_CONSTANT->value; | ||
$name1 = SomeEnum::SOME_CONSTANT->name; | ||
$name2 = SomeEnum::SOME_CONSTANT->name; | ||
CODE_SAMPLE | ||
), | ||
]); | ||
} | ||
|
||
/** | ||
* @return array<class-string<Node>> | ||
*/ | ||
public function getNodeTypes(): array | ||
{ | ||
return [MethodCall::class, StaticCall::class]; | ||
} | ||
|
||
/** | ||
* @param MethodCall|StaticCall $node | ||
*/ | ||
public function refactor(Node $node): ?Node | ||
{ | ||
if ($node->name instanceof Expr) { | ||
return null; | ||
} | ||
|
||
$enumCaseName = $this->getName($node->name); | ||
if ($enumCaseName === null) { | ||
return null; | ||
} | ||
|
||
if ($this->shouldOmitEnumCase($enumCaseName)) { | ||
return null; | ||
} | ||
|
||
if ($node instanceof MethodCall) { | ||
return $this->refactorMethodCall($node, $enumCaseName); | ||
} | ||
|
||
if (! $this->isObjectType($node->class, new ObjectType(self::SPATIE_FQN))) { | ||
return null; | ||
} | ||
|
||
$className = $this->getName($node->class); | ||
if (! is_string($className)) { | ||
return null; | ||
} | ||
|
||
$constantName = strtoupper($enumCaseName); | ||
|
||
return $this->nodeFactory->createClassConstFetch($className, $constantName); | ||
} | ||
|
||
public function provideMinPhpVersion(): int | ||
{ | ||
return PhpVersionFeature::ENUM; | ||
} | ||
|
||
private function refactorGetterToMethodCall(MethodCall $methodCall, string $property): ?PropertyFetch | ||
{ | ||
if (! $methodCall->var instanceof StaticCall) { | ||
return null; | ||
} | ||
|
||
$staticCall = $methodCall->var; | ||
$className = $this->getName($staticCall->class); | ||
if ($className === null) { | ||
return null; | ||
} | ||
|
||
$enumCaseName = $this->getName($staticCall->name); | ||
if ($enumCaseName === null) { | ||
return null; | ||
} | ||
|
||
if ($this->shouldOmitEnumCase($enumCaseName)) { | ||
return null; | ||
} | ||
|
||
$upperCaseName = strtoupper($enumCaseName); | ||
$enumConstFetch = $this->nodeFactory->createClassConstFetch($className, $upperCaseName); | ||
|
||
return new PropertyFetch($enumConstFetch, $property); | ||
} | ||
|
||
private function refactorMethodCall(MethodCall $methodCall, string $methodName): null|PropertyFetch | ||
{ | ||
if (! $this->isObjectType($methodCall->var, new ObjectType(self::SPATIE_FQN))) { | ||
return null; | ||
} | ||
|
||
if ($methodName === 'getName' || $methodName === 'label') { | ||
return $this->refactorGetterToMethodCall($methodCall, 'name'); | ||
} | ||
|
||
if ($methodName === 'getValue' || $methodName === 'value') { | ||
return $this->refactorGetterToMethodCall($methodCall, 'value'); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
private function shouldOmitEnumCase(string $enumCaseName): bool | ||
{ | ||
return in_array($enumCaseName, self::ENUM_METHODS, true); | ||
} | ||
} |