mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-28 23:10:51 +00:00
[DeadCode] Add RemoveUnusedNonEmptyArrayBeforeForeachRector (#3066)
This commit is contained in:
parent
6cd9aa70cc
commit
5204ce1523
|
@ -36,3 +36,4 @@ services:
|
|||
Rector\DeadCode\Rector\Assign\RemoveUnusedVariableAssignRector: null
|
||||
Rector\DeadCode\Rector\FunctionLike\RemoveDuplicatedIfReturnRector: null
|
||||
Rector\DeadCode\Rector\Function_\RemoveUnusedFunctionRector: null
|
||||
Rector\DeadCode\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector: null
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# All 468 Rectors Overview
|
||||
# All 469 Rectors Overview
|
||||
|
||||
- [Projects](#projects)
|
||||
- [General](#general)
|
||||
|
@ -3083,6 +3083,32 @@ Remove unused function
|
|||
|
||||
<br>
|
||||
|
||||
### `RemoveUnusedNonEmptyArrayBeforeForeachRector`
|
||||
|
||||
- class: [`Rector\DeadCode\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector`](/../master/rules/dead-code/src/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector.php)
|
||||
- [test fixtures](/../master/rules/dead-code/tests/Rector/If_/RemoveUnusedNonEmptyArrayBeforeForeachRector/Fixture)
|
||||
|
||||
Remove unused if check to non-empty array before foreach of the array
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$values = [];
|
||||
- if ($values !== []) {
|
||||
- foreach ($values as $value) {
|
||||
- echo $value;
|
||||
- }
|
||||
+ foreach ($values as $value) {
|
||||
+ echo $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### `RemoveUnusedParameterRector`
|
||||
|
||||
- class: [`Rector\DeadCode\Rector\ClassMethod\RemoveUnusedParameterRector`](/../master/rules/dead-code/src/Rector/ClassMethod/RemoveUnusedParameterRector.php)
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DeadCode\Rector\If_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Array_;
|
||||
use PhpParser\Node\Expr\BinaryOp;
|
||||
use PhpParser\Node\Expr\BinaryOp\NotEqual;
|
||||
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
|
||||
use PhpParser\Node\Stmt\Foreach_;
|
||||
use PhpParser\Node\Stmt\If_;
|
||||
use Rector\Core\PhpParser\Node\Manipulator\IfManipulator;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\DeadCode\Tests\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector\RemoveUnusedNonEmptyArrayBeforeForeachRectorTest
|
||||
*/
|
||||
final class RemoveUnusedNonEmptyArrayBeforeForeachRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var IfManipulator
|
||||
*/
|
||||
private $ifManipulator;
|
||||
|
||||
public function __construct(IfManipulator $ifManipulator)
|
||||
{
|
||||
$this->ifManipulator = $ifManipulator;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Remove unused if check to non-empty array before foreach of the array', [
|
||||
new CodeSample(
|
||||
<<<'PHP'
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$values = [];
|
||||
if ($values !== []) {
|
||||
foreach ($values as $value) {
|
||||
echo $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PHP
|
||||
,
|
||||
<<<'PHP'
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$values = [];
|
||||
foreach ($values as $value) {
|
||||
echo $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
PHP
|
||||
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [If_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param If_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (! $this->ifManipulator->isIfWithOnlyForeach($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var Foreach_ $foreach */
|
||||
$foreach = $node->stmts[0];
|
||||
$foreachExpr = $foreach->expr;
|
||||
|
||||
if (! $node->cond instanceof NotIdentical && ! $node->cond instanceof NotEqual) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @var NotIdentical|NotEqual $notIdentical */
|
||||
$notIdentical = $node->cond;
|
||||
|
||||
if (! $this->isMatching($notIdentical, $foreachExpr)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $foreach;
|
||||
}
|
||||
|
||||
private function isEmptyArray(Expr $expr): bool
|
||||
{
|
||||
if (! $expr instanceof Array_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $expr->items === [];
|
||||
}
|
||||
|
||||
private function isEmptyArrayAndForeachedVariable(Expr $leftExpr, Expr $rightExpr, Expr $foreachExpr): bool
|
||||
{
|
||||
if (! $this->isEmptyArray($leftExpr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->areNodesWithoutCommentsEqual($foreachExpr, $rightExpr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param NotIdentical|NotEqual $binaryOp
|
||||
*/
|
||||
private function isMatching(BinaryOp $binaryOp, Expr $foreachExpr): bool
|
||||
{
|
||||
if ($this->isEmptyArrayAndForeachedVariable($binaryOp->left, $binaryOp->right, $foreachExpr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->isEmptyArrayAndForeachedVariable($binaryOp->right, $binaryOp->left, $foreachExpr);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DeadCode\Tests\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$values = [];
|
||||
if ($values !== []) {
|
||||
foreach ($values as $value) {
|
||||
echo $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ([] !== $values) {
|
||||
foreach ($values as $value) {
|
||||
echo $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DeadCode\Tests\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$values = [];
|
||||
foreach ($values as $value) {
|
||||
echo $value;
|
||||
}
|
||||
|
||||
foreach ($values as $value) {
|
||||
echo $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DeadCode\Tests\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector\Fixture;
|
||||
|
||||
class NotEqual
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$values = [];
|
||||
if ($values != []) {
|
||||
foreach ($values as $value) {
|
||||
echo $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\DeadCode\Tests\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector\Fixture;
|
||||
|
||||
class NotEqual
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$values = [];
|
||||
foreach ($values as $value) {
|
||||
echo $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\DeadCode\Tests\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector\Fixture;
|
||||
|
||||
class SkipDifferentForeach
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$values = [];
|
||||
$values2 = [];
|
||||
|
||||
if ($values != []) {
|
||||
foreach ($values2 as $value) {
|
||||
echo $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\DeadCode\Tests\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\DeadCode\Rector\If_\RemoveUnusedNonEmptyArrayBeforeForeachRector;
|
||||
|
||||
final class RemoveUnusedNonEmptyArrayBeforeForeachRectorTest 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 RemoveUnusedNonEmptyArrayBeforeForeachRector::class;
|
||||
}
|
||||
}
|
|
@ -276,6 +276,19 @@ final class IfManipulator
|
|||
return $this->hasOnlyStmtOfType($node, Return_::class);
|
||||
}
|
||||
|
||||
public function isIfWithOnlyForeach(Node $node): bool
|
||||
{
|
||||
if (! $node instanceof If_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->isIfWithoutElseAndElseIfs($node)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->hasOnlyStmtOfType($node, Foreach_::class);
|
||||
}
|
||||
|
||||
private function matchComparedAndReturnedNode(NotIdentical $notIdentical, Return_ $returnNode): ?Expr
|
||||
{
|
||||
if ($this->betterStandardPrinter->areNodesEqual(
|
||||
|
|
Loading…
Reference in New Issue
Block a user