mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-31 00:10:51 +00:00
[CodingStyle] Deprecate RemoveUnusedAliasRector, job rather for coding standard tool and opinonated (#1157)
This commit is contained in:
parent
0c3527ebd8
commit
49aa15dbfb
|
@ -12,7 +12,7 @@
|
|||
|
||||
- [CodeQuality](#codequality) (69)
|
||||
|
||||
- [CodingStyle](#codingstyle) (39)
|
||||
- [CodingStyle](#codingstyle) (38)
|
||||
|
||||
- [Composer](#composer) (6)
|
||||
|
||||
|
@ -76,7 +76,7 @@
|
|||
|
||||
- [Php80](#php80) (17)
|
||||
|
||||
- [Php81](#php81) (5)
|
||||
- [Php81](#php81) (6)
|
||||
|
||||
- [PhpSpecToPHPUnit](#phpspectophpunit) (7)
|
||||
|
||||
|
@ -2352,24 +2352,6 @@ Non-magic PHP object methods cannot start with "__"
|
|||
|
||||
<br>
|
||||
|
||||
### RemoveUnusedAliasRector
|
||||
|
||||
Removes unused use aliases. Keep annotation aliases like "Doctrine\ORM\Mapping as ORM" to keep convention format
|
||||
|
||||
- class: [`Rector\CodingStyle\Rector\Use_\RemoveUnusedAliasRector`](../rules/CodingStyle/Rector/Use_/RemoveUnusedAliasRector.php)
|
||||
|
||||
```diff
|
||||
-use Symfony\Kernel as BaseKernel;
|
||||
+use Symfony\Kernel;
|
||||
|
||||
-class SomeClass extends BaseKernel
|
||||
+class SomeClass extends Kernel
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### ReturnArrayClassMethodToYieldRector
|
||||
|
||||
Turns array return to yield return in specific type and method
|
||||
|
@ -8025,6 +8007,26 @@ Refactor MyCLabs enum fetch to Enum const
|
|||
|
||||
<br>
|
||||
|
||||
### Php81ResourceReturnToObjectRector
|
||||
|
||||
Change `is_resource()` to instanceof Object
|
||||
|
||||
- class: [`Rector\Php81\Rector\FuncCall\Php81ResourceReturnToObjectRector`](../rules/Php81/Rector/FuncCall/Php81ResourceReturnToObjectRector.php)
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$f = finfo_open();
|
||||
- is_resource($f);
|
||||
+ $f instanceof \finfo;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### ReadOnlyPropertyRector
|
||||
|
||||
Decorate read-only property with `readonly` attribute
|
||||
|
|
|
@ -30,7 +30,6 @@ use Rector\CodingStyle\Rector\String_\SplitStringClassConstantToClassConstFetchR
|
|||
use Rector\CodingStyle\Rector\String_\SymplifyQuoteEscapeRector;
|
||||
use Rector\CodingStyle\Rector\Switch_\BinarySwitchToIfElseRector;
|
||||
use Rector\CodingStyle\Rector\Ternary\TernaryConditionVariableAssignmentRector;
|
||||
use Rector\CodingStyle\Rector\Use_\RemoveUnusedAliasRector;
|
||||
use Rector\CodingStyle\Rector\Use_\SeparateMultiUseImportsRector;
|
||||
use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector;
|
||||
use Rector\Transform\Rector\FuncCall\FuncCallToConstFetchRector;
|
||||
|
@ -43,7 +42,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
$services->set(BinarySwitchToIfElseRector::class);
|
||||
$services->set(ConsistentImplodeRector::class);
|
||||
$services->set(TernaryConditionVariableAssignmentRector::class);
|
||||
$services->set(RemoveUnusedAliasRector::class);
|
||||
$services->set(SymplifyQuoteEscapeRector::class);
|
||||
$services->set(SplitGroupedConstantsAndPropertiesRector::class);
|
||||
$services->set(SplitStringClassConstantToClassConstFetchRector::class);
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\NameImporting\NodeAnalyzer\UseAnalyzer\Fixture;
|
||||
|
||||
use Rector\Tests\NameImporting\NodeAnalyzer\UseAnalyzer\Source\FirstUsage;
|
||||
|
||||
final class SomeUses
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return new FirstUsage();
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\NameImporting\NodeAnalyzer\UseAnalyzer\Fixture;
|
||||
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\UnionType as PhpParserUnionType;
|
||||
|
||||
final class UnionAliasImports
|
||||
{
|
||||
public function param(String_ | PhpParserUnionType $node)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\NameImporting\NodeAnalyzer\UseAnalyzer\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractInterface as BaseInterface;
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractKernel as BaseKernel;
|
||||
|
||||
class SomeClass extends BaseKernel implements BaseInterface
|
||||
{
|
||||
public function run(BaseKernel $baseKernel): BaseInterface
|
||||
{
|
||||
$anotherBaseKernel = new BaseKernel();
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\NameImporting\NodeAnalyzer\UseAnalyzer\Source;
|
||||
|
||||
final class FirstUsage
|
||||
{
|
||||
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\NameImporting\NodeAnalyzer\UseAnalyzer;
|
||||
|
||||
use Iterator;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\UseUse;
|
||||
use PhpParser\Node\UnionType;
|
||||
use Rector\NameImporting\NodeAnalyzer\UseAnalyzer;
|
||||
use Rector\NameImporting\ValueObject\NameAndParent;
|
||||
use Rector\Testing\PHPUnit\AbstractTestCase;
|
||||
use Rector\Testing\TestingParser\TestingParser;
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractKernel;
|
||||
use Rector\Tests\NameImporting\NodeAnalyzer\UseAnalyzer\Source\FirstUsage;
|
||||
|
||||
final class UseAnalyzerTest extends AbstractTestCase
|
||||
{
|
||||
private UseAnalyzer $useAnalyzer;
|
||||
|
||||
private TestingParser $testingParser;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->boot();
|
||||
|
||||
$this->useAnalyzer = $this->getService(UseAnalyzer::class);
|
||||
$this->testingParser = $this->getService(TestingParser::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*
|
||||
* @param class-string<Node> $parentNodeType
|
||||
* @param Identifier|FullyQualified $expectedNameNode
|
||||
*/
|
||||
public function test(
|
||||
string $filePath,
|
||||
string $expectedShortName,
|
||||
int $position,
|
||||
Name|Identifier $expectedNameNode,
|
||||
string $parentNodeType
|
||||
): void {
|
||||
$file = $this->testingParser->parseFilePathToFile($filePath);
|
||||
$firstStmt = $file->getOldStmts()[1];
|
||||
|
||||
$namesAndParents = $this->useAnalyzer->resolveUsedNameNodes($firstStmt);
|
||||
|
||||
$this->assertArrayHasKey($position, $namesAndParents);
|
||||
$nameAndParent = $namesAndParents[$position];
|
||||
$this->assertInstanceOf(NameAndParent::class, $nameAndParent);
|
||||
|
||||
$this->assertTrue($nameAndParent->matchShortName($expectedShortName));
|
||||
|
||||
// remove attributes for compare
|
||||
$nameNode = $nameAndParent->getNameNode();
|
||||
$nameNode->setAttributes([]);
|
||||
|
||||
$this->assertEquals($expectedNameNode, $nameNode);
|
||||
$this->assertInstanceOf($parentNodeType, $nameAndParent->getParentNode());
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
yield [
|
||||
__DIR__ . '/Fixture/some_uses.php.inc',
|
||||
'FirstUsage',
|
||||
0,
|
||||
new FullyQualified(FirstUsage::class),
|
||||
New_::class,
|
||||
];
|
||||
|
||||
yield [__DIR__ . '/Fixture/some_uses.php.inc', 'SomeUses', 1, new Identifier('SomeUses'), Class_::class];
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Fixture/use_import.php.inc',
|
||||
'BaseKernel',
|
||||
4,
|
||||
new FullyQualified(AbstractKernel::class),
|
||||
New_::class,
|
||||
];
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Fixture/use_import.php.inc',
|
||||
'BaseInterface',
|
||||
6,
|
||||
new Identifier('BaseInterface'),
|
||||
UseUse::class,
|
||||
];
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Fixture/use_import.php.inc',
|
||||
'BaseKernel',
|
||||
7,
|
||||
new Identifier('BaseKernel'),
|
||||
UseUse::class,
|
||||
];
|
||||
|
||||
yield [__DIR__ . '/Fixture/use_import.php.inc', 'SomeClass', 5, new Identifier('SomeClass'), Class_::class];
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Fixture/union_alias_imports.php.inc',
|
||||
'String_',
|
||||
0,
|
||||
new FullyQualified(String_::class),
|
||||
UnionType::class,
|
||||
];
|
||||
|
||||
yield [
|
||||
__DIR__ . '/Fixture/union_alias_imports.php.inc',
|
||||
'PhpParserUnionType',
|
||||
3,
|
||||
new Identifier('PhpParserUnionType'),
|
||||
UseUse::class,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,119 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NameImporting\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\UseUse;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\NameImporting\ValueObject\NameAndParent;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\NameImporting\NodeAnalyzer\UseAnalyzer\UseAnalyzerTest
|
||||
*/
|
||||
final class UseAnalyzer
|
||||
{
|
||||
public function __construct(
|
||||
private BetterNodeFinder $betterNodeFinder,
|
||||
private NodeNameResolver $nodeNameResolver
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NameAndParent[]
|
||||
*/
|
||||
public function resolveUsedNameNodes(Node $node): array
|
||||
{
|
||||
$usedNames = $this->resolveUsedNames($node);
|
||||
$usedClassNames = $this->resolveUsedClassNames($node);
|
||||
$usedTraitNames = $this->resolveTraitUseNames($node);
|
||||
|
||||
return array_merge($usedNames, $usedClassNames, $usedTraitNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NameAndParent[]
|
||||
*/
|
||||
private function resolveUsedNames(Node $node): array
|
||||
{
|
||||
$namesAndParents = [];
|
||||
|
||||
/** @var Name[] $names */
|
||||
$names = $this->betterNodeFinder->findInstanceOf($node, Name::class);
|
||||
|
||||
foreach ($names as $name) {
|
||||
/** node name before becoming FQN - attribute from @see NameResolver */
|
||||
$originalName = $name->getAttribute(AttributeKey::ORIGINAL_NAME);
|
||||
if (! $originalName instanceof Name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parentNode = $name->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parentNode instanceof Node) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$shortName = $originalName->toString();
|
||||
$namesAndParents[] = new NameAndParent($shortName, $name, $parentNode);
|
||||
}
|
||||
|
||||
return $namesAndParents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NameAndParent[]
|
||||
*/
|
||||
private function resolveUsedClassNames(Node $node): array
|
||||
{
|
||||
$namesAndParents = [];
|
||||
|
||||
/** @var ClassLike[] $classLikes */
|
||||
$classLikes = $this->betterNodeFinder->findClassLikes($node);
|
||||
|
||||
foreach ($classLikes as $classLike) {
|
||||
$classLikeName = $classLike->name;
|
||||
if (! $classLikeName instanceof Identifier) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = $this->nodeNameResolver->getName($classLikeName);
|
||||
if (! is_string($name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$namesAndParents[] = new NameAndParent($name, $classLikeName, $classLike);
|
||||
}
|
||||
|
||||
return $namesAndParents;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NameAndParent[]
|
||||
*/
|
||||
private function resolveTraitUseNames(Node $node): array
|
||||
{
|
||||
$namesAndParents = [];
|
||||
|
||||
/** @var Identifier[] $identifiers */
|
||||
$identifiers = $this->betterNodeFinder->findInstanceOf($node, Identifier::class);
|
||||
|
||||
foreach ($identifiers as $identifier) {
|
||||
$parentNode = $identifier->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parentNode instanceof UseUse) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$shortName = $identifier->name;
|
||||
$namesAndParents[] = new NameAndParent($shortName, $identifier, $parentNode);
|
||||
}
|
||||
|
||||
return $namesAndParents;
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\NameImporting\ValueObject;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
|
||||
final class NameAndParent
|
||||
{
|
||||
/**
|
||||
* @param Name|Identifier $nameNode
|
||||
*/
|
||||
public function __construct(
|
||||
private string $shortName,
|
||||
private Node $nameNode,
|
||||
private Node $parentNode
|
||||
) {
|
||||
}
|
||||
|
||||
public function getNameNode(): Identifier | Name
|
||||
{
|
||||
return $this->nameNode;
|
||||
}
|
||||
|
||||
public function getParentNode(): Node
|
||||
{
|
||||
return $this->parentNode;
|
||||
}
|
||||
|
||||
public function matchShortName(string $desiredShortName): bool
|
||||
{
|
||||
return strtolower($this->shortName) === strtolower($desiredShortName);
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractInterface as BaseInterface;
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractKernel as BaseKernel;
|
||||
|
||||
|
||||
class SomeClass extends BaseKernel implements BaseInterface
|
||||
{
|
||||
public function run(BaseKernel $baseKernel): BaseInterface
|
||||
{
|
||||
$anotherBaseKernel = new BaseKernel();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractInterface;
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractKernel;
|
||||
|
||||
|
||||
class SomeClass extends AbstractKernel implements AbstractInterface
|
||||
{
|
||||
public function run(AbstractKernel $baseKernel): AbstractInterface
|
||||
{
|
||||
$anotherBaseKernel = new AbstractKernel();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AliasedStaticCall as CallOnMe;
|
||||
|
||||
class HandleStaticCall
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
CallOnMe::someCall();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AliasedStaticCall;
|
||||
|
||||
class HandleStaticCall
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
AliasedStaticCall::someCall();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,23 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractInterface as NotNeededAliasInterface;
|
||||
|
||||
interface BasicInterface extends NotNeededAliasInterface
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractInterface;
|
||||
|
||||
interface BasicInterface extends AbstractInterface
|
||||
{
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Nette\Utils\Finder as NetteFinder;
|
||||
use Symfony\Component\Finder\Finder as SymfonyFinder;
|
||||
|
||||
final class KeepNetteSymfonyFinder
|
||||
{
|
||||
public function nette()
|
||||
{
|
||||
return new NetteFinder();
|
||||
}
|
||||
|
||||
public function symfony()
|
||||
{
|
||||
return new SymfonyFinder();
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use SplFileInfo as NativeSplFileInfo;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
|
||||
final class KeepUsedDocParam
|
||||
{
|
||||
/**
|
||||
* @param SplFileInfo $type
|
||||
*/
|
||||
public function run($type): void
|
||||
{
|
||||
$splFileInfo = new NativeSplFileInfo('tests/Posts/Year2018/Exceptions/Source/some_file.txt');
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use SplFileInfo as NativeSplFileInfo;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
|
||||
final class KeepUsedSplFileInfo
|
||||
{
|
||||
public function testSplFileInfo(): void
|
||||
{
|
||||
$splFileInfo = new NativeSplFileInfo('tests/Posts/Year2018/Exceptions/Source/some_file.txt');
|
||||
|
||||
/** @var SplFileInfo $file */
|
||||
$file = array_pop($files);
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractKernel as BaseKernel;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run(?BaseKernel $baseKernel)
|
||||
{
|
||||
$anotherBaseKernel = $baseKernel ?? new BaseKernel();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractKernel;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run(?AbstractKernel $baseKernel)
|
||||
{
|
||||
$anotherBaseKernel = $baseKernel ?? new AbstractKernel();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\DifferentNamespace as Foo;
|
||||
|
||||
class SkipAliasAsUsedNamespace
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$foo = new Foo\StandaloneClass();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\StandaloneClass as BaseKernel;
|
||||
|
||||
class StandaloneClass extends BaseKernel
|
||||
{
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use \Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\StandaloneClass as FirstStandalone;
|
||||
use \Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\DifferentNamespace\StandaloneClass as SecondStandalone;
|
||||
|
||||
class DifferentNamespacesSameClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$firstStandalone = new FirstStandalone;
|
||||
$secondStandalone = new SecondStandalone;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use PhpParser\Node\Const_;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Const_ as ConstStmt;
|
||||
|
||||
$consts = [new Const_('CONSTANT_IN_CLASS', new String_('default value'))];
|
||||
|
||||
return new ConstStmt($consts);
|
|
@ -1,9 +0,0 @@
|
|||
<?php
|
||||
|
||||
use PhpParser\Node\Const_;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Const_ as ConstStmt;
|
||||
|
||||
$consts = [new Const_('CONSTANT_IN_CLASS', new String_('default value'))];
|
||||
|
||||
return new ConstStmt($consts);
|
|
@ -1,13 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\Mapping as ORM;
|
||||
|
||||
class SkipDocBlock
|
||||
{
|
||||
/**
|
||||
* @ORM\Id
|
||||
*/
|
||||
protected $id;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use DateTime as PhpDateTime;
|
||||
use DateTimeImmutable as PhpDateTimeImmutable;
|
||||
|
||||
class SkipDocBlockUniontype
|
||||
{
|
||||
/**
|
||||
* @var PhpDateTime|bool
|
||||
*/
|
||||
protected $b;
|
||||
|
||||
/**
|
||||
* @var PhpDateTimeImmutable
|
||||
*/
|
||||
protected $a;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Nette\Utils\FileSystem as NetteFileSystem;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symplify\ConsoleColorDiff\Console\Output\ConsoleDiffer;
|
||||
|
||||
final class SkipNetteSymfonyFilesystemAlias
|
||||
{
|
||||
/**
|
||||
* @var Filesystem
|
||||
*/
|
||||
private $filesystem;
|
||||
|
||||
public function __construct(Filesystem $filesystem, ConsoleDiffer $consoleDiffer)
|
||||
{
|
||||
$this->filesystem = $filesystem;
|
||||
}
|
||||
|
||||
public function fixComposerJson(string $composerJsonFile): void
|
||||
{
|
||||
$fileContent = NetteFileSystem::read($composerJsonFile);
|
||||
$this->filesystem->dumpFile($composerJsonFile, '...');
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\StandaloneClass as BaseKernel;
|
||||
|
||||
class StandaloneClass extends BaseKernel
|
||||
{
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\StandaloneClass;
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\DifferentNamespace\StandaloneClass as StandaloneClassDifferentNamespace;
|
||||
|
||||
class SkipSameClassInUseStatementNotUsed
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return new StandaloneClassDifferentNamespace();
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\StandaloneTrait as DuplicatedStandaloneTrait;
|
||||
|
||||
trait StandaloneTrait
|
||||
{
|
||||
use DuplicatedStandaloneTrait;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractKernel as BaseKernel;
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\Another\AbstractKernel;
|
||||
|
||||
class SkipUsed extends BaseKernel
|
||||
{
|
||||
public function run(BaseKernel $baseKernel, AbstractKernel $abstractKernel)
|
||||
{
|
||||
$anotherBaseKernel = new BaseKernel();
|
||||
$anotherAbstractKernel = new AbstractKernel();
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
use Vich\UploaderBundle\Mapping\Annotation as Vich;
|
||||
|
||||
/**
|
||||
* @ORM\Table()
|
||||
* @ORM\Entity()
|
||||
* @UniqueEntity("slug")
|
||||
* @Vich\Uploadable
|
||||
*/
|
||||
class Entity
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*
|
||||
* @ORM\Column(name="slug", type="string", length=50, unique=true)
|
||||
* @Assert\NotBlank()
|
||||
* @Assert\Length(max="50")
|
||||
*/
|
||||
private $slug;
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractKernel as BaseKernel;
|
||||
|
||||
class UnderInstanceOf
|
||||
{
|
||||
public function run(?BaseKernel $baseKernel)
|
||||
{
|
||||
if ($baseKernel instanceof BaseKernel) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\AbstractKernel;
|
||||
|
||||
class UnderInstanceOf
|
||||
{
|
||||
public function run(?AbstractKernel $baseKernel)
|
||||
{
|
||||
if ($baseKernel instanceof AbstractKernel) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,27 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\ClassicTrait;
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\StandaloneTrait as DuplicatedStandaloneTrait;
|
||||
|
||||
trait UnneededStandaloneTrait
|
||||
{
|
||||
use ClassicTrait, DuplicatedStandaloneTrait;
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\ClassicTrait;
|
||||
use Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\StandaloneTrait;
|
||||
|
||||
trait UnneededStandaloneTrait
|
||||
{
|
||||
use ClassicTrait, StandaloneTrait;
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,45 +0,0 @@
|
|||
<?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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\UnionType as PhpParserUnionType;
|
||||
|
||||
final class UsedUnionType
|
||||
{
|
||||
public function param(String_ | PhpParserUnionType $node)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Fixture;
|
||||
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\UnionType;
|
||||
|
||||
final class UsedUnionType
|
||||
{
|
||||
public function param(String_ | UnionType $node)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class RemoveUnusedAliasRectorTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $fileInfo): void
|
||||
{
|
||||
$this->doTestFileInfo($fileInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Iterator<SmartFileInfo>
|
||||
*/
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
public function provideConfigFilePath(): string
|
||||
{
|
||||
return __DIR__ . '/config/configured_rule.php';
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source;
|
||||
|
||||
interface AbstractInterface
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source;
|
||||
|
||||
class AbstractKernel
|
||||
{
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source;
|
||||
|
||||
class AliasedStaticCall
|
||||
{
|
||||
public static function someCall()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\Another;
|
||||
|
||||
class AbstractKernel
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source;
|
||||
|
||||
trait ClassicTrait
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source\DifferentNamespace;
|
||||
|
||||
class StandaloneClass
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source;
|
||||
|
||||
final class Mapping
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source;
|
||||
|
||||
class StandaloneClass
|
||||
{
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\Source;
|
||||
|
||||
trait StandaloneTrait
|
||||
{
|
||||
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\CodingStyle\Rector\Use_\RemoveUnusedAliasRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
$services->set(RemoveUnusedAliasRector::class);
|
||||
};
|
|
@ -1,215 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\CodingStyle\Naming;
|
||||
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Expr\Instanceof_;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\NullableType;
|
||||
use PhpParser\Node\Param;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Interface_;
|
||||
use PhpParser\Node\Stmt\TraitUse;
|
||||
use PhpParser\Node\UnionType;
|
||||
use Rector\NameImporting\ValueObject\NameAndParent;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
|
||||
final class NameRenamer
|
||||
{
|
||||
public function __construct(
|
||||
private NodeNameResolver $nodeNameResolver
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param NameAndParent[] $namesAndParent
|
||||
*/
|
||||
public function renameNameNode(array $namesAndParent, string $lastName): void
|
||||
{
|
||||
foreach ($namesAndParent as $nameAndParent) {
|
||||
$parentNode = $nameAndParent->getParentNode();
|
||||
$usedName = $nameAndParent->getNameNode();
|
||||
|
||||
if ($parentNode instanceof TraitUse) {
|
||||
$this->renameTraitUse($lastName, $parentNode, $usedName);
|
||||
}
|
||||
|
||||
if ($parentNode instanceof Class_) {
|
||||
$this->renameClass($lastName, $parentNode, $usedName);
|
||||
}
|
||||
|
||||
if ($parentNode instanceof Param) {
|
||||
$this->renameParam($lastName, $parentNode, $usedName);
|
||||
}
|
||||
|
||||
if ($parentNode instanceof New_) {
|
||||
$this->renameNew($lastName, $parentNode, $usedName);
|
||||
}
|
||||
|
||||
if ($parentNode instanceof ClassMethod) {
|
||||
$this->renameClassMethod($lastName, $parentNode, $usedName);
|
||||
}
|
||||
|
||||
if ($parentNode instanceof Interface_) {
|
||||
$this->renameInterface($lastName, $parentNode, $usedName);
|
||||
}
|
||||
|
||||
if ($parentNode instanceof StaticCall) {
|
||||
$this->renameStaticCall($lastName, $parentNode);
|
||||
}
|
||||
|
||||
if ($parentNode instanceof UnionType) {
|
||||
$this->renameUnionType($lastName, $parentNode, $usedName);
|
||||
}
|
||||
|
||||
if ($parentNode instanceof NullableType) {
|
||||
$this->renameNullableType($lastName, $parentNode, $usedName);
|
||||
}
|
||||
|
||||
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,
|
||||
Name | Identifier $usedNameNode
|
||||
): void {
|
||||
if (! $this->nodeNameResolver->areNamesEqual($instanceof->class, $usedNameNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$instanceof->class = new Name($lastName);
|
||||
}
|
||||
|
||||
private function renameNullableType(
|
||||
string $lastName,
|
||||
NullableType $nullableType,
|
||||
Name | Identifier $usedNameNode
|
||||
): void {
|
||||
if (! $this->nodeNameResolver->areNamesEqual($nullableType->type, $usedNameNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$nullableType->type = new Name($lastName);
|
||||
}
|
||||
|
||||
private function renameTraitUse(string $lastName, TraitUse $traitUse, Name | Identifier $usedNameNode): void
|
||||
{
|
||||
foreach ($traitUse->traits as $key => $traitName) {
|
||||
if (! $this->nodeNameResolver->areNamesEqual($traitName, $usedNameNode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$traitUse->traits[$key] = new Name($lastName);
|
||||
}
|
||||
}
|
||||
|
||||
private function renameClass(string $lastName, Class_ $class, Name | Identifier $usedNameNode): void
|
||||
{
|
||||
if ($class->name !== null && $this->nodeNameResolver->areNamesEqual($class->name, $usedNameNode)) {
|
||||
$class->name = new Identifier($lastName);
|
||||
}
|
||||
|
||||
if ($class->extends !== null && $this->nodeNameResolver->areNamesEqual($class->extends, $usedNameNode)) {
|
||||
$class->extends = new Name($lastName);
|
||||
}
|
||||
|
||||
foreach ($class->implements as $key => $implementNode) {
|
||||
if ($this->nodeNameResolver->areNamesEqual($implementNode, $usedNameNode)) {
|
||||
$class->implements[$key] = new Name($lastName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function renameParam(string $lastName, Param $param, Name | Identifier $usedNameNode): void
|
||||
{
|
||||
if ($param->type === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $this->nodeNameResolver->areNamesEqual($param->type, $usedNameNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$param->type = new Name($lastName);
|
||||
}
|
||||
|
||||
private function renameUnionType(string $lastName, UnionType $unionType, Identifier|Name $usedNameNode): void
|
||||
{
|
||||
foreach ($unionType->types as $key => $unionedType) {
|
||||
if (! $this->nodeNameResolver->areNamesEqual($unionedType, $usedNameNode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $unionedType instanceof Name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$unionType->types[$key] = new Name($lastName);
|
||||
}
|
||||
}
|
||||
|
||||
private function renameNew(string $lastName, New_ $new, Name | Identifier $usedNameNode): void
|
||||
{
|
||||
if ($this->nodeNameResolver->areNamesEqual($new->class, $usedNameNode)) {
|
||||
$new->class = new Name($lastName);
|
||||
}
|
||||
}
|
||||
|
||||
private function renameClassMethod(
|
||||
string $lastName,
|
||||
ClassMethod $classMethod,
|
||||
Name | Identifier $usedNameNode
|
||||
): void {
|
||||
if ($classMethod->returnType === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $this->nodeNameResolver->areNamesEqual($classMethod->returnType, $usedNameNode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$classMethod->returnType = new Name($lastName);
|
||||
}
|
||||
|
||||
private function renameInterface(string $lastName, Interface_ $interface, Name | Identifier $usedNameNode): void
|
||||
{
|
||||
foreach ($interface->extends as $key => $extendInterfaceName) {
|
||||
if (! $this->nodeNameResolver->areNamesEqual($extendInterfaceName, $usedNameNode)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$interface->extends[$key] = new Name($lastName);
|
||||
}
|
||||
}
|
||||
|
||||
private function renameStaticCall(string $lastName, StaticCall $staticCall): void
|
||||
{
|
||||
$staticCall->class = new Name($lastName);
|
||||
}
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\CodingStyle\Node;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Comment\Doc;
|
||||
use PhpParser\Node;
|
||||
use PHPStan\Type\Type;
|
||||
use PHPStan\Type\UnionType;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType;
|
||||
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
|
||||
|
||||
final class DocAliasResolver
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
* @see https://regex101.com/r/cWpliJ/1
|
||||
*/
|
||||
private const DOC_ALIAS_REGEX = '#\@(?<possible_alias>\w+)(\\\\)?#s';
|
||||
|
||||
public function __construct(
|
||||
private SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
|
||||
private PhpDocInfoFactory $phpDocInfoFactory
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function resolve(Node $node): array
|
||||
{
|
||||
$possibleDocAliases = [];
|
||||
|
||||
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($node, function (Node $node) use (
|
||||
&$possibleDocAliases
|
||||
): void {
|
||||
$docComment = $node->getDocComment();
|
||||
if (! $docComment instanceof Doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||
$possibleDocAliases = $this->collectVarType($phpDocInfo, $possibleDocAliases);
|
||||
|
||||
// e.g. "use Dotrine\ORM\Mapping as ORM" etc.
|
||||
$matches = Strings::matchAll($docComment->getText(), self::DOC_ALIAS_REGEX);
|
||||
foreach ($matches as $match) {
|
||||
$possibleDocAliases[] = $match['possible_alias'];
|
||||
}
|
||||
});
|
||||
|
||||
return array_unique($possibleDocAliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $possibleDocAliases
|
||||
* @return string[]
|
||||
*/
|
||||
private function collectVarType(PhpDocInfo $phpDocInfo, array $possibleDocAliases): array
|
||||
{
|
||||
$possibleDocAliases = $this->appendPossibleAliases($phpDocInfo->getVarType(), $possibleDocAliases);
|
||||
$possibleDocAliases = $this->appendPossibleAliases($phpDocInfo->getReturnType(), $possibleDocAliases);
|
||||
|
||||
foreach ($phpDocInfo->getParamTypesByName() as $paramType) {
|
||||
$possibleDocAliases = $this->appendPossibleAliases($paramType, $possibleDocAliases);
|
||||
}
|
||||
|
||||
return $possibleDocAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $possibleDocAliases
|
||||
* @return string[]
|
||||
*/
|
||||
private function appendPossibleAliases(Type $varType, array $possibleDocAliases): array
|
||||
{
|
||||
if ($varType instanceof AliasedObjectType) {
|
||||
$possibleDocAliases[] = $varType->getClassName();
|
||||
}
|
||||
|
||||
if ($varType instanceof UnionType) {
|
||||
foreach ($varType->getTypes() as $type) {
|
||||
$possibleDocAliases = $this->appendPossibleAliases($type, $possibleDocAliases);
|
||||
}
|
||||
}
|
||||
|
||||
return $possibleDocAliases;
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\CodingStyle\Node;
|
||||
|
||||
use Rector\CodingStyle\ClassNameImport\ShortNameResolver;
|
||||
use Rector\CodingStyle\Naming\ClassNaming;
|
||||
use Rector\Core\ValueObject\Application\File;
|
||||
|
||||
final class UseNameAliasToNameResolver
|
||||
{
|
||||
public function __construct(
|
||||
private ClassNaming $classNaming,
|
||||
private ShortNameResolver $shortNameResolver
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, string[]>
|
||||
*/
|
||||
public function resolve(File $file): array
|
||||
{
|
||||
$useNamesAliasToName = [];
|
||||
|
||||
$shortNames = $this->shortNameResolver->resolveFromFile($file);
|
||||
foreach ($shortNames as $alias => $useImport) {
|
||||
if (! is_string($alias)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$shortName = $this->classNaming->getShortName($useImport);
|
||||
if ($shortName === $alias) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$useNamesAliasToName[$shortName][] = $alias;
|
||||
}
|
||||
|
||||
return $useNamesAliasToName;
|
||||
}
|
||||
}
|
|
@ -1,244 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\CodingStyle\Rector\Use_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt\Namespace_;
|
||||
use PhpParser\Node\Stmt\Use_;
|
||||
use PhpParser\Node\Stmt\UseUse;
|
||||
use Rector\CodingStyle\ClassNameImport\ClassNameImportSkipper;
|
||||
use Rector\CodingStyle\Naming\NameRenamer;
|
||||
use Rector\CodingStyle\Node\DocAliasResolver;
|
||||
use Rector\CodingStyle\Node\UseNameAliasToNameResolver;
|
||||
use Rector\Core\PhpParser\NodeFinder\FullyQualifiedFromUseFinder;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\NameImporting\NodeAnalyzer\UseAnalyzer;
|
||||
use Rector\NameImporting\ValueObject\NameAndParent;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\Tests\CodingStyle\Rector\Use_\RemoveUnusedAliasRector\RemoveUnusedAliasRectorTest
|
||||
*/
|
||||
final class RemoveUnusedAliasRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var NameAndParent[]
|
||||
*/
|
||||
private array $namesAndParents = [];
|
||||
|
||||
/**
|
||||
* @var array<string, string[]>
|
||||
*/
|
||||
private array $useNamesAliasToName = [];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private array $resolvedDocPossibleAliases = [];
|
||||
|
||||
public function __construct(
|
||||
private DocAliasResolver $docAliasResolver,
|
||||
private UseAnalyzer $useAnalyzer,
|
||||
private UseNameAliasToNameResolver $useNameAliasToNameResolver,
|
||||
private NameRenamer $nameRenamer,
|
||||
private ClassNameImportSkipper $classNameImportSkipper,
|
||||
private FullyQualifiedFromUseFinder $fullyQualifiedFromUseFinder
|
||||
) {
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition(
|
||||
'Removes unused use aliases. Keep annotation aliases like "Doctrine\ORM\Mapping as ORM" to keep convention format',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
use Symfony\Kernel as BaseKernel;
|
||||
|
||||
class SomeClass extends BaseKernel
|
||||
{
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
use Symfony\Kernel;
|
||||
|
||||
class SomeClass extends Kernel
|
||||
{
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<Node>>
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Use_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Use_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($this->shouldSkipUse($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$searchNode = $this->resolveSearchNode($node);
|
||||
if (! $searchNode instanceof Node) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->namesAndParents = $this->useAnalyzer->resolveUsedNameNodes($searchNode);
|
||||
$this->resolvedDocPossibleAliases = $this->docAliasResolver->resolve($searchNode);
|
||||
$this->useNamesAliasToName = $this->useNameAliasToNameResolver->resolve($this->file);
|
||||
|
||||
// lowercase
|
||||
$this->resolvedDocPossibleAliases = $this->lowercaseArray($this->resolvedDocPossibleAliases);
|
||||
|
||||
$this->useNamesAliasToName = array_change_key_case($this->useNamesAliasToName, CASE_LOWER);
|
||||
|
||||
foreach ($node->uses as $use) {
|
||||
if ($use->alias === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lastName = $use->name->getLast();
|
||||
|
||||
/** @var string $aliasName */
|
||||
$aliasName = $this->getName($use->alias);
|
||||
if ($this->shouldSkip($node, $lastName, $aliasName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// only last name is used → no need for alias
|
||||
$matchedNamesAndParents = $this->matchNamesAndParentsByShort($lastName);
|
||||
if ($matchedNamesAndParents !== []) {
|
||||
$use->alias = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->refactorAliasName($node, $use->name->toString(), $lastName, $use);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
private function shouldSkipUse(Use_ $use): bool
|
||||
{
|
||||
// skip cases without namespace, problematic to analyse
|
||||
$namespace = $this->betterNodeFinder->findParentType($use, Namespace_::class);
|
||||
if (! $namespace instanceof Node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ! $this->hasUseAlias($use);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $values
|
||||
* @return string[]
|
||||
*/
|
||||
private function lowercaseArray(array $values): array
|
||||
{
|
||||
return array_map('strtolower', $values);
|
||||
}
|
||||
|
||||
private function shouldSkip(Use_ $use, string $lastName, string $aliasName): bool
|
||||
{
|
||||
// PHP is case insensitive
|
||||
$loweredLastName = strtolower($lastName);
|
||||
$loweredAliasName = strtolower($aliasName);
|
||||
|
||||
// both are used → nothing to remove
|
||||
if ($this->areBothShortNamesUsed($loweredLastName, $loweredLastName)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// part of some @Doc annotation
|
||||
if (in_array($loweredAliasName, $this->resolvedDocPossibleAliases, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (bool) $this->fullyQualifiedFromUseFinder->matchAliasNamespace($use, $loweredAliasName);
|
||||
}
|
||||
|
||||
private function refactorAliasName(Use_ $use, string $fullUseUseName, string $lastName, UseUse $useUse): void
|
||||
{
|
||||
$parentUse = $use->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if (! $parentUse instanceof Node) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var Use_[] $uses */
|
||||
$uses = $this->betterNodeFinder->find($parentUse, function (Node $node) use ($use): bool {
|
||||
if ($node === $use) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $node instanceof Use_;
|
||||
});
|
||||
|
||||
if ($this->classNameImportSkipper->isShortNameInUseStatement(new Name($lastName), $uses)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$parentsAndNames = $this->matchNamesAndParentsByShort($fullUseUseName);
|
||||
if ($parentsAndNames === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->nameRenamer->renameNameNode($parentsAndNames, $lastName);
|
||||
$useUse->alias = null;
|
||||
}
|
||||
|
||||
private function hasUseAlias(Use_ $use): bool
|
||||
{
|
||||
foreach ($use->uses as $useUse) {
|
||||
if ($useUse->alias !== null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function resolveSearchNode(Use_ $use): ?Node
|
||||
{
|
||||
$searchNode = $use->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if ($searchNode !== null) {
|
||||
return $searchNode;
|
||||
}
|
||||
|
||||
return $use->getAttribute(AttributeKey::NEXT_NODE);
|
||||
}
|
||||
|
||||
private function areBothShortNamesUsed(string $firstName, string $secondName): bool
|
||||
{
|
||||
$firstNamesAndParents = $this->matchNamesAndParentsByShort($firstName);
|
||||
$secondNamesAndParents = $this->matchNamesAndParentsByShort($secondName);
|
||||
|
||||
return $firstNamesAndParents !== [] && $secondNamesAndParents !== [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return NameAndParent[]
|
||||
*/
|
||||
private function matchNamesAndParentsByShort(string $shortName): array
|
||||
{
|
||||
return array_filter(
|
||||
$this->namesAndParents,
|
||||
fn (NameAndParent $nameAndParent): bool => $nameAndParent->matchShortName($shortName)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?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;
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user