4
4
5
5
namespace Symplify \PHPStanRules \Rules ;
6
6
7
+ use PhpParser \Node \Stmt \ClassMethod ;
7
8
use PhpParser \Node ;
8
- use PhpParser \Node \Expr ;
9
9
use PhpParser \Node \Expr \ArrayDimFetch ;
10
10
use PhpParser \Node \Expr \Assign ;
11
+ use PhpParser \Node \Expr \Closure ;
12
+ use PhpParser \Node \Stmt ;
13
+ use PhpParser \Node \Stmt \Else_ ;
11
14
use PhpParser \Node \Stmt \Expression ;
15
+ use PhpParser \Node \Stmt \Function_ ;
16
+ use PhpParser \Node \Stmt \If_ ;
12
17
use PHPStan \Analyser \Scope ;
13
18
use PHPStan \Rules \Rule ;
14
- use Symplify \Astral \ValueObject \AttributeKey ;
19
+ use PHPStan \Rules \RuleError ;
20
+ use PHPStan \Rules \RuleErrorBuilder ;
15
21
use Symplify \PHPStanRules \Printer \NodeComparator ;
16
22
use Symplify \RuleDocGenerator \Contract \DocumentedRuleInterface ;
17
23
use Symplify \RuleDocGenerator \ValueObject \CodeSample \CodeSample ;
18
24
use Symplify \RuleDocGenerator \ValueObject \RuleDefinition ;
19
25
20
26
/**
21
27
* @see \Symplify\PHPStanRules\Tests\Rules\NoMultiArrayAssignRule\NoMultiArrayAssignRuleTest
28
+ * @implements Rule<Node>
22
29
*/
23
30
final class NoMultiArrayAssignRule implements Rule, DocumentedRuleInterface
24
31
{
@@ -32,35 +39,49 @@ public function __construct(
32
39
) {
33
40
}
34
41
35
- /**
36
- * @return class-string<Node>
37
- */
38
42
public function getNodeType (): string
39
43
{
40
- return Assign ::class;
44
+ return Node ::class;
41
45
}
42
46
43
47
/**
44
- * @param Assign $node
45
- * @return string[]
48
+ * @return RuleError[]
46
49
*/
47
50
public function processNode (Node $ node , Scope $ scope ): array
48
51
{
49
- if (! $ node ->var instanceof ArrayDimFetch) {
52
+ // check all of stmts aware nodes, see https://github.com/nikic/PHP-Parser/pull/836
53
+ if (! $ node instanceof ClassMethod && ! $ node instanceof Function_ && ! $ node instanceof Closure && ! $ node instanceof If_ && ! $ node instanceof Else_) {
50
54
return [];
51
55
}
52
56
53
- // is previous array dim assign too? - print the exprt conteont
54
- $ previousArrayDimFetch = $ this ->matchParentArrayDimFetch ( $ node );
55
- if (! $ previousArrayDimFetch instanceof ArrayDimFetch) {
56
- return [] ;
57
- }
57
+ foreach (( array ) $ node -> stmts as $ key => $ stmt ) {
58
+ $ firstArrayDimFetch = $ this ->matchAssignToArrayDimFetch ( $ stmt );
59
+ if (! $ firstArrayDimFetch instanceof ArrayDimFetch) {
60
+ continue ;
61
+ }
58
62
59
- if (! $ this ->haveSameArrayDimFetchNonEmptyRoot ($ node ->var , $ previousArrayDimFetch )) {
60
- return [];
63
+ $ nextStmt = $ node ->stmts [$ key + 1 ] ?? null ;
64
+ if (! $ nextStmt instanceof Stmt) {
65
+ return [];
66
+ }
67
+
68
+ $ secondArrayDimFetch = $ this ->matchAssignToArrayDimFetch ($ nextStmt );
69
+ if (! $ secondArrayDimFetch instanceof ArrayDimFetch) {
70
+ continue ;
71
+ }
72
+
73
+ if (! $ this ->haveSameArrayDimFetchNonEmptyRoot ($ firstArrayDimFetch , $ secondArrayDimFetch )) {
74
+ continue ;
75
+ }
76
+
77
+ $ ruleError = RuleErrorBuilder::message (self ::ERROR_MESSAGE )
78
+ ->line ($ nextStmt ->getLine ())
79
+ ->build ();
80
+
81
+ return [$ ruleError ];
61
82
}
62
83
63
- return [self :: ERROR_MESSAGE ];
84
+ return [];
64
85
}
65
86
66
87
public function getRuleDefinition (): RuleDefinition
@@ -105,27 +126,21 @@ private function resolveSingleNestedArrayDimFetch(ArrayDimFetch $arrayDimFetch):
105
126
return $ arrayDimFetch ;
106
127
}
107
128
108
- private function matchParentArrayDimFetch ( Assign $ assign ): ?Expr
129
+ private function matchAssignToArrayDimFetch ( Stmt $ stmt ): ?ArrayDimFetch
109
130
{
110
- $ parent = $ assign ->getAttribute (AttributeKey::PARENT );
111
- if (! $ parent instanceof Expression) {
112
- return null ;
113
- }
114
-
115
- $ previous = $ parent ->getAttribute (AttributeKey::PREVIOUS );
116
- if (! $ previous instanceof Expression) {
131
+ if (! $ stmt instanceof Expression) {
117
132
return null ;
118
133
}
119
134
120
- if (! $ previous ->expr instanceof Assign) {
135
+ if (! $ stmt ->expr instanceof Assign) {
121
136
return null ;
122
137
}
123
138
124
- $ previousAssign = $ previous ->expr ;
125
- if (! $ previousAssign ->var instanceof ArrayDimFetch) {
139
+ $ assign = $ stmt ->expr ;
140
+ if (! $ assign ->var instanceof ArrayDimFetch) {
126
141
return null ;
127
142
}
128
143
129
- return $ previousAssign ->var ;
144
+ return $ assign ->var ;
130
145
}
131
146
}
0 commit comments