Skip to content

Commit 03af320

Browse files
committed
[CodeQuality] Parenthesize assignments nested under unary/binary operators in LogicalToBooleanRector (#9807, #9808)
1 parent 653ec23 commit 03af320

6 files changed

Lines changed: 99 additions & 0 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
$x = 0;
4+
2 * $x += 42 and true;
5+
6+
?>
7+
-----
8+
<?php
9+
10+
$x = 0;
11+
2 * ($x += 42) && true;
12+
13+
?>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
$s = 0;
4+
2 * ($s += 42) and true;
5+
6+
?>
7+
-----
8+
<?php
9+
10+
$s = 0;
11+
2 * ($s += 42) && true;
12+
13+
?>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
$t = 0;
4+
(int) $t = 42 and true;
5+
6+
?>
7+
-----
8+
<?php
9+
10+
$t = 0;
11+
(int) ($t = 42) && true;
12+
13+
?>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
$z = 0;
4+
-$z += 42 and true;
5+
6+
?>
7+
-----
8+
<?php
9+
10+
$z = 0;
11+
-($z += 42) && true;
12+
13+
?>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
$y = 0;
4+
!$y = 42 and true;
5+
6+
?>
7+
-----
8+
<?php
9+
10+
$y = 0;
11+
!($y = 42) && true;
12+
13+
?>

rules/CodeQuality/Rector/LogicalAnd/LogicalToBooleanRector.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,22 @@
55
namespace Rector\CodeQuality\Rector\LogicalAnd;
66

77
use PhpParser\Node;
8+
use PhpParser\Node\Expr;
89
use PhpParser\Node\Expr\Assign;
10+
use PhpParser\Node\Expr\AssignOp;
11+
use PhpParser\Node\Expr\AssignRef;
12+
use PhpParser\Node\Expr\BinaryOp;
913
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
1014
use PhpParser\Node\Expr\BinaryOp\BooleanOr;
1115
use PhpParser\Node\Expr\BinaryOp\LogicalAnd;
1216
use PhpParser\Node\Expr\BinaryOp\LogicalOr;
17+
use PhpParser\Node\Expr\BitwiseNot;
18+
use PhpParser\Node\Expr\BooleanNot;
19+
use PhpParser\Node\Expr\Cast;
20+
use PhpParser\Node\Expr\ErrorSuppress;
21+
use PhpParser\Node\Expr\UnaryMinus;
22+
use PhpParser\Node\Expr\UnaryPlus;
23+
use Rector\NodeTypeResolver\Node\AttributeKey;
1324
use Rector\Rector\AbstractRector;
1425
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
1526
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@@ -74,10 +85,33 @@ private function refactorLogicalToBoolean(LogicalOr|LogicalAnd $node): BooleanAn
7485
$node->right = $this->refactorLogicalToBoolean($node->right);
7586
}
7687

88+
// "and"/"or" bind looser than "="/"+="; once they become "&&"/"||" the assignment must be
89+
// re-printed so the pretty-printer re-adds the parentheses that keep the original semantics
90+
$this->reprintNestedAssign($node->left);
91+
$this->reprintNestedAssign($node->right);
92+
7793
if ($node instanceof LogicalOr) {
7894
return new BooleanOr($node->left, $node->right);
7995
}
8096

8197
return new BooleanAnd($node->left, $node->right);
8298
}
99+
100+
private function reprintNestedAssign(Expr $expr): void
101+
{
102+
if ($expr instanceof Assign || $expr instanceof AssignOp || $expr instanceof AssignRef) {
103+
$expr->setAttribute(AttributeKey::ORIGINAL_NODE, null);
104+
return;
105+
}
106+
107+
if ($expr instanceof BooleanNot || $expr instanceof BitwiseNot || $expr instanceof UnaryMinus || $expr instanceof UnaryPlus || $expr instanceof ErrorSuppress || $expr instanceof Cast) {
108+
$this->reprintNestedAssign($expr->expr);
109+
return;
110+
}
111+
112+
if ($expr instanceof BinaryOp) {
113+
$this->reprintNestedAssign($expr->left);
114+
$this->reprintNestedAssign($expr->right);
115+
}
116+
}
83117
}

0 commit comments

Comments
 (0)