2019-12-29 21:11:24 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
2019-12-29 21:55:54 +00:00
|
|
|
namespace Rector\SOLID\Rector\If_;
|
2019-12-29 21:11:24 +00:00
|
|
|
|
|
|
|
use PhpParser\Node;
|
2020-01-15 20:13:29 +00:00
|
|
|
use PhpParser\Node\Expr\Exit_;
|
|
|
|
use PhpParser\Node\Stmt\Continue_;
|
|
|
|
use PhpParser\Node\Stmt\ElseIf_;
|
|
|
|
use PhpParser\Node\Stmt\Expression;
|
2019-12-29 21:11:24 +00:00
|
|
|
use PhpParser\Node\Stmt\If_;
|
2020-01-15 20:13:29 +00:00
|
|
|
use PhpParser\Node\Stmt\Return_;
|
|
|
|
use PhpParser\Node\Stmt\Throw_;
|
2020-02-06 21:48:18 +00:00
|
|
|
use Rector\Core\Rector\AbstractRector;
|
|
|
|
use Rector\Core\RectorDefinition\CodeSample;
|
|
|
|
use Rector\Core\RectorDefinition\RectorDefinition;
|
2019-12-29 21:11:24 +00:00
|
|
|
|
|
|
|
/**
|
2020-01-15 20:13:29 +00:00
|
|
|
* @see \Rector\SOLID\Tests\Rector\If_\RemoveAlwaysElse\SplitIfsRectorTest
|
2019-12-29 21:11:24 +00:00
|
|
|
*/
|
2019-12-29 21:55:54 +00:00
|
|
|
final class RemoveAlwaysElseRector extends AbstractRector
|
2019-12-29 21:11:24 +00:00
|
|
|
{
|
|
|
|
public function getDefinition(): RectorDefinition
|
|
|
|
{
|
2020-01-15 20:13:29 +00:00
|
|
|
return new RectorDefinition('Split if statement, when if condition always break execution flow', [
|
2019-12-29 21:11:24 +00:00
|
|
|
new CodeSample(
|
|
|
|
<<<'PHP'
|
|
|
|
class SomeClass
|
|
|
|
{
|
|
|
|
public function run($value)
|
|
|
|
{
|
|
|
|
if ($value) {
|
2019-12-29 21:55:54 +00:00
|
|
|
throw new \InvalidStateException;
|
2019-12-29 21:11:24 +00:00
|
|
|
} else {
|
|
|
|
return 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PHP
|
|
|
|
,
|
|
|
|
<<<'PHP'
|
|
|
|
class SomeClass
|
|
|
|
{
|
|
|
|
public function run($value)
|
|
|
|
{
|
|
|
|
if ($value) {
|
2019-12-29 21:55:54 +00:00
|
|
|
throw new \InvalidStateException;
|
2019-12-29 21:11:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 10;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
PHP
|
|
|
|
|
|
|
|
),
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string[]
|
|
|
|
*/
|
|
|
|
public function getNodeTypes(): array
|
|
|
|
{
|
2019-12-29 21:55:54 +00:00
|
|
|
return [If_::class];
|
2019-12-29 21:11:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2019-12-29 21:55:54 +00:00
|
|
|
* @param If_ $node
|
2019-12-29 21:11:24 +00:00
|
|
|
*/
|
|
|
|
public function refactor(Node $node): ?Node
|
|
|
|
{
|
2020-01-15 20:13:29 +00:00
|
|
|
if ($this->lastStatementBreaksFlow($node)) {
|
2019-12-29 21:55:54 +00:00
|
|
|
return null;
|
|
|
|
}
|
2020-02-17 00:24:19 +00:00
|
|
|
|
2020-01-15 20:13:29 +00:00
|
|
|
if ($node->elseifs !== []) {
|
|
|
|
$newNode = new If_($node->cond);
|
|
|
|
$newNode->stmts = $node->stmts;
|
2020-02-17 00:24:19 +00:00
|
|
|
|
2020-01-15 20:13:29 +00:00
|
|
|
$this->addNodeBeforeNode($newNode, $node);
|
2020-02-17 00:24:19 +00:00
|
|
|
|
2020-01-15 20:13:29 +00:00
|
|
|
/** @var ElseIf_ $firstElseIf */
|
|
|
|
$firstElseIf = array_shift($node->elseifs);
|
|
|
|
$node->cond = $firstElseIf->cond;
|
|
|
|
$node->stmts = $firstElseIf->stmts;
|
2020-02-17 00:24:19 +00:00
|
|
|
|
2020-01-15 20:13:29 +00:00
|
|
|
return $node;
|
|
|
|
}
|
2019-12-29 21:11:24 +00:00
|
|
|
|
2020-01-15 20:13:29 +00:00
|
|
|
if ($node->else !== null) {
|
|
|
|
foreach ($node->else->stmts as $stmt) {
|
|
|
|
$this->addNodeAfterNode($stmt, $node);
|
|
|
|
}
|
|
|
|
$node->else = null;
|
|
|
|
return $node;
|
2019-12-29 21:55:54 +00:00
|
|
|
}
|
2019-12-29 21:11:24 +00:00
|
|
|
|
2020-01-15 20:13:29 +00:00
|
|
|
return null;
|
|
|
|
}
|
2019-12-29 21:11:24 +00:00
|
|
|
|
2020-01-15 20:13:29 +00:00
|
|
|
protected function lastStatementBreaksFlow(Node $node): bool
|
|
|
|
{
|
|
|
|
$lastStmt = end($node->stmts);
|
|
|
|
return ! ($lastStmt instanceof Return_
|
|
|
|
|| $lastStmt instanceof Throw_
|
|
|
|
|| $lastStmt instanceof Continue_
|
|
|
|
|| ($lastStmt instanceof Expression && $lastStmt->expr instanceof Exit_));
|
2019-12-29 21:11:24 +00:00
|
|
|
}
|
|
|
|
}
|