1: | <?php |
2: | |
3: | declare(strict_types=1); |
4: | |
5: | |
6: | |
7: | |
8: | |
9: | |
10: | |
11: | |
12: | |
13: | |
14: | namespace Nexus\PHPStan\Rules\CleanCode; |
15: | |
16: | use PhpParser\Node; |
17: | use PHPStan\Analyser\Scope; |
18: | use PHPStan\Rules\IdentifierRuleError; |
19: | use PHPStan\Rules\Rule; |
20: | use PHPStan\Rules\RuleErrorBuilder; |
21: | |
22: | |
23: | |
24: | |
25: | final class AssignExprInCondRule implements Rule |
26: | { |
27: | public function getNodeType(): string |
28: | { |
29: | return Node\Stmt::class; |
30: | } |
31: | |
32: | public function processNode(Node $node, Scope $scope): array |
33: | { |
34: | if ($node instanceof Node\Stmt\If_) { |
35: | return $this->processExprCond($node->cond, 'an if'); |
36: | } |
37: | |
38: | if ($node instanceof Node\Stmt\ElseIf_) { |
39: | return $this->processExprCond($node->cond, 'an elseif'); |
40: | } |
41: | |
42: | if ($node instanceof Node\Stmt\While_) { |
43: | return $this->processExprCond($node->cond, 'a while'); |
44: | } |
45: | |
46: | if ($node instanceof Node\Stmt\Do_) { |
47: | return $this->processExprCond($node->cond, 'a do-while'); |
48: | } |
49: | |
50: | return []; |
51: | } |
52: | |
53: | |
54: | |
55: | |
56: | private function processExprCond(Node\Expr $cond, string $stmt): array |
57: | { |
58: | if ($cond instanceof Node\Expr\Assign) { |
59: | return [ |
60: | RuleErrorBuilder::message(\sprintf( |
61: | 'Assignment inside %s condition is not allowed.', |
62: | $stmt, |
63: | )) |
64: | ->identifier('nexus.assignInCond') |
65: | ->line($cond->getStartLine()) |
66: | ->build(), |
67: | ]; |
68: | } |
69: | |
70: | if ($cond instanceof Node\Expr\AssignRef) { |
71: | return [ |
72: | RuleErrorBuilder::message(\sprintf( |
73: | 'Assignment by reference inside %s condition is not allowed.', |
74: | $stmt, |
75: | )) |
76: | ->identifier('nexus.assignRefInCond') |
77: | ->line($cond->getStartLine()) |
78: | ->build(), |
79: | ]; |
80: | } |
81: | |
82: | if ($cond instanceof Node\Expr\AssignOp) { |
83: | if ( |
84: | $cond instanceof Node\Expr\AssignOp\BitwiseAnd |
85: | || $cond instanceof Node\Expr\AssignOp\BitwiseOr |
86: | || $cond instanceof Node\Expr\AssignOp\BitwiseXor |
87: | || $cond instanceof Node\Expr\AssignOp\ShiftLeft |
88: | || $cond instanceof Node\Expr\AssignOp\ShiftRight |
89: | ) { |
90: | return [ |
91: | RuleErrorBuilder::message(\sprintf( |
92: | 'Bitwise assignment inside %s condition is not allowed.', |
93: | $stmt, |
94: | )) |
95: | ->identifier('nexus.bitwiseAssignInCond') |
96: | ->line($cond->getStartLine()) |
97: | ->build(), |
98: | ]; |
99: | } |
100: | |
101: | if ($cond instanceof Node\Expr\AssignOp\Coalesce) { |
102: | return [ |
103: | RuleErrorBuilder::message(\sprintf( |
104: | 'Null-coalesce assignment inside %s condition is not allowed.', |
105: | $stmt, |
106: | )) |
107: | ->identifier('nexus.nullCoalesceAssignInCond') |
108: | ->line($cond->getStartLine()) |
109: | ->build(), |
110: | ]; |
111: | } |
112: | |
113: | if ($cond instanceof Node\Expr\AssignOp\Concat) { |
114: | return [ |
115: | RuleErrorBuilder::message(\sprintf( |
116: | 'Concatenation assignment inside %s condition is not allowed.', |
117: | $stmt, |
118: | )) |
119: | ->identifier('nexus.concatenationAssignInCond') |
120: | ->line($cond->getStartLine()) |
121: | ->build(), |
122: | ]; |
123: | } |
124: | |
125: | return [ |
126: | RuleErrorBuilder::message(\sprintf( |
127: | 'Arithmetic assignment inside %s condition is not allowed.', |
128: | $stmt, |
129: | )) |
130: | ->identifier('nexus.arithmeticAssignInCond') |
131: | ->line($cond->getStartLine()) |
132: | ->build(), |
133: | ]; |
134: | } |
135: | |
136: | return []; |
137: | } |
138: | } |
139: | |