Skip to content

Commit

Permalink
implemented 🎉
Browse files Browse the repository at this point in the history
  • Loading branch information
samsonasik committed Nov 9, 2023
1 parent bbc4fa3 commit 21da091
Showing 1 changed file with 75 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/
final class RemoveDuplicatedCaseInSwitchRector extends AbstractRector
{
private bool $hasChanged = false;

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
Expand Down Expand Up @@ -82,28 +84,90 @@ public function refactor(Node $node): ?Node
return null;
}

$this->hasChanged = false;

$insertByKeys = $this->resolveInsertedByKeys($node);
$this->insertCaseByKeys($node, $insertByKeys);
$this->cleanUpEqualCaseStmts($node);

if (! $this->hasChanged) {
return null;
}

return $node;
}

/**
* @return array<int, array<int, Case_>>
*/
private function resolveInsertedByKeys(Switch_ $switch): array
{
$totalKeys = count($switch->cases);
$insertByKeys = [];

foreach ($switch->cases as $key => $case) {
if ($case->stmts === []) {
continue;
}

$nextKey = $key + 1;
for ($jumpToKey = $key + 1; $jumpToKey < $totalKeys; ++$jumpToKey) {
if (! isset($switch->cases[$jumpToKey])) {
continue;
}

if (! $this->areSwitchStmtsEqualsAndWithBreak($case, $switch->cases[$jumpToKey])) {
continue;
}

if ($nextKey === $jumpToKey) {
continue 2;
}

$nextCase = $switch->cases[$jumpToKey];

unset($switch->cases[$jumpToKey]);

$insertByKeys[$key][] = $nextCase;

$this->hasChanged = true;
}
}

return $insertByKeys;
}

/**
* @param array<int, array<int, Case_>> $insertByKeys
*/
private function insertCaseByKeys(Switch_ $switch, array $insertByKeys): void
{
foreach ($insertByKeys as $key => $insertByKey) {
$switch->cases[$key]->stmts = [];
$nextKey = $key + 1;

array_splice($switch->cases, $nextKey, 0, $insertByKey);
}
}

private function cleanUpEqualCaseStmts(Switch_ $switch): void
{
/** @var Case_|null $previousCase */
$previousCase = null;
$hasChanged = false;
foreach ($node->cases as $case) {
foreach ($switch->cases as $case) {
if ($previousCase instanceof Case_ && $this->areSwitchStmtsEqualsAndWithBreak($case, $previousCase)) {
$previousCase->stmts = [];
$hasChanged = true;

$this->hasChanged = true;
}

$previousCase = $case;
}

if (! $hasChanged) {
return null;
}

return $node;
}

private function areSwitchStmtsEqualsAndWithBreak(Case_ $currentCase, Case_ $previousCase): bool
private function areSwitchStmtsEqualsAndWithBreak(Case_ $currentCase, Case_ $nextCase): bool
{
if (! $this->nodeComparator->areNodesEqual($currentCase->stmts, $previousCase->stmts)) {
if (! $this->nodeComparator->areNodesEqual($currentCase->stmts, $nextCase->stmts)) {
return false;
}

Expand Down

0 comments on commit 21da091

Please sign in to comment.