15
15
use PhpParser \Node \Expr \Assign ;
16
16
use PhpParser \Node \Expr \BinaryOp ;
17
17
use PhpParser \Node \Expr \CallLike ;
18
- use PhpParser \Node \Expr \Cast ;
19
18
use PhpParser \Node \Expr \Closure ;
20
19
use PhpParser \Node \Expr \Match_ ;
21
20
use PhpParser \Node \Expr \MethodCall ;
22
21
use PhpParser \Node \Expr \NullsafePropertyFetch ;
22
+ use PhpParser \Node \Expr \Print_ ;
23
23
use PhpParser \Node \Expr \PropertyFetch ;
24
24
use PhpParser \Node \Expr \StaticPropertyFetch ;
25
25
use PhpParser \Node \Expr \Ternary ;
35
35
use PhpParser \Node \Stmt \Echo_ ;
36
36
use PhpParser \Node \Stmt \Else_ ;
37
37
use PhpParser \Node \Stmt \ElseIf_ ;
38
- use PhpParser \Node \Stmt \Expression ;
39
38
use PhpParser \Node \Stmt \Finally_ ;
40
39
use PhpParser \Node \Stmt \For_ ;
41
40
use PhpParser \Node \Stmt \Foreach_ ;
@@ -67,12 +66,16 @@ final class ExecutableLinesFindingVisitor extends NodeVisitorAbstract
67
66
private $ propertyLines = [];
68
67
69
68
/**
70
- * @psalm-var array<int, Return_>
69
+ * @psalm-var array<int, Return_|Assign|Array_ >
71
70
*/
72
71
private $ returns = [];
73
72
74
73
public function enterNode (Node $ node ): void
75
74
{
75
+ if (!$ node instanceof NodeAbstract) {
76
+ return ;
77
+ }
78
+
76
79
$ this ->savePropertyLines ($ node );
77
80
78
81
if (!$ this ->isExecutable ($ node )) {
@@ -111,17 +114,23 @@ private function savePropertyLines(Node $node): void
111
114
112
115
private function computeReturns (): void
113
116
{
114
- foreach ($ this ->returns as $ return ) {
115
- foreach (range ($ return ->getStartLine (), $ return ->getEndLine ()) as $ loc ) {
116
- if (isset ($ this ->executableLines [$ loc ])) {
117
+ foreach ($ this ->returns as $ node ) {
118
+ foreach (range ($ node ->getStartLine (), $ node ->getEndLine ()) as $ index ) {
119
+ if (isset ($ this ->executableLines [$ index ])) {
117
120
continue 2 ;
118
121
}
119
122
}
120
123
121
- if ($ return ->expr !== null ) {
122
- $ line = $ this ->getNodeStartLine ($ return ->expr );
124
+ if ($ node instanceof Return_) {
125
+ if ($ node ->expr === null ) {
126
+ $ line = $ node ->getEndLine ();
127
+ } else {
128
+ $ line = $ this ->getNodeStartLine ($ node ->expr );
129
+ }
130
+ } elseif ($ node instanceof Assign) {
131
+ $ line = $ this ->getNodeStartLine ($ node ->expr );
123
132
} else {
124
- $ line = $ return -> getEndLine ( );
133
+ $ line = $ this -> getNodeStartLine ( $ node );
125
134
}
126
135
127
136
$ this ->executableLines [$ line ] = $ line ;
@@ -131,33 +140,26 @@ private function computeReturns(): void
131
140
/**
132
141
* @return int[]
133
142
*/
134
- private function getLines (Node $ node ): array
143
+ private function getLines (NodeAbstract $ node ): array
135
144
{
145
+ if ($ node instanceof Return_ || $ node instanceof Assign || $ node instanceof Array_) {
146
+ $ this ->returns [] = $ node ;
147
+
148
+ return [];
149
+ }
150
+
136
151
if ($ node instanceof BinaryOp) {
137
152
return [];
138
153
}
139
154
140
- if ($ node instanceof Cast ||
141
- $ node instanceof PropertyFetch ||
155
+ if ($ node instanceof PropertyFetch ||
142
156
$ node instanceof NullsafePropertyFetch ||
143
157
$ node instanceof StaticPropertyFetch) {
144
- return [$ node -> getEndLine ( )];
158
+ return [$ this -> getNodeStartLine ( $ node -> name )];
145
159
}
146
160
147
- if ($ node instanceof ArrayDimFetch) {
148
- if (null === $ node ->dim ) {
149
- return [];
150
- }
151
-
152
- return [$ node ->dim ->getStartLine ()];
153
- }
154
-
155
- if ($ node instanceof Array_) {
156
- if ([] === $ node ->items ) {
157
- return [$ node ->getEndLine ()];
158
- }
159
-
160
- return [];
161
+ if ($ node instanceof ArrayDimFetch && null !== $ node ->dim ) {
162
+ return [$ this ->getNodeStartLine ($ node ->dim )];
161
163
}
162
164
163
165
if ($ node instanceof ClassMethod) {
@@ -185,49 +187,45 @@ private function getLines(Node $node): array
185
187
}
186
188
187
189
if ($ node instanceof MethodCall) {
188
- return [$ node -> name -> getStartLine ( )];
190
+ return [$ this -> getNodeStartLine ( $ node -> name )];
189
191
}
190
192
191
193
if ($ node instanceof Ternary) {
192
- $ lines = [$ node -> cond -> getStartLine ( )];
194
+ $ lines = [$ this -> getNodeStartLine ( $ node -> cond )];
193
195
194
196
if (null !== $ node ->if ) {
195
- $ lines [] = $ node -> if -> getStartLine ( );
197
+ $ lines [] = $ this -> getNodeStartLine ( $ node -> if );
196
198
}
197
199
198
- $ lines [] = $ node -> else -> getStartLine ( );
200
+ $ lines [] = $ this -> getNodeStartLine ( $ node -> else );
199
201
200
202
return $ lines ;
201
203
}
202
204
203
205
if ($ node instanceof Match_) {
204
- return [$ node -> cond -> getStartLine ( )];
206
+ return [$ this -> getNodeStartLine ( $ node -> cond )];
205
207
}
206
208
207
209
if ($ node instanceof MatchArm) {
208
- return [$ node -> body -> getStartLine ( )];
210
+ return [$ this -> getNodeStartLine ( $ node -> body )];
209
211
}
210
212
211
- if ($ node instanceof Expression && (
212
- $ node ->expr instanceof Cast ||
213
- $ node ->expr instanceof Match_ ||
214
- $ node ->expr instanceof MethodCall
215
- )) {
216
- return [];
213
+ // TODO this concept should be extended for every statement class like Foreach_
214
+ if ($ node instanceof If_ ||
215
+ $ node instanceof ElseIf_) {
216
+ return [$ this ->getNodeStartLine ($ node ->cond )];
217
217
}
218
218
219
- if ($ node instanceof Return_) {
220
- $ this ->returns [] = $ node ;
221
-
222
- return [];
223
- }
224
-
225
- return [$ node ->getStartLine ()];
219
+ return [$ this ->getNodeStartLine ($ node )];
226
220
}
227
221
228
222
private function getNodeStartLine (NodeAbstract $ node ): int
229
223
{
230
- if ($ node instanceof Node \Expr \BooleanNot) {
224
+ if ($ node instanceof Node \Expr \Cast ||
225
+ $ node instanceof Node \Expr \BooleanNot ||
226
+ $ node instanceof Node \Expr \UnaryMinus ||
227
+ $ node instanceof Node \Expr \UnaryPlus
228
+ ) {
231
229
return $ this ->getNodeStartLine ($ node ->expr );
232
230
}
233
231
@@ -242,19 +240,25 @@ private function getNodeStartLine(NodeAbstract $node): int
242
240
return $ node ->getStartLine () + 1 ;
243
241
}
244
242
245
- return $ node ->getStartLine ();
243
+ if ($ node instanceof Array_) {
244
+ if ([] === $ node ->items || $ node ->items [0 ] === null ) {
245
+ return $ node ->getEndLine ();
246
+ }
247
+
248
+ return $ this ->getNodeStartLine ($ node ->items [0 ]);
249
+ }
250
+
251
+ return $ node ->getStartLine (); // $node should be only a scalar here
246
252
}
247
253
248
254
private function isExecutable (Node $ node ): bool
249
255
{
250
256
return $ node instanceof Assign ||
251
257
$ node instanceof ArrayDimFetch ||
252
- $ node instanceof Array_ ||
253
258
$ node instanceof BinaryOp ||
254
259
$ node instanceof Break_ ||
255
260
$ node instanceof CallLike ||
256
261
$ node instanceof Case_ ||
257
- $ node instanceof Cast ||
258
262
$ node instanceof Catch_ ||
259
263
$ node instanceof ClassMethod ||
260
264
$ node instanceof Closure ||
@@ -264,7 +268,6 @@ private function isExecutable(Node $node): bool
264
268
$ node instanceof ElseIf_ ||
265
269
$ node instanceof Else_ ||
266
270
$ node instanceof Encapsed ||
267
- $ node instanceof Expression ||
268
271
$ node instanceof Finally_ ||
269
272
$ node instanceof For_ ||
270
273
$ node instanceof Foreach_ ||
@@ -274,6 +277,7 @@ private function isExecutable(Node $node): bool
274
277
$ node instanceof MatchArm ||
275
278
$ node instanceof MethodCall ||
276
279
$ node instanceof NullsafePropertyFetch ||
280
+ $ node instanceof Print_ ||
277
281
$ node instanceof PropertyFetch ||
278
282
$ node instanceof Return_ ||
279
283
$ node instanceof StaticPropertyFetch ||
0 commit comments