[CodingStyle] Handle ClassConstFetch on RemoveUnusedAliasRector (#785)

* [CodingStyle] Handle CClassConstFetch on RemoveUnusedAliasRector

* add conflict fixture

* eol

* add FullyQualifiedFromUseFinder

* [ci-review] Rector Rectify

* final touch: match -> matchAlias naming method

* final touch: matchAlias -> matchAliasNamespace naming method

Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Abdul Malik Ikhsan 2021-08-29 18:47:29 +07:00 committed by GitHub
parent dd49d3874b
commit 13bf954089
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 130 additions and 40 deletions

View File

@ -551,4 +551,4 @@ parameters:
paths:
- rules/Php74/Rector/LNumber/AddLiteralSeparatorToNumberRector.php
- '#^Cognitive complexity for "Rector\\CodingStyle\\Naming\\NameRenamer\:\:renameNameNode\(\)" is 12, keep it under 9$#'
- '#^Cognitive complexity for "Rector\\CodingStyle\\Naming\\NameRenamer\:\:renameNameNode\(\)" is 13, keep it under 9$#'

View File

@ -0,0 +1,23 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
use App\Bar as BarAlias;
use App\Foo\Bar;
use App\NoAlias;
class SkipHasConflictClassConstant
{
private $classMap = [
BarAlias::class => 'bar',
NoAlias::class => 'noalias',
];
public function run()
{
Bar::execute();
Bar::DATA;
}
}
?>

View File

@ -1,12 +0,0 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
use App\Bar as BarAlias;
class SkipUsedInClassConstant
{
private $classMap = [
BarAlias::class => 'bar',
];
}

View File

@ -0,0 +1,45 @@
<?php
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
use App\Bar as BarAlias;
use App\NoAlias;
class UsedInClassConstant
{
private $classMap = [
BarAlias::class => 'bar',
NoAlias::class => 'noalias',
];
public function run()
{
BarAlias::execute();
BarAlias::DATA;
}
}
?>
-----
<?php
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
use App\Bar;
use App\NoAlias;
class UsedInClassConstant
{
private $classMap = [
Bar::class => 'bar',
NoAlias::class => 'noalias',
];
public function run()
{
Bar::execute();
Bar::DATA;
}
}
?>

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Rector\CodingStyle\Naming;
use PhpParser\Node;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Expr\Instanceof_;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\StaticCall;
@ -75,9 +76,26 @@ final class NameRenamer
if ($parentNode instanceof Instanceof_) {
$this->renameInInstanceOf($lastName, $parentNode, $usedName);
}
if ($parentNode instanceof ClassConstFetch) {
$this->renameClassConstFetch($lastName, $parentNode, $usedName);
}
}
}
private function renameClassConstFetch(
string $lastName,
ClassConstFetch $classConstFetch,
Name | Identifier $usedNameNode
): void
{
if (! $this->nodeNameResolver->areNamesEqual($classConstFetch->class, $usedNameNode)) {
return;
}
$classConstFetch->class = new Name($lastName);
}
private function renameInInstanceOf(
string $lastName,
Instanceof_ $instanceof,

View File

@ -4,11 +4,8 @@ declare(strict_types=1);
namespace Rector\CodingStyle\Rector\Use_;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\Node\Stmt\Use_;
use PhpParser\Node\Stmt\UseUse;
@ -18,6 +15,7 @@ use Rector\CodingStyle\Node\DocAliasResolver;
use Rector\CodingStyle\Node\UseManipulator;
use Rector\CodingStyle\Node\UseNameAliasToNameResolver;
use Rector\CodingStyle\ValueObject\NameAndParent;
use Rector\Core\PhpParser\NodeFinder\FullyQualifiedFromUseFinder;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@ -48,7 +46,8 @@ final class RemoveUnusedAliasRector extends AbstractRector
private UseManipulator $useManipulator,
private UseNameAliasToNameResolver $useNameAliasToNameResolver,
private NameRenamer $nameRenamer,
private ClassNameImportSkipper $classNameImportSkipper
private ClassNameImportSkipper $classNameImportSkipper,
private FullyQualifiedFromUseFinder $fullyQualifiedFromUseFinder
) {
}
@ -183,29 +182,7 @@ CODE_SAMPLE
return true;
}
return (bool) $this->betterNodeFinder->findFirstNext($use, function (Node $node) use (
$name,
$loweredAliasName
): bool {
if ($node instanceof FullyQualified) {
$originalName = $node->getAttribute(AttributeKey::ORIGINAL_NAME);
if ($originalName instanceof Name) {
$loweredOriginalName = strtolower($originalName->toString());
$loweredOriginalNameNamespace = Strings::before($loweredOriginalName, '\\');
return $loweredAliasName === $loweredOriginalNameNamespace;
}
}
if (! $node instanceof ClassConstFetch) {
return false;
}
if (! $node->class instanceof Name) {
return false;
}
return $node->class->toString() === $name->toString();
});
return (bool) $this->fullyQualifiedFromUseFinder->matchAliasNamespace($use, $loweredAliasName);
}
private function refactorAliasName(Use_ $use, string $aliasName, string $lastName, UseUse $useUse): void

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Rector\Core\PhpParser\NodeFinder;
use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Use_;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class FullyQualifiedFromUseFinder
{
public function __construct(
private BetterNodeFinder $betterNodeFinder
) {
}
public function matchAliasNamespace(Use_ $use, string $loweredAliasName): ?Node
{
return $this->betterNodeFinder->findFirstNext($use, function (Node $node) use ($loweredAliasName): bool {
if (! $node instanceof FullyQualified) {
return false;
}
$originalName = $node->getAttribute(AttributeKey::ORIGINAL_NAME);
if (! $originalName instanceof Name) {
return false;
}
$loweredOriginalName = strtolower($originalName->toString());
$loweredOriginalNameNamespace = Strings::before($loweredOriginalName, '\\');
return $loweredAliasName === $loweredOriginalNameNamespace;
});
}
}