2
2
3
3
namespace PHPStan \Rules \Comparison ;
4
4
5
+ use PhpParser \Node \Expr \BinaryOp \BooleanOr ;
6
+ use PHPStan \Node \BooleanOrNode ;
5
7
use PHPStan \Rules \RuleErrorBuilder ;
6
8
use PHPStan \Type \Constant \ConstantBooleanType ;
7
9
8
10
/**
9
- * @implements \PHPStan\Rules\Rule<\PhpParser\Node\Expr\BinaryOp\BooleanOr >
11
+ * @implements \PHPStan\Rules\Rule<BooleanOrNode >
10
12
*/
11
13
class BooleanOrConstantConditionRule implements \PHPStan \Rules \Rule
12
14
{
@@ -15,35 +17,44 @@ class BooleanOrConstantConditionRule implements \PHPStan\Rules\Rule
15
17
16
18
private bool $ treatPhpDocTypesAsCertain ;
17
19
20
+ private bool $ checkLogicalOrConstantCondition ;
21
+
18
22
public function __construct (
19
23
ConstantConditionRuleHelper $ helper ,
20
- bool $ treatPhpDocTypesAsCertain
24
+ bool $ treatPhpDocTypesAsCertain ,
25
+ bool $ checkLogicalOrConstantCondition
21
26
)
22
27
{
23
28
$ this ->helper = $ helper ;
24
29
$ this ->treatPhpDocTypesAsCertain = $ treatPhpDocTypesAsCertain ;
30
+ $ this ->checkLogicalOrConstantCondition = $ checkLogicalOrConstantCondition ;
25
31
}
26
32
27
33
public function getNodeType (): string
28
34
{
29
- return \ PhpParser \ Node \ Expr \ BinaryOp \BooleanOr ::class;
35
+ return BooleanOrNode ::class;
30
36
}
31
37
32
38
public function processNode (
33
39
\PhpParser \Node $ node ,
34
40
\PHPStan \Analyser \Scope $ scope
35
41
): array
36
42
{
43
+ $ originalNode = $ node ->getOriginalNode ();
44
+ if (!$ originalNode instanceof BooleanOr && !$ this ->checkLogicalOrConstantCondition ) {
45
+ return [];
46
+ }
47
+
37
48
$ messages = [];
38
- $ leftType = $ this ->helper ->getBooleanType ($ scope , $ node ->left );
49
+ $ leftType = $ this ->helper ->getBooleanType ($ scope , $ originalNode ->left );
39
50
$ tipText = 'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>. ' ;
40
51
if ($ leftType instanceof ConstantBooleanType) {
41
- $ addTipLeft = function (RuleErrorBuilder $ ruleErrorBuilder ) use ($ scope , $ node , $ tipText ): RuleErrorBuilder {
52
+ $ addTipLeft = function (RuleErrorBuilder $ ruleErrorBuilder ) use ($ scope , $ originalNode , $ tipText ): RuleErrorBuilder {
42
53
if (!$ this ->treatPhpDocTypesAsCertain ) {
43
54
return $ ruleErrorBuilder ;
44
55
}
45
56
46
- $ booleanNativeType = $ this ->helper ->getNativeBooleanType ($ scope , $ node ->left );
57
+ $ booleanNativeType = $ this ->helper ->getNativeBooleanType ($ scope , $ originalNode ->left );
47
58
if ($ booleanNativeType instanceof ConstantBooleanType) {
48
59
return $ ruleErrorBuilder ;
49
60
}
@@ -53,22 +64,23 @@ public function processNode(
53
64
$ messages [] = $ addTipLeft (RuleErrorBuilder::message (sprintf (
54
65
'Left side of || is always %s. ' ,
55
66
$ leftType ->getValue () ? 'true ' : 'false '
56
- )))->line ($ node ->left ->getLine ())->build ();
67
+ )))->line ($ originalNode ->left ->getLine ())->build ();
57
68
}
58
69
70
+ $ rightScope = $ node ->getRightScope ();
59
71
$ rightType = $ this ->helper ->getBooleanType (
60
- $ scope -> filterByFalseyValue ( $ node -> left ) ,
61
- $ node ->right
72
+ $ rightScope ,
73
+ $ originalNode ->right
62
74
);
63
75
if ($ rightType instanceof ConstantBooleanType) {
64
- $ addTipRight = function (RuleErrorBuilder $ ruleErrorBuilder ) use ($ scope , $ node , $ tipText ): RuleErrorBuilder {
76
+ $ addTipRight = function (RuleErrorBuilder $ ruleErrorBuilder ) use ($ rightScope , $ originalNode , $ tipText ): RuleErrorBuilder {
65
77
if (!$ this ->treatPhpDocTypesAsCertain ) {
66
78
return $ ruleErrorBuilder ;
67
79
}
68
80
69
81
$ booleanNativeType = $ this ->helper ->getNativeBooleanType (
70
- $ scope ->doNotTreatPhpDocTypesAsCertain ()-> filterByFalseyValue ( $ node -> left ),
71
- $ node ->right
82
+ $ rightScope ->doNotTreatPhpDocTypesAsCertain (),
83
+ $ originalNode ->right
72
84
);
73
85
if ($ booleanNativeType instanceof ConstantBooleanType) {
74
86
return $ ruleErrorBuilder ;
@@ -79,18 +91,18 @@ public function processNode(
79
91
$ messages [] = $ addTipRight (RuleErrorBuilder::message (sprintf (
80
92
'Right side of || is always %s. ' ,
81
93
$ rightType ->getValue () ? 'true ' : 'false '
82
- )))->line ($ node ->right ->getLine ())->build ();
94
+ )))->line ($ originalNode ->right ->getLine ())->build ();
83
95
}
84
96
85
97
if (count ($ messages ) === 0 ) {
86
- $ nodeType = $ scope ->getType ($ node );
98
+ $ nodeType = $ scope ->getType ($ originalNode );
87
99
if ($ nodeType instanceof ConstantBooleanType) {
88
- $ addTip = function (RuleErrorBuilder $ ruleErrorBuilder ) use ($ scope , $ node , $ tipText ): RuleErrorBuilder {
100
+ $ addTip = function (RuleErrorBuilder $ ruleErrorBuilder ) use ($ scope , $ originalNode , $ tipText ): RuleErrorBuilder {
89
101
if (!$ this ->treatPhpDocTypesAsCertain ) {
90
102
return $ ruleErrorBuilder ;
91
103
}
92
104
93
- $ booleanNativeType = $ scope ->doNotTreatPhpDocTypesAsCertain ()->getType ($ node );
105
+ $ booleanNativeType = $ scope ->doNotTreatPhpDocTypesAsCertain ()->getType ($ originalNode );
94
106
if ($ booleanNativeType instanceof ConstantBooleanType) {
95
107
return $ ruleErrorBuilder ;
96
108
}
0 commit comments