[EarlyReturn] Handle continue/break in foreach with next return on ChangeAndIfToEarlyReturnRector (#946)

* [EarlyReturn] Handle continue in foreach with next return on ChangeAndIfToEarlyReturnRector

* update

* eol

* Fixed 🎉
This commit is contained in:
Abdul Malik Ikhsan 2021-10-02 00:54:47 +07:00 committed by GitHub
parent 347b593847
commit 0552b3a885
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 108 additions and 1 deletions

View File

@ -0,0 +1,45 @@
<?php
namespace Rector\Tests\EarlyReturn\Rector\If_\ChangeAndIfToEarlyReturnRector\Fixture;
class BreakInForeachNextReturn
{
public function run(array $data, bool $a, bool $b)
{
foreach ($data as $value) {
if ($a === $b && ! $value) {
break;
}
return true;
}
return false;
}
}
?>
-----
<?php
namespace Rector\Tests\EarlyReturn\Rector\If_\ChangeAndIfToEarlyReturnRector\Fixture;
class BreakInForeachNextReturn
{
public function run(array $data, bool $a, bool $b)
{
foreach ($data as $value) {
if ($a !== $b) {
return true;
}
if ($value) {
return true;
}
break;
}
return false;
}
}
?>

View File

@ -0,0 +1,45 @@
<?php
namespace Rector\Tests\EarlyReturn\Rector\If_\ChangeAndIfToEarlyReturnRector\Fixture;
class ContinueInForeachNextReturn
{
public function run(array $data, bool $a, bool $b)
{
foreach ($data as $value) {
if ($a === $b && ! $value) {
continue;
}
return true;
}
return false;
}
}
?>
-----
<?php
namespace Rector\Tests\EarlyReturn\Rector\If_\ChangeAndIfToEarlyReturnRector\Fixture;
class ContinueInForeachNextReturn
{
public function run(array $data, bool $a, bool $b)
{
foreach ($data as $value) {
if ($a !== $b) {
return true;
}
if ($value) {
return true;
}
continue;
}
return false;
}
}
?>

View File

@ -7,6 +7,8 @@ namespace Rector\EarlyReturn\Rector\If_;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
use PhpParser\Node\Stmt\Break_;
use PhpParser\Node\Stmt\Continue_;
use PhpParser\Node\Stmt\Else_;
use PhpParser\Node\Stmt\ElseIf_;
use PhpParser\Node\Stmt\If_;
@ -119,13 +121,28 @@ CODE_SAMPLE
? clone $node->stmts[0]
: new Return_();
if ($this->contextAnalyzer->isInLoop($node)) {
if ($this->isInLoopWithoutContinueOrBreak($node)) {
$afters[] = new Return_();
}
return $this->processReplaceIfs($node, $booleanAndConditions, $ifNextReturnClone, $afters);
}
private function isInLoopWithoutContinueOrBreak(If_ $if): bool
{
if (!$this->contextAnalyzer->isInLoop(
$if
)) {
return false;
}
if ($if->stmts[0] instanceof Continue_) {
return false;
}
return ! $if->stmts[0] instanceof Break_;
}
/**
* @param Expr[] $conditions
* @param Node[] $afters