From 413c45dfb95342912f9f63c9e35e00e541b0c454 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 22 Nov 2025 21:17:52 +0700 Subject: [PATCH 1/2] [EarlyReturn] Handle If, elseIf, else all returned on RemoveAlwaysElseRector --- .../Fixture/if_elseif_else.php.inc | 42 +++++++++++++++++++ ...f_with_terminating_elseif_and_else.php.inc | 4 +- .../Fixture/process_empty_return_last.php.inc | 4 +- .../Rector/If_/RemoveAlwaysElseRector.php | 13 +++++- 4 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/if_elseif_else.php.inc diff --git a/rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/if_elseif_else.php.inc b/rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/if_elseif_else.php.inc new file mode 100644 index 00000000000..0f2a926d295 --- /dev/null +++ b/rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/if_elseif_else.php.inc @@ -0,0 +1,42 @@ + +----- + diff --git a/rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/nested_if_with_terminating_elseif_and_else.php.inc b/rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/nested_if_with_terminating_elseif_and_else.php.inc index ad03daa7cb3..be7b8010571 100644 --- a/rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/nested_if_with_terminating_elseif_and_else.php.inc +++ b/rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/nested_if_with_terminating_elseif_and_else.php.inc @@ -37,9 +37,7 @@ class NestedIfWithTerminatingElseIfAndElse if ($cond3) { return 'bar'; } - else { - return 'baz'; - } + return 'baz'; } foo(); } diff --git a/rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/process_empty_return_last.php.inc b/rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/process_empty_return_last.php.inc index ca6d518b0b9..d3989cd29e5 100644 --- a/rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/process_empty_return_last.php.inc +++ b/rules-tests/EarlyReturn/Rector/If_/RemoveAlwaysElseRector/Fixture/process_empty_return_last.php.inc @@ -47,9 +47,7 @@ class ProcessEmptyReturnLast $value = 55; return 10; } - else { - return; - } + return; } public function secondRun($value) diff --git a/rules/EarlyReturn/Rector/If_/RemoveAlwaysElseRector.php b/rules/EarlyReturn/Rector/If_/RemoveAlwaysElseRector.php index 44da436638c..99c5d1b73b9 100644 --- a/rules/EarlyReturn/Rector/If_/RemoveAlwaysElseRector.php +++ b/rules/EarlyReturn/Rector/If_/RemoveAlwaysElseRector.php @@ -130,7 +130,18 @@ private function handleElseIfs(If_ $if): array } if ($originalIf->else instanceof Else_) { - $nodesToReturn[] = $originalIf->else; + $mergeStmts = true; + foreach ($nodesToReturn as $nodeToReturn) { + if ($this->doesLastStatementBreakFlow($nodeToReturn)) { + $nodesToReturn[] = $originalIf->else; + $mergeStmts = false; + break; + } + } + + if ($mergeStmts) { + $nodesToReturn = array_merge($nodesToReturn, $originalIf->else->stmts); + } } return $nodesToReturn; From ae51b6dd4e3183f3c40c5637ff3e7d0b5ebe04bb Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Sat, 22 Nov 2025 21:41:30 +0700 Subject: [PATCH 2/2] Fix method name as it verify not break flow --- .../Rector/If_/RemoveAlwaysElseRector.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rules/EarlyReturn/Rector/If_/RemoveAlwaysElseRector.php b/rules/EarlyReturn/Rector/If_/RemoveAlwaysElseRector.php index 99c5d1b73b9..b977853751e 100644 --- a/rules/EarlyReturn/Rector/If_/RemoveAlwaysElseRector.php +++ b/rules/EarlyReturn/Rector/If_/RemoveAlwaysElseRector.php @@ -74,7 +74,7 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?array { - if ($this->doesLastStatementBreakFlow($node)) { + if ($this->doesNotLastStatementBreakFlow($node)) { return null; } @@ -108,7 +108,7 @@ private function handleElseIfs(If_ $if): array $currentElseIf = array_shift($if->elseifs); // If the last statement in the `elseif` breaks flow, merge it into the original `if` and stop processing - if ($this->doesLastStatementBreakFlow($currentElseIf)) { + if ($this->doesNotLastStatementBreakFlow($currentElseIf)) { $this->updateIfWithElseIf($if, $currentElseIf); $nodesToReturn = [...$nodesToReturn, $if, ...$this->getStatementsElseIfs($if)]; @@ -132,7 +132,7 @@ private function handleElseIfs(If_ $if): array if ($originalIf->else instanceof Else_) { $mergeStmts = true; foreach ($nodesToReturn as $nodeToReturn) { - if ($this->doesLastStatementBreakFlow($nodeToReturn)) { + if ($this->doesNotLastStatementBreakFlow($nodeToReturn)) { $nodesToReturn[] = $originalIf->else; $mergeStmts = false; break; @@ -154,7 +154,7 @@ private function getStatementsElseIfs(If_ $if): array { $statements = []; foreach ($if->elseifs as $key => $elseif) { - if ($this->doesLastStatementBreakFlow($elseif) && $elseif->stmts !== []) { + if ($this->doesNotLastStatementBreakFlow($elseif) && $elseif->stmts !== []) { continue; } @@ -165,17 +165,17 @@ private function getStatementsElseIfs(If_ $if): array return $statements; } - private function doesLastStatementBreakFlow(If_ | ElseIf_ | Else_ $node): bool + private function doesNotLastStatementBreakFlow(If_ | ElseIf_ | Else_ $node): bool { $lastStmt = end($node->stmts); if ($lastStmt instanceof If_ && $lastStmt->else instanceof Else_) { - if ($this->doesLastStatementBreakFlow($lastStmt) || $this->doesLastStatementBreakFlow($lastStmt->else)) { + if ($this->doesNotLastStatementBreakFlow($lastStmt) || $this->doesNotLastStatementBreakFlow($lastStmt->else)) { return true; } foreach ($lastStmt->elseifs as $elseIf) { - if ($this->doesLastStatementBreakFlow($elseIf)) { + if ($this->doesNotLastStatementBreakFlow($elseIf)) { return true; } }