Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PHP 8.1] Extend MyCLabsMethodCallToEnumConstRector with getValue() and static call #2695

Merged
merged 2 commits into from
Jul 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Fixture;

use Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Source\SomeEnum;

final class SkipMagicCalls
{
public function run($value, $magicMethod)
{
$compare = SomeEnum::$magicMethod();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Fixture;

use Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Source\SomeEnum;

final class StaticMethodCall
{
public function run($value)
{
$compare = SomeEnum::USED_TO_BE_CONST();
}
}

?>
-----
<?php

namespace Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Fixture;

use Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Source\SomeEnum;

final class StaticMethodCall
{
public function run($value)
{
$compare = \Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Source\SomeEnum::USED_TO_BE_CONST;
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class UsageOfConstant
{
public function run($value)
{
$compare = \Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Source\SomeEnum::VALUE;
$compare = \Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Source\SomeEnum::VALUE->getKey();
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Fixture;

use Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Source\SomeEnum;

final class UsageOfConstantValue
{
public function run($value)
{
$compare = SomeEnum::VALUE()->getValue();
}
}

?>
-----
<?php

namespace Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Fixture;

use Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Source\SomeEnum;

final class UsageOfConstantValue
{
public function run($value)
{
$compare = \Rector\Tests\Php81\Rector\MethodCall\MyCLabsMethodCallToEnumConstRector\Source\SomeEnum::VALUE->getValue();
}
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
use MyCLabs\Enum\Enum;

/**
* @method SomeEnum VALUE()
* @method SomeEnum USED_TO_BE_CONST()
*/
final class SomeEnum extends Enum
{
const VALUE = 'value';
const USED_TO_BE_CONST = 'value';
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
namespace Rector\Php81\Rector\MethodCall;

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
Expand Down Expand Up @@ -43,27 +46,51 @@ public function getRuleDefinition(): RuleDefinition
*/
public function getNodeTypes(): array
{
return [MethodCall::class];
return [MethodCall::class, StaticCall::class];
}

/**
* @param MethodCall $node
* @param MethodCall|StaticCall $node
*/
public function refactor(Node $node): ?Node
{
if (! $this->isObjectType($node->var, new ObjectType('MyCLabs\Enum\Enum'))) {
if ($node->name instanceof Expr) {
return null;
}

if (! $this->isName($node->name, 'getKey')) {
$enumCaseName = $this->getName($node->name);
if ($enumCaseName === null) {
return null;
}

if ($node instanceof MethodCall) {
return $this->refactorMethodCall($node, $enumCaseName);
}

if (! $this->isObjectType($node->class, new ObjectType('MyCLabs\Enum\Enum'))) {
return null;
}

if (! $node->var instanceof StaticCall) {
$className = $this->getName($node->class);
if (! is_string($className)) {
return null;
}

return $this->nodeFactory->createClassConstFetch($className, $enumCaseName);
}

public function provideMinPhpVersion(): int
{
return PhpVersionFeature::ENUM;
}

private function refactorGetKeyMethodCall(MethodCall $methodCall): ?ClassConstFetch
{
if (! $methodCall->var instanceof StaticCall) {
return null;
}

$staticCall = $node->var;
$staticCall = $methodCall->var;
$className = $this->getName($staticCall->class);
if ($className === null) {
return null;
Expand All @@ -77,8 +104,42 @@ public function refactor(Node $node): ?Node
return $this->nodeFactory->createClassConstFetch($className, $enumCaseName);
}

public function provideMinPhpVersion(): int
private function refactorGetValueMethodCall(MethodCall $methodCall): ?PropertyFetch
{
return PhpVersionFeature::ENUM;
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;
}

$enumConstFetch = $this->nodeFactory->createClassConstFetch($className, $enumCaseName);

return new PropertyFetch($enumConstFetch, 'value');
}

private function refactorMethodCall(MethodCall $methodCall, string $methodName): null|ClassConstFetch|PropertyFetch
{
if (! $this->isObjectType($methodCall->var, new ObjectType('MyCLabs\Enum\Enum'))) {
return null;
}

if ($methodName === 'getKey') {
return $this->refactorGetKeyMethodCall($methodCall);
}

if ($methodName === 'getValue') {
return $this->refactorGetValueMethodCall($methodCall);
}

return null;
}
}