[DeadCode] Add RemoveUnusedClassConstantRector

This commit is contained in:
TomasVotruba 2020-02-23 22:04:20 +01:00
parent c011720d4f
commit c2b89700a3
10 changed files with 248 additions and 9 deletions

View File

@ -32,4 +32,4 @@ services:
Rector\DeadCode\Rector\Ternary\TernaryToBooleanOrFalseToBooleanAndRector: null
Rector\PHPUnit\Rector\ClassMethod\RemoveEmptyTestMethodRector: null
Rector\DeadCode\Rector\TryCatch\RemoveDeadTryCatchRector: null
Rector\DeadCode\Rector\ClassConst\RemoveUnusedClassConstantRector: null

View File

@ -1,4 +1,4 @@
# All 460 Rectors Overview
# All 461 Rectors Overview
- [Projects](#projects)
- [General](#general)
@ -351,12 +351,13 @@ Changes method calls based on matching the first parameter value.
```yaml
services:
Rector\CakePHP\Rector\MethodCall\RenameMethodCallBasedOnParameterRector:
getParam:
match_parameter: paging
replace_with: getAttribute
withParam:
match_parameter: paging
replace_with: withAttribute
$methodNamesByTypes:
getParam:
match_parameter: paging
replace_with: getAttribute
withParam:
match_parameter: paging
replace_with: withAttribute
```
@ -2936,6 +2937,26 @@ Remove unreachable statements
<br>
### `RemoveUnusedClassConstantRector`
- class: [`Rector\DeadCode\Rector\ClassConst\RemoveUnusedClassConstantRector`](/../master/rules/dead-code/src/Rector/ClassConst/RemoveUnusedClassConstantRector.php)
- [test fixtures](/../master/rules/dead-code/tests/Rector/ClassConst/RemoveUnusedClassConstantRector/Fixture)
Remove unused class constants
```diff
class SomeClass
{
- private const SOME_CONST = 'dead';
-
public function run()
{
}
}
```
<br>
### `RemoveUnusedClassesRector`
- class: [`Rector\DeadCode\Rector\Class_\RemoveUnusedClassesRector`](/../master/rules/dead-code/src/Rector/Class_/RemoveUnusedClassesRector.php)

View File

@ -0,0 +1,101 @@
<?php
declare(strict_types=1);
namespace Rector\DeadCode\Rector\ClassConst;
use PhpParser\Node;
use PhpParser\Node\Stmt\ClassConst;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\NodeCollector\NodeFinder\ClassConstParsedNodesFinder;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
* @see \Rector\DeadCode\Tests\Rector\ClassConst\RemoveUnusedClassConstantRector\RemoveUnusedClassConstantRectorTest
*/
final class RemoveUnusedClassConstantRector extends AbstractRector
{
/**
* @var ClassConstParsedNodesFinder
*/
private $classConstParsedNodesFinder;
public function __construct(ClassConstParsedNodesFinder $classConstParsedNodesFinder)
{
$this->classConstParsedNodesFinder = $classConstParsedNodesFinder;
}
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Remove unused class constants', [
new CodeSample(
<<<'PHP'
class SomeClass
{
private const SOME_CONST = 'dead';
public function run()
{
}
}
PHP
,
<<<'PHP'
class SomeClass
{
public function run()
{
}
}
PHP
),
]);
}
/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [ClassConst::class];
}
/**
* @param ClassConst $node
*/
public function refactor(Node $node): ?Node
{
if (count($node->consts) !== 1) {
return null;
}
/** @var string $class */
$class = $node->getAttribute(AttributeKey::CLASS_NAME);
// 0. constants declared in interfaces have to be public
if ($this->classLikeParsedNodesFinder->findInterface($class) !== null) {
$this->makePublic($node);
return $node;
}
/** @var string $constant */
$constant = $this->getName($node);
$directUseClasses = $this->classConstParsedNodesFinder->findDirectClassConstantFetches($class, $constant);
if ($directUseClasses !== []) {
return null;
}
$indirectUseClasses = $this->classConstParsedNodesFinder->findIndirectClassConstantFetches($class, $constant);
if ($indirectUseClasses !== []) {
return null;
}
$this->removeNode($node);
return null;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace Rector\DeadCode\Tests\Rector\ClassConst\RemoveUnusedClassConstantRector\Fixture;
class ExternalPublic
{
public const SOME_CONST = 'dead';
}
?>
-----
<?php
namespace Rector\DeadCode\Tests\Rector\ClassConst\RemoveUnusedClassConstantRector\Fixture;
class ExternalPublic
{
}
?>

View File

@ -0,0 +1,27 @@
<?php
namespace Rector\DeadCode\Tests\Rector\ClassConst\RemoveUnusedClassConstantRector\Fixture;
class SomeClass
{
private const SOME_CONST = 'dead';
public function run()
{
}
}
?>
-----
<?php
namespace Rector\DeadCode\Tests\Rector\ClassConst\RemoveUnusedClassConstantRector\Fixture;
class SomeClass
{
public function run()
{
}
}
?>

View File

@ -0,0 +1,16 @@
<?php
namespace Rector\DeadCode\Tests\Rector\ClassConst\RemoveUnusedClassConstantRector\Fixture;
class SkipChildUsed
{
protected const SOME_CONST = 'dead';
}
class SomeChild extends SkipChildUsed
{
public function run()
{
return self::SOME_CONST;
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace Rector\DeadCode\Tests\Rector\ClassConst\RemoveUnusedClassConstantRector\Fixture;
class SkipExternalUsed
{
public const SOME_CONST = 'dead';
}
class SomeUsed
{
public function run()
{
return SkipExternalUsed::SOME_CONST;
}
}

View File

@ -0,0 +1,8 @@
<?php
namespace Rector\DeadCode\Tests\Rector\ClassConst\RemoveUnusedClassConstantRector\Fixture;
class SkipMultipleConstants
{
public const SOME_CONST = 'dead', NOT_USED_EITHER = 'dead';
}

View File

@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace Rector\DeadCode\Tests\Rector\ClassConst\RemoveUnusedClassConstantRector;
use Iterator;
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
use Rector\DeadCode\Rector\ClassConst\RemoveUnusedClassConstantRector;
final class RemoveUnusedClassConstantRectorTest extends AbstractRectorTestCase
{
/**
* @dataProvider provideData()
*/
public function test(string $file): void
{
$this->doTestFile($file);
}
public function provideData(): Iterator
{
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
}
protected function getRectorClass(): string
{
return RemoveUnusedClassConstantRector::class;
}
}

View File

@ -188,7 +188,7 @@ PHP
?ConstantVisibility $constantVisibility,
string $class
): void {
// 1. is actually never used (@todo use in "dead-code" set)
// 1. is actually never used
if ($directUseClasses === []) {
if ($indirectUseClasses !== [] && $constantVisibility !== null) {
$this->makePrivateOrWeaker($classConst, $constantVisibility);