Skip to content

Commit

Permalink
Fix for Match to Switch when inside binary operation (#263)
Browse files Browse the repository at this point in the history
* working test

* Working fix

* rector fix

* fixes
  • Loading branch information
peterfox authored Jan 11, 2025
1 parent f9cc5a0 commit dd8086f
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\ArrayItem;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrowFunction;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\BinaryOp;
use PhpParser\Node\Expr\CallLike;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\Match_;
Expand Down Expand Up @@ -294,7 +296,11 @@ private function createSwitchStmts(
} elseif ($matchArm->body instanceof Throw_) {
$stmts[] = new Expression($matchArm->body);
} elseif ($node instanceof Return_) {
$stmts[] = new Return_($matchArm->body);
if ($node->expr instanceof BinaryOp) {
$stmts[] = $this->replicateBinaryOp($node->expr, $matchArm->body);
} else {
$stmts[] = new Return_($matchArm->body);
}
} elseif ($node instanceof Echo_) {
$stmts[] = new Echo_([$matchArm->body]);
$stmts[] = new Break_();
Expand All @@ -314,4 +320,19 @@ private function createSwitchStmts(

return $stmts;
}

private function replicateBinaryOp(BinaryOp $binaryOp, Expr $expr): Return_
{
$newExpr = clone $binaryOp;
// remove the match statement from the binary operation
$this->traverseNodesWithCallable($newExpr, static function (Node $node) use ($expr): ?Expr {
if ($node instanceof Match_) {
return $expr;
}

return null;
});

return new Return_($newExpr);
}
}
53 changes: 53 additions & 0 deletions tests/Set/Fixture/match_in_binary_op.php.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Rector\Tests\Set\Fixture;

final class MatchInBinaryOp
{
public function run($value, $booleanFlag)
{
return match (true) {
$value === 2 => true,
default => false,
} && $booleanFlag;
}

public function runTwo($value, $booleanFlag)
{
return match (true) {
$value === 2 => true,
default => false,
} || $booleanFlag;
}
}

?>
-----
<?php

namespace Rector\Tests\Set\Fixture;

final class MatchInBinaryOp
{
public function run($value, $booleanFlag)
{
switch (true) {
case $value === 2:
return true && $booleanFlag;
default:
return false && $booleanFlag;
}
}

public function runTwo($value, $booleanFlag)
{
switch (true) {
case $value === 2:
return true || $booleanFlag;
default:
return false || $booleanFlag;
}
}
}

?>

0 comments on commit dd8086f

Please sign in to comment.