Skip to content

Commit 9d276aa

Browse files
committed
Add rector to reduce known boolean and forms
1 parent fc872f4 commit 9d276aa

2 files changed

Lines changed: 106 additions & 0 deletions

File tree

rector.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
require_once __DIR__ . '/util/rector/RemoveAlwaysFalseIfStatementRector.php';
44
require_once __DIR__ . '/util/rector/RemoveAlwaysTrueIfConditionRector2.php';
5+
require_once __DIR__ . '/util/rector/ReduceKnownBooleanAnd.php';
56
require_once __DIR__ . '/util/rector/ReplaceKnownDefinedWithBooleanRector.php';
67
require_once __DIR__ . '/util/rector/ReplaceNegatedBooleanRector.php';
78

@@ -17,6 +18,7 @@
1718
use Rector\Php53\Rector\Ternary\TernaryToElvisRector;
1819
use Rector\Set\ValueObject\SetList;
1920
use Rector\Transform\Rector\BooleanNot\ReplaceNegatedBooleanRector;
21+
use StaticDeploy\Rector\ReduceKnownBooleanAnd;
2022

2123
// Search rules at https://getrector.com/find-rule
2224

@@ -39,6 +41,7 @@
3941
[
4042
RemoveAlwaysFalseIfStatementRector::class,
4143
RemoveAlwaysTrueIfConditionRector2::class,
44+
ReduceKnownBooleanAnd::class,
4245
ReplaceKnownDefinedWithBooleanRector::class,
4346
ReplaceNegatedBooleanRector::class,
4447
]
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace StaticDeploy\Rector;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Expr;
9+
use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
10+
use PhpParser\Node\Expr\ConstFetch;
11+
use PhpParser\Node\Name;
12+
use Rector\DeadCode\NodeAnalyzer\SafeLeftTypeBooleanAndOrAnalyzer;
13+
use Rector\PhpParser\Node\Value\ValueResolver;
14+
use Rector\Rector\AbstractRector;
15+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
16+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
17+
18+
final class ReduceKnownBooleanAnd extends AbstractRector
19+
{
20+
public function __construct(
21+
private readonly SafeLeftTypeBooleanAndOrAnalyzer $safeLeftTypeBooleanAndOrAnalyzer,
22+
private readonly ValueResolver $valueResolver
23+
) {
24+
}
25+
26+
public function getRuleDefinition(): RuleDefinition
27+
{
28+
return new RuleDefinition('Remove `and true` that has no added value', [
29+
new CodeSample(
30+
<<<'CODE_SAMPLE'
31+
class SomeClass
32+
{
33+
public function run()
34+
{
35+
return true && 5 === 1;
36+
}
37+
}
38+
CODE_SAMPLE
39+
,
40+
<<<'CODE_SAMPLE'
41+
class SomeClass
42+
{
43+
public function run()
44+
{
45+
return 5 === 1;
46+
}
47+
}
48+
CODE_SAMPLE
49+
),
50+
]);
51+
}
52+
53+
/**
54+
* @return array<class-string<Node>>
55+
*/
56+
public function getNodeTypes(): array
57+
{
58+
return [BooleanAnd::class];
59+
}
60+
61+
/**
62+
* @param BooleanAnd $node
63+
*/
64+
public function refactor(Node $node): ?Node
65+
{
66+
if ($this->isTrueOrBooleanAndTrues($node->right)) {
67+
return $node->left;
68+
}
69+
70+
if (! $this->safeLeftTypeBooleanAndOrAnalyzer->isSafe($node)) {
71+
return null;
72+
}
73+
74+
$conditionStaticType = $this->getType($node->left);
75+
76+
if ($conditionStaticType->isFalse()->yes()) {
77+
return new ConstFetch(new Name('false'));
78+
}
79+
80+
if ($conditionStaticType->isTrue()->yes()) {
81+
return $node->right;
82+
}
83+
84+
return null;
85+
}
86+
87+
private function isTrueOrBooleanAndTrues(Expr $expr): bool
88+
{
89+
if ($this->valueResolver->isTrue($expr)) {
90+
return true;
91+
}
92+
93+
if (! $expr instanceof BooleanAnd) {
94+
return false;
95+
}
96+
97+
if (! $this->isTrueOrBooleanAndTrues($expr->left)) {
98+
return false;
99+
}
100+
101+
return $this->isTrueOrBooleanAndTrues($expr->right);
102+
}
103+
}

0 commit comments

Comments
 (0)