diff --git a/.gitignore b/.gitignore index 9de97a38946..b0ad8f0b6fb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ composer.lock # PHPStorm meta files .idea/ +# VS Code files +.vscode + .phpunit.result.cache # since PHPUnit 10 .phpunit.cache diff --git a/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/consecutive_equal_case_stmts4.php.inc b/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/consecutive_equal_case_stmts4.php.inc new file mode 100644 index 00000000000..ebd6941e59b --- /dev/null +++ b/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/consecutive_equal_case_stmts4.php.inc @@ -0,0 +1,46 @@ + +----- + diff --git a/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/consecutive_equal_case_stmts5.php.inc b/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/consecutive_equal_case_stmts5.php.inc new file mode 100644 index 00000000000..9ccca6f0712 --- /dev/null +++ b/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/consecutive_equal_case_stmts5.php.inc @@ -0,0 +1,46 @@ + +----- + diff --git a/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/different_indirect_duplicated4.php.inc b/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/different_indirect_duplicated4.php.inc new file mode 100644 index 00000000000..a0ed8bc0e08 --- /dev/null +++ b/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/different_indirect_duplicated4.php.inc @@ -0,0 +1,56 @@ + +----- + diff --git a/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/different_indirect_duplicated5.php.inc b/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/different_indirect_duplicated5.php.inc new file mode 100644 index 00000000000..bf33e1be122 --- /dev/null +++ b/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/different_indirect_duplicated5.php.inc @@ -0,0 +1,53 @@ + +----- + diff --git a/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/no_stmts_without_comments.php.inc b/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/no_stmts_without_comments.php.inc new file mode 100644 index 00000000000..c72c3b223ad --- /dev/null +++ b/rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/no_stmts_without_comments.php.inc @@ -0,0 +1,47 @@ +cases); - $conds = []; + /** @var Case_[] */ + $result = []; + + /** @var int[] */ + $processedCasesNumbers = []; + + foreach ($switch->cases as $outerCaseKey => $outerCase) { + if (in_array($outerCaseKey, $processedCasesNumbers)) { + continue; + } - foreach (array_keys($switch->cases) as $key) { - if (isset($switch->cases[$key - 1]) && $switch->cases[$key - 1]->stmts === []) { + $processedCasesNumbers[] = $outerCaseKey; + + if ($outerCase->stmts === []) { + $result[] = $outerCase; continue; } - $nextCases = []; - for ($jumpToKey = $key + 1; $jumpToKey < $totalKeys; ++$jumpToKey) { - if (! isset($switch->cases[$jumpToKey])) { + /** @var array */ + $casesWithoutStmts = []; + + /** @var Case_[] */ + $equalCases = []; + + foreach ($switch->cases as $innerCaseKey => $innerCase) { + if (in_array($innerCaseKey, $processedCasesNumbers)) { continue; } - if (! $this->areSwitchStmtsEqualsAndWithBreak($switch->cases[$key], $switch->cases[$jumpToKey])) { + if ($innerCase->stmts === []) { + $casesWithoutStmts[$innerCaseKey] = $innerCase; continue; } - $nextCase = $switch->cases[$jumpToKey]; + if ($this->areSwitchStmtsEqualsAndWithBreak($outerCase, $innerCase)) { + if ($casesWithoutStmts !== []) { + foreach ($casesWithoutStmts as $caseWithoutStmtsKey => $caseWithoutStmts) { + $equalCases[] = $caseWithoutStmts; + $processedCasesNumbers[] = $caseWithoutStmtsKey; + } - if (isset($switch->cases[$jumpToKey - 1]) && $switch->cases[$jumpToKey - 1]->stmts === []) { - $nextCases[] = $switch->cases[$jumpToKey - 1]; - $conds[] = $switch->cases[$jumpToKey - 1]->cond; - } - - unset($switch->cases[$jumpToKey]); + $casesWithoutStmts = []; + } - $nextCases[] = $nextCase; + $innerCase->stmts = []; + $equalCases[] = $innerCase; + $processedCasesNumbers[] = $innerCaseKey; - $this->hasChanged = true; + $this->hasChanged = true; + } else { + $casesWithoutStmts = []; + } } - if ($nextCases === []) { + if ($equalCases === []) { + $result[] = $outerCase; continue; } - array_splice($switch->cases, $key + 1, 0, $nextCases); + $equalCases[array_key_last($equalCases)]->stmts = $outerCase->stmts; + $outerCase->stmts = []; - for ($jumpToKey = $key; $jumpToKey < $key + count($nextCases); ++$jumpToKey) { - $switch->cases[$jumpToKey]->stmts = []; - } - - $key += count($nextCases); + $result = array_merge($result, [$outerCase, ...$equalCases]); } - foreach ($conds as $keyCond => $cond) { - foreach (array_reverse($switch->cases, true) as $keyCase => $case) { - if ($this->nodeComparator->areNodesEqual($cond, $case->cond)) { - unset($switch->cases[$keyCase]); - unset($conds[$keyCond]); - - continue 2; - } - } - } + $switch->cases = $result; } private function areSwitchStmtsEqualsAndWithBreak(Case_ $currentCase, Case_ $nextCase): bool { + /** + * Skip multi no stmts + * @see rules-tests/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector/Fixture/skip_multi_no_stmts.php.inc + */ + if ($currentCase->stmts[0] instanceof Break_ && $nextCase->stmts[0] instanceof Break_) { + return $this->areSwitchStmtsEqualsConsideringComments($currentCase, $nextCase); + } + if (! $this->nodeComparator->areNodesEqual($currentCase->stmts, $nextCase->stmts)) { return false; } @@ -171,4 +196,9 @@ private function areSwitchStmtsEqualsAndWithBreak(Case_ $currentCase, Case_ $nex return false; } + + private function areSwitchStmtsEqualsConsideringComments(Case_ $currentCase, Case_ $nextCase): bool + { + return $this->betterStandardPrinter->print($currentCase->stmts) === $this->betterStandardPrinter->print($nextCase->stmts); + } }