Skip to content

Commit

Permalink
Merge pull request #1261 from rectorphp/dead-if-foreach-for
Browse files Browse the repository at this point in the history
[DeadCode] Add RemoveDeadIfForeachForRector
  • Loading branch information
TomasVotruba committed Mar 31, 2019
2 parents 919f3e5 + b7783f9 commit 8aa22d2
Show file tree
Hide file tree
Showing 6 changed files with 262 additions and 2 deletions.
1 change: 1 addition & 0 deletions config/level/dead-code/dead-code.yaml
Expand Up @@ -14,3 +14,4 @@ services:
Rector\DeadCode\Rector\FunctionLike\RemoveCodeAfterReturnRector: ~
Rector\DeadCode\Rector\ClassMethod\RemoveDeadConstructorRector: ~
Rector\DeadCode\Rector\FunctionLike\RemoveDeadReturnRector: ~
Rector\DeadCode\Rector\For_\RemoveDeadIfForeachForRector: ~
147 changes: 147 additions & 0 deletions packages/DeadCode/src/Rector/For_/RemoveDeadIfForeachForRector.php
@@ -0,0 +1,147 @@
<?php declare(strict_types=1);

namespace Rector\DeadCode\Rector\For_;

use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar;
use PhpParser\Node\Stmt\For_;
use PhpParser\Node\Stmt\Foreach_;
use PhpParser\Node\Stmt\If_;
use Rector\Rector\AbstractRector;
use Rector\RectorDefinition\CodeSample;
use Rector\RectorDefinition\RectorDefinition;

final class RemoveDeadIfForeachForRector extends AbstractRector
{
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Remove if, foreach and for that does not do anything', [
new CodeSample(
<<<'CODE_SAMPLE'
class SomeClass
{
public function run($someObject)
{
$value = 5;
if ($value) {
}
if ($someObject->run()) {
}
foreach ($values as $value) {
}
return $value;
}
}
CODE_SAMPLE
,
<<<'CODE_SAMPLE'
class SomeClass
{
public function run($someObject)
{
$value = 5;
if ($someObject->run()) {
}
return $value;
}
}
CODE_SAMPLE
),
]);
}

/**
* @return string[]
*/
public function getNodeTypes(): array
{
return [For_::class, If_::class, Foreach_::class];
}

/**
* @param For_|If_|Foreach_ $node
*/
public function refactor(Node $node): ?Node
{
if ($node instanceof If_) {
return $this->processIf($node);
}

if ($node instanceof Foreach_) {
return $this->processForeach($node);
}

if ($node instanceof For_) {
if ($node->stmts) {
return null;
}

$this->removeNode($node);

return null;
}

return $node;
}

private function processIf(If_ $if): ?If_
{
if ($if->stmts) {
return null;
}

if ($if->else) {
return null;
}

if ($if->elseifs) {
return null;
}

if ($this->isNodeWithSideEffect($if->cond)) {
return null;
}

$this->removeNode($if);

return null;
}

private function processForeach(Foreach_ $node): ?Foreach_
{
if ($node->stmts) {
return null;
}

if ($this->isNodeWithSideEffect($node->expr)) {
return null;
}

$this->removeNode($node);

return null;
}

private function isNodeWithSideEffect(Expr $expr): bool
{
if ($expr instanceof Variable) {
return false;
}

if ($expr instanceof Scalar) {
return false;
}

if ($this->isBool($expr)) {
return false;
}

return true;
}
}
@@ -0,0 +1,55 @@
<?php

namespace Rector\DeadCode\Tests\Rector\For_\RemoveDeadIfForeachForRector\Fixture;

class SomeClass
{
public function run($someObject)
{
$value = 5;
if ($value) {
}

if ($someObject->run()) {
}

$values = [];
foreach ($values as $value) {
}

return $value;
}

public function forMe()
{
for ($i = 0; $i < 5; ++$i) {
}
}
}

?>
-----
<?php

namespace Rector\DeadCode\Tests\Rector\For_\RemoveDeadIfForeachForRector\Fixture;

class SomeClass
{
public function run($someObject)
{
$value = 5;

if ($someObject->run()) {
}

$values = [];

return $value;
}

public function forMe()
{
}
}

?>
@@ -0,0 +1,35 @@
<?php

namespace Rector\DeadCode\Tests\Rector\For_\RemoveDeadIfForeachForRector\Fixture;

class SideEffectChecks
{
public function run()
{
if (10) {
}

if (true) {
}

if (5 + 10) {
}
}
}

?>
-----
<?php

namespace Rector\DeadCode\Tests\Rector\For_\RemoveDeadIfForeachForRector\Fixture;

class SideEffectChecks
{
public function run()
{
if (5 + 10) {
}
}
}

?>
@@ -0,0 +1,22 @@
<?php declare(strict_types=1);

namespace Rector\DeadCode\Tests\Rector\For_\RemoveDeadIfForeachForRector;

use Rector\DeadCode\Rector\For_\RemoveDeadIfForeachForRector;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class RemoveDeadIfForeachForRectorTest extends AbstractRectorTestCase
{
public function test(): void
{
$this->doTestFiles([
__DIR__ . '/Fixture/fixture.php.inc',
__DIR__ . '/Fixture/side_effect_checks.php.inc',
]);
}

protected function getRectorClass(): string
{
return RemoveDeadIfForeachForRector::class;
}
}
Expand Up @@ -2,7 +2,7 @@

namespace Rector\Php\Tests\Rector\FuncCall\RegexDashEscapeRector\Fixture;

class Variable
class RegexInAVar
{
public function run()
{
Expand All @@ -20,7 +20,7 @@ class Variable

namespace Rector\Php\Tests\Rector\FuncCall\RegexDashEscapeRector\Fixture;

class Variable
class RegexInAVar
{
public function run()
{
Expand Down

0 comments on commit 8aa22d2

Please sign in to comment.