PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 6.3.0
Defender Security – Malware Scanner, Login Security & Firewall v6.3.0
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
← All changes | src/extra/php-codesniffer-php-token/Tokenizers/PHP.php +2003 -1998 3.0.1 → 6.3.0 View file →
@@ -10,512 +10,510 @@
10 10 namespace PHP_CodeSniffer\Tokenizers;
11 11
12 12 use PHP_CodeSniffer\Util;
13 13
14 -class PHP extends Tokenizer
15 -{
14 +class PHP extends Tokenizer {
16 15
17 - /**
18 - * A list of tokens that are allowed to open a scope.
19 - *
20 - * This array also contains information about what kind of token the scope
21 - * opener uses to open and close the scope, if the token strictly requires
22 - * an opener, if the token can share a scope closer, and who it can be shared
23 - * with. An example of a token that shares a scope closer is a CASE scope.
24 - *
25 - * @var array
26 - */
27 - public $scopeOpeners = [
28 - T_IF => [
29 - 'start' => [
30 - T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
31 - T_COLON => T_COLON,
32 - ],
33 - 'end' => [
34 - T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
35 - T_ENDIF => T_ENDIF,
36 - T_ELSE => T_ELSE,
37 - T_ELSEIF => T_ELSEIF,
38 - ],
39 - 'strict' => false,
40 - 'shared' => false,
41 - 'with' => [
42 - T_ELSE => T_ELSE,
43 - T_ELSEIF => T_ELSEIF,
44 - ],
45 - ],
46 - T_TRY => [
47 - 'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
48 - 'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
49 - 'strict' => true,
50 - 'shared' => false,
51 - 'with' => [],
52 - ],
53 - T_CATCH => [
54 - 'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
55 - 'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
56 - 'strict' => true,
57 - 'shared' => false,
58 - 'with' => [],
59 - ],
60 - T_FINALLY => [
61 - 'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
62 - 'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
63 - 'strict' => true,
64 - 'shared' => false,
65 - 'with' => [],
66 - ],
67 - T_ELSE => [
68 - 'start' => [
69 - T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
70 - T_COLON => T_COLON,
71 - ],
72 - 'end' => [
73 - T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
74 - T_ENDIF => T_ENDIF,
75 - ],
76 - 'strict' => false,
77 - 'shared' => false,
78 - 'with' => [
79 - T_IF => T_IF,
80 - T_ELSEIF => T_ELSEIF,
81 - ],
82 - ],
83 - T_ELSEIF => [
84 - 'start' => [
85 - T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
86 - T_COLON => T_COLON,
87 - ],
88 - 'end' => [
89 - T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
90 - T_ENDIF => T_ENDIF,
91 - T_ELSE => T_ELSE,
92 - T_ELSEIF => T_ELSEIF,
93 - ],
94 - 'strict' => false,
95 - 'shared' => false,
96 - 'with' => [
97 - T_IF => T_IF,
98 - T_ELSE => T_ELSE,
99 - ],
100 - ],
101 - T_FOR => [
102 - 'start' => [
103 - T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
104 - T_COLON => T_COLON,
105 - ],
106 - 'end' => [
107 - T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
108 - T_ENDFOR => T_ENDFOR,
109 - ],
110 - 'strict' => false,
111 - 'shared' => false,
112 - 'with' => [],
113 - ],
114 - T_FOREACH => [
115 - 'start' => [
116 - T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
117 - T_COLON => T_COLON,
118 - ],
119 - 'end' => [
120 - T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
121 - T_ENDFOREACH => T_ENDFOREACH,
122 - ],
123 - 'strict' => false,
124 - 'shared' => false,
125 - 'with' => [],
126 - ],
127 - T_INTERFACE => [
128 - 'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
129 - 'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
130 - 'strict' => true,
131 - 'shared' => false,
132 - 'with' => [],
133 - ],
134 - T_FUNCTION => [
135 - 'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
136 - 'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
137 - 'strict' => true,
138 - 'shared' => false,
139 - 'with' => [],
140 - ],
141 - T_CLASS => [
142 - 'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
143 - 'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
144 - 'strict' => true,
145 - 'shared' => false,
146 - 'with' => [],
147 - ],
148 - T_TRAIT => [
149 - 'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
150 - 'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
151 - 'strict' => true,
152 - 'shared' => false,
153 - 'with' => [],
154 - ],
155 - T_USE => [
156 - 'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
157 - 'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
158 - 'strict' => false,
159 - 'shared' => false,
160 - 'with' => [],
161 - ],
162 - T_DECLARE => [
163 - 'start' => [
164 - T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
165 - T_COLON => T_COLON,
166 - ],
167 - 'end' => [
168 - T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
169 - T_ENDDECLARE => T_ENDDECLARE,
170 - ],
171 - 'strict' => false,
172 - 'shared' => false,
173 - 'with' => [],
174 - ],
175 - T_NAMESPACE => [
176 - 'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
177 - 'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
178 - 'strict' => false,
179 - 'shared' => false,
180 - 'with' => [],
181 - ],
182 - T_WHILE => [
183 - 'start' => [
184 - T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
185 - T_COLON => T_COLON,
186 - ],
187 - 'end' => [
188 - T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
189 - T_ENDWHILE => T_ENDWHILE,
190 - ],
191 - 'strict' => false,
192 - 'shared' => false,
193 - 'with' => [],
194 - ],
195 - T_DO => [
196 - 'start' => [T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET],
197 - 'end' => [T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET],
198 - 'strict' => true,
199 - 'shared' => false,
200 - 'with' => [],
201 - ],
202 - T_SWITCH => [
203 - 'start' => [
204 - T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
205 - T_COLON => T_COLON,
206 - ],
207 - 'end' => [
208 - T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
209 - T_ENDSWITCH => T_ENDSWITCH,
210 - ],
211 - 'strict' => true,
212 - 'shared' => false,
213 - 'with' => [],
214 - ],
215 - T_CASE => [
216 - 'start' => [
217 - T_COLON => T_COLON,
218 - T_SEMICOLON => T_SEMICOLON,
219 - ],
220 - 'end' => [
221 - T_BREAK => T_BREAK,
222 - T_RETURN => T_RETURN,
223 - T_CONTINUE => T_CONTINUE,
224 - T_THROW => T_THROW,
225 - T_EXIT => T_EXIT,
226 - ],
227 - 'strict' => true,
228 - 'shared' => true,
229 - 'with' => [
230 - T_DEFAULT => T_DEFAULT,
231 - T_CASE => T_CASE,
232 - T_SWITCH => T_SWITCH,
233 - ],
234 - ],
235 - T_DEFAULT => [
236 - 'start' => [
237 - T_COLON => T_COLON,
238 - T_SEMICOLON => T_SEMICOLON,
239 - ],
240 - 'end' => [
241 - T_BREAK => T_BREAK,
242 - T_RETURN => T_RETURN,
243 - T_CONTINUE => T_CONTINUE,
244 - T_THROW => T_THROW,
245 - T_EXIT => T_EXIT,
246 - ],
247 - 'strict' => true,
248 - 'shared' => true,
249 - 'with' => [
250 - T_CASE => T_CASE,
251 - T_SWITCH => T_SWITCH,
252 - ],
253 - ],
254 - T_START_HEREDOC => [
255 - 'start' => [T_START_HEREDOC => T_START_HEREDOC],
256 - 'end' => [T_END_HEREDOC => T_END_HEREDOC],
257 - 'strict' => true,
258 - 'shared' => false,
259 - 'with' => [],
260 - ],
261 - T_START_NOWDOC => [
262 - 'start' => [T_START_NOWDOC => T_START_NOWDOC],
263 - 'end' => [T_END_NOWDOC => T_END_NOWDOC],
264 - 'strict' => true,
265 - 'shared' => false,
266 - 'with' => [],
267 - ],
268 - ];
16 + /**
17 + * A list of tokens that are allowed to open a scope.
18 + *
19 + * This array also contains information about what kind of token the scope
20 + * opener uses to open and close the scope, if the token strictly requires
21 + * an opener, if the token can share a scope closer, and who it can be shared
22 + * with. An example of a token that shares a scope closer is a CASE scope.
23 + *
24 + * @var array
25 + */
26 + public $scopeOpeners = [
27 + T_IF => [
28 + 'start' => [
29 + T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
30 + T_COLON => T_COLON,
31 + ],
32 + 'end' => [
33 + T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
34 + T_ENDIF => T_ENDIF,
35 + T_ELSE => T_ELSE,
36 + T_ELSEIF => T_ELSEIF,
37 + ],
38 + 'strict' => false,
39 + 'shared' => false,
40 + 'with' => [
41 + T_ELSE => T_ELSE,
42 + T_ELSEIF => T_ELSEIF,
43 + ],
44 + ],
45 + T_TRY => [
46 + 'start' => [ T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET ],
47 + 'end' => [ T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET ],
48 + 'strict' => true,
49 + 'shared' => false,
50 + 'with' => [],
51 + ],
52 + T_CATCH => [
53 + 'start' => [ T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET ],
54 + 'end' => [ T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET ],
55 + 'strict' => true,
56 + 'shared' => false,
57 + 'with' => [],
58 + ],
59 + T_FINALLY => [
60 + 'start' => [ T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET ],
61 + 'end' => [ T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET ],
62 + 'strict' => true,
63 + 'shared' => false,
64 + 'with' => [],
65 + ],
66 + T_ELSE => [
67 + 'start' => [
68 + T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
69 + T_COLON => T_COLON,
70 + ],
71 + 'end' => [
72 + T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
73 + T_ENDIF => T_ENDIF,
74 + ],
75 + 'strict' => false,
76 + 'shared' => false,
77 + 'with' => [
78 + T_IF => T_IF,
79 + T_ELSEIF => T_ELSEIF,
80 + ],
81 + ],
82 + T_ELSEIF => [
83 + 'start' => [
84 + T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
85 + T_COLON => T_COLON,
86 + ],
87 + 'end' => [
88 + T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
89 + T_ENDIF => T_ENDIF,
90 + T_ELSE => T_ELSE,
91 + T_ELSEIF => T_ELSEIF,
92 + ],
93 + 'strict' => false,
94 + 'shared' => false,
95 + 'with' => [
96 + T_IF => T_IF,
97 + T_ELSE => T_ELSE,
98 + ],
99 + ],
100 + T_FOR => [
101 + 'start' => [
102 + T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
103 + T_COLON => T_COLON,
104 + ],
105 + 'end' => [
106 + T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
107 + T_ENDFOR => T_ENDFOR,
108 + ],
109 + 'strict' => false,
110 + 'shared' => false,
111 + 'with' => [],
112 + ],
113 + T_FOREACH => [
114 + 'start' => [
115 + T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
116 + T_COLON => T_COLON,
117 + ],
118 + 'end' => [
119 + T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
120 + T_ENDFOREACH => T_ENDFOREACH,
121 + ],
122 + 'strict' => false,
123 + 'shared' => false,
124 + 'with' => [],
125 + ],
126 + T_INTERFACE => [
127 + 'start' => [ T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET ],
128 + 'end' => [ T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET ],
129 + 'strict' => true,
130 + 'shared' => false,
131 + 'with' => [],
132 + ],
133 + T_FUNCTION => [
134 + 'start' => [ T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET ],
135 + 'end' => [ T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET ],
136 + 'strict' => true,
137 + 'shared' => false,
138 + 'with' => [],
139 + ],
140 + T_CLASS => [
141 + 'start' => [ T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET ],
142 + 'end' => [ T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET ],
143 + 'strict' => true,
144 + 'shared' => false,
145 + 'with' => [],
146 + ],
147 + T_TRAIT => [
148 + 'start' => [ T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET ],
149 + 'end' => [ T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET ],
150 + 'strict' => true,
151 + 'shared' => false,
152 + 'with' => [],
153 + ],
154 + T_USE => [
155 + 'start' => [ T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET ],
156 + 'end' => [ T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET ],
157 + 'strict' => false,
158 + 'shared' => false,
159 + 'with' => [],
160 + ],
161 + T_DECLARE => [
162 + 'start' => [
163 + T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
164 + T_COLON => T_COLON,
165 + ],
166 + 'end' => [
167 + T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
168 + T_ENDDECLARE => T_ENDDECLARE,
169 + ],
170 + 'strict' => false,
171 + 'shared' => false,
172 + 'with' => [],
173 + ],
174 + T_NAMESPACE => [
175 + 'start' => [ T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET ],
176 + 'end' => [ T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET ],
177 + 'strict' => false,
178 + 'shared' => false,
179 + 'with' => [],
180 + ],
181 + T_WHILE => [
182 + 'start' => [
183 + T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
184 + T_COLON => T_COLON,
185 + ],
186 + 'end' => [
187 + T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
188 + T_ENDWHILE => T_ENDWHILE,
189 + ],
190 + 'strict' => false,
191 + 'shared' => false,
192 + 'with' => [],
193 + ],
194 + T_DO => [
195 + 'start' => [ T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET ],
196 + 'end' => [ T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET ],
197 + 'strict' => true,
198 + 'shared' => false,
199 + 'with' => [],
200 + ],
201 + T_SWITCH => [
202 + 'start' => [
203 + T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET,
204 + T_COLON => T_COLON,
205 + ],
206 + 'end' => [
207 + T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
208 + T_ENDSWITCH => T_ENDSWITCH,
209 + ],
210 + 'strict' => true,
211 + 'shared' => false,
212 + 'with' => [],
213 + ],
214 + T_CASE => [
215 + 'start' => [
216 + T_COLON => T_COLON,
217 + T_SEMICOLON => T_SEMICOLON,
218 + ],
219 + 'end' => [
220 + T_BREAK => T_BREAK,
221 + T_RETURN => T_RETURN,
222 + T_CONTINUE => T_CONTINUE,
223 + T_THROW => T_THROW,
224 + T_EXIT => T_EXIT,
225 + ],
226 + 'strict' => true,
227 + 'shared' => true,
228 + 'with' => [
229 + T_DEFAULT => T_DEFAULT,
230 + T_CASE => T_CASE,
231 + T_SWITCH => T_SWITCH,
232 + ],
233 + ],
234 + T_DEFAULT => [
235 + 'start' => [
236 + T_COLON => T_COLON,
237 + T_SEMICOLON => T_SEMICOLON,
238 + ],
239 + 'end' => [
240 + T_BREAK => T_BREAK,
241 + T_RETURN => T_RETURN,
242 + T_CONTINUE => T_CONTINUE,
243 + T_THROW => T_THROW,
244 + T_EXIT => T_EXIT,
245 + ],
246 + 'strict' => true,
247 + 'shared' => true,
248 + 'with' => [
249 + T_CASE => T_CASE,
250 + T_SWITCH => T_SWITCH,
251 + ],
252 + ],
253 + T_START_HEREDOC => [
254 + 'start' => [ T_START_HEREDOC => T_START_HEREDOC ],
255 + 'end' => [ T_END_HEREDOC => T_END_HEREDOC ],
256 + 'strict' => true,
257 + 'shared' => false,
258 + 'with' => [],
259 + ],
260 + T_START_NOWDOC => [
261 + 'start' => [ T_START_NOWDOC => T_START_NOWDOC ],
262 + 'end' => [ T_END_NOWDOC => T_END_NOWDOC ],
263 + 'strict' => true,
264 + 'shared' => false,
265 + 'with' => [],
266 + ],
267 + ];
269 268
270 - /**
271 - * A list of tokens that end the scope.
272 - *
273 - * This array is just a unique collection of the end tokens
274 - * from the scopeOpeners array. The data is duplicated here to
275 - * save time during parsing of the file.
276 - *
277 - * @var array
278 - */
279 - public $endScopeTokens = [
280 - T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
281 - T_ENDIF => T_ENDIF,
282 - T_ENDFOR => T_ENDFOR,
283 - T_ENDFOREACH => T_ENDFOREACH,
284 - T_ENDWHILE => T_ENDWHILE,
285 - T_ENDSWITCH => T_ENDSWITCH,
286 - T_BREAK => T_BREAK,
287 - T_END_HEREDOC => T_END_HEREDOC,
288 - ];
269 + /**
270 + * A list of tokens that end the scope.
271 + *
272 + * This array is just a unique collection of the end tokens
273 + * from the scopeOpeners array. The data is duplicated here to
274 + * save time during parsing of the file.
275 + *
276 + * @var array
277 + */
278 + public $endScopeTokens = [
279 + T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
280 + T_ENDIF => T_ENDIF,
281 + T_ENDFOR => T_ENDFOR,
282 + T_ENDFOREACH => T_ENDFOREACH,
283 + T_ENDWHILE => T_ENDWHILE,
284 + T_ENDSWITCH => T_ENDSWITCH,
285 + T_BREAK => T_BREAK,
286 + T_END_HEREDOC => T_END_HEREDOC,
287 + ];
289 288
290 - /**
291 - * Known lengths of tokens.
292 - *
293 - * @var array<int, int>
294 - */
295 - public $knownLengths = [
296 - T_ABSTRACT => 8,
297 - T_AND_EQUAL => 2,
298 - T_ARRAY => 5,
299 - T_AS => 2,
300 - T_BOOLEAN_AND => 2,
301 - T_BOOLEAN_OR => 2,
302 - T_BREAK => 5,
303 - T_CALLABLE => 8,
304 - T_CASE => 4,
305 - T_CATCH => 5,
306 - T_CLASS => 5,
307 - T_CLASS_C => 9,
308 - T_CLONE => 5,
309 - T_CONCAT_EQUAL => 2,
310 - T_CONST => 5,
311 - T_CONTINUE => 8,
312 - T_CURLY_OPEN => 2,
313 - T_DEC => 2,
314 - T_DECLARE => 7,
315 - T_DEFAULT => 7,
316 - T_DIR => 7,
317 - T_DIV_EQUAL => 2,
318 - T_DO => 2,
319 - T_DOLLAR_OPEN_CURLY_BRACES => 2,
320 - T_DOUBLE_ARROW => 2,
321 - T_DOUBLE_COLON => 2,
322 - T_ECHO => 4,
323 - T_ELSE => 4,
324 - T_ELSEIF => 6,
325 - T_EMPTY => 5,
326 - T_ENDDECLARE => 10,
327 - T_ENDFOR => 6,
328 - T_ENDFOREACH => 10,
329 - T_ENDIF => 5,
330 - T_ENDSWITCH => 9,
331 - T_ENDWHILE => 8,
332 - T_EVAL => 4,
333 - T_EXTENDS => 7,
334 - T_FILE => 8,
335 - T_FINAL => 5,
336 - T_FINALLY => 7,
337 - T_FOR => 3,
338 - T_FOREACH => 7,
339 - T_FUNCTION => 8,
340 - T_FUNC_C => 12,
341 - T_GLOBAL => 6,
342 - T_GOTO => 4,
343 - T_HALT_COMPILER => 15,
344 - T_IF => 2,
345 - T_IMPLEMENTS => 10,
346 - T_INC => 2,
347 - T_INCLUDE => 7,
348 - T_INCLUDE_ONCE => 12,
349 - T_INSTANCEOF => 10,
350 - T_INSTEADOF => 9,
351 - T_INTERFACE => 9,
352 - T_ISSET => 5,
353 - T_IS_EQUAL => 2,
354 - T_IS_GREATER_OR_EQUAL => 2,
355 - T_IS_IDENTICAL => 3,
356 - T_IS_NOT_EQUAL => 2,
357 - T_IS_NOT_IDENTICAL => 3,
358 - T_IS_SMALLER_OR_EQUAL => 2,
359 - T_LINE => 8,
360 - T_LIST => 4,
361 - T_LOGICAL_AND => 3,
362 - T_LOGICAL_OR => 2,
363 - T_LOGICAL_XOR => 3,
364 - T_METHOD_C => 10,
365 - T_MINUS_EQUAL => 2,
366 - T_POW_EQUAL => 3,
367 - T_MOD_EQUAL => 2,
368 - T_MUL_EQUAL => 2,
369 - T_NAMESPACE => 9,
370 - T_NS_C => 13,
371 - T_NS_SEPARATOR => 1,
372 - T_NEW => 3,
373 - T_OBJECT_OPERATOR => 2,
374 - T_OPEN_TAG_WITH_ECHO => 3,
375 - T_OR_EQUAL => 2,
376 - T_PLUS_EQUAL => 2,
377 - T_PRINT => 5,
378 - T_PRIVATE => 7,
379 - T_PUBLIC => 6,
380 - T_PROTECTED => 9,
381 - T_REQUIRE => 7,
382 - T_REQUIRE_ONCE => 12,
383 - T_RETURN => 6,
384 - T_STATIC => 6,
385 - T_SWITCH => 6,
386 - T_THROW => 5,
387 - T_TRAIT => 5,
388 - T_TRAIT_C => 9,
389 - T_TRY => 3,
390 - T_UNSET => 5,
391 - T_USE => 3,
392 - T_VAR => 3,
393 - T_WHILE => 5,
394 - T_XOR_EQUAL => 2,
395 - T_YIELD => 5,
396 - T_OPEN_CURLY_BRACKET => 1,
397 - T_CLOSE_CURLY_BRACKET => 1,
398 - T_OPEN_SQUARE_BRACKET => 1,
399 - T_CLOSE_SQUARE_BRACKET => 1,
400 - T_OPEN_PARENTHESIS => 1,
401 - T_CLOSE_PARENTHESIS => 1,
402 - T_COLON => 1,
403 - T_STRING_CONCAT => 1,
404 - T_INLINE_THEN => 1,
405 - T_INLINE_ELSE => 1,
406 - T_NULLABLE => 1,
407 - T_NULL => 4,
408 - T_FALSE => 5,
409 - T_TRUE => 4,
410 - T_SEMICOLON => 1,
411 - T_EQUAL => 1,
412 - T_MULTIPLY => 1,
413 - T_DIVIDE => 1,
414 - T_PLUS => 1,
415 - T_MINUS => 1,
416 - T_MODULUS => 1,
417 - T_POW => 2,
418 - T_SPACESHIP => 3,
419 - T_COALESCE => 2,
420 - T_COALESCE_EQUAL => 3,
421 - T_BITWISE_AND => 1,
422 - T_BITWISE_OR => 1,
423 - T_BITWISE_XOR => 1,
424 - T_SL => 2,
425 - T_SR => 2,
426 - T_SL_EQUAL => 3,
427 - T_SR_EQUAL => 3,
428 - T_GREATER_THAN => 1,
429 - T_LESS_THAN => 1,
430 - T_BOOLEAN_NOT => 1,
431 - T_SELF => 4,
432 - T_PARENT => 6,
433 - T_COMMA => 1,
434 - T_THIS => 4,
435 - T_CLOSURE => 8,
436 - T_BACKTICK => 1,
437 - T_OPEN_SHORT_ARRAY => 1,
438 - T_CLOSE_SHORT_ARRAY => 1,
439 - ];
289 + /**
290 + * Known lengths of tokens.
291 + *
292 + * @var array<int, int>
293 + */
294 + public $knownLengths = [
295 + T_ABSTRACT => 8,
296 + T_AND_EQUAL => 2,
297 + T_ARRAY => 5,
298 + T_AS => 2,
299 + T_BOOLEAN_AND => 2,
300 + T_BOOLEAN_OR => 2,
301 + T_BREAK => 5,
302 + T_CALLABLE => 8,
303 + T_CASE => 4,
304 + T_CATCH => 5,
305 + T_CLASS => 5,
306 + T_CLASS_C => 9,
307 + T_CLONE => 5,
308 + T_CONCAT_EQUAL => 2,
309 + T_CONST => 5,
310 + T_CONTINUE => 8,
311 + T_CURLY_OPEN => 2,
312 + T_DEC => 2,
313 + T_DECLARE => 7,
314 + T_DEFAULT => 7,
315 + T_DIR => 7,
316 + T_DIV_EQUAL => 2,
317 + T_DO => 2,
318 + T_DOLLAR_OPEN_CURLY_BRACES => 2,
319 + T_DOUBLE_ARROW => 2,
320 + T_DOUBLE_COLON => 2,
321 + T_ECHO => 4,
322 + T_ELSE => 4,
323 + T_ELSEIF => 6,
324 + T_EMPTY => 5,
325 + T_ENDDECLARE => 10,
326 + T_ENDFOR => 6,
327 + T_ENDFOREACH => 10,
328 + T_ENDIF => 5,
329 + T_ENDSWITCH => 9,
330 + T_ENDWHILE => 8,
331 + T_EVAL => 4,
332 + T_EXTENDS => 7,
333 + T_FILE => 8,
334 + T_FINAL => 5,
335 + T_FINALLY => 7,
336 + T_FOR => 3,
337 + T_FOREACH => 7,
338 + T_FUNCTION => 8,
339 + T_FUNC_C => 12,
340 + T_GLOBAL => 6,
341 + T_GOTO => 4,
342 + T_HALT_COMPILER => 15,
343 + T_IF => 2,
344 + T_IMPLEMENTS => 10,
345 + T_INC => 2,
346 + T_INCLUDE => 7,
347 + T_INCLUDE_ONCE => 12,
348 + T_INSTANCEOF => 10,
349 + T_INSTEADOF => 9,
350 + T_INTERFACE => 9,
351 + T_ISSET => 5,
352 + T_IS_EQUAL => 2,
353 + T_IS_GREATER_OR_EQUAL => 2,
354 + T_IS_IDENTICAL => 3,
355 + T_IS_NOT_EQUAL => 2,
356 + T_IS_NOT_IDENTICAL => 3,
357 + T_IS_SMALLER_OR_EQUAL => 2,
358 + T_LINE => 8,
359 + T_LIST => 4,
360 + T_LOGICAL_AND => 3,
361 + T_LOGICAL_OR => 2,
362 + T_LOGICAL_XOR => 3,
363 + T_METHOD_C => 10,
364 + T_MINUS_EQUAL => 2,
365 + T_POW_EQUAL => 3,
366 + T_MOD_EQUAL => 2,
367 + T_MUL_EQUAL => 2,
368 + T_NAMESPACE => 9,
369 + T_NS_C => 13,
370 + T_NS_SEPARATOR => 1,
371 + T_NEW => 3,
372 + T_OBJECT_OPERATOR => 2,
373 + T_OPEN_TAG_WITH_ECHO => 3,
374 + T_OR_EQUAL => 2,
375 + T_PLUS_EQUAL => 2,
376 + T_PRINT => 5,
377 + T_PRIVATE => 7,
378 + T_PUBLIC => 6,
379 + T_PROTECTED => 9,
380 + T_REQUIRE => 7,
381 + T_REQUIRE_ONCE => 12,
382 + T_RETURN => 6,
383 + T_STATIC => 6,
384 + T_SWITCH => 6,
385 + T_THROW => 5,
386 + T_TRAIT => 5,
387 + T_TRAIT_C => 9,
388 + T_TRY => 3,
389 + T_UNSET => 5,
390 + T_USE => 3,
391 + T_VAR => 3,
392 + T_WHILE => 5,
393 + T_XOR_EQUAL => 2,
394 + T_YIELD => 5,
395 + T_OPEN_CURLY_BRACKET => 1,
396 + T_CLOSE_CURLY_BRACKET => 1,
397 + T_OPEN_SQUARE_BRACKET => 1,
398 + T_CLOSE_SQUARE_BRACKET => 1,
399 + T_OPEN_PARENTHESIS => 1,
400 + T_CLOSE_PARENTHESIS => 1,
401 + T_COLON => 1,
402 + T_STRING_CONCAT => 1,
403 + T_INLINE_THEN => 1,
404 + T_INLINE_ELSE => 1,
405 + T_NULLABLE => 1,
406 + T_NULL => 4,
407 + T_FALSE => 5,
408 + T_TRUE => 4,
409 + T_SEMICOLON => 1,
410 + T_EQUAL => 1,
411 + T_MULTIPLY => 1,
412 + T_DIVIDE => 1,
413 + T_PLUS => 1,
414 + T_MINUS => 1,
415 + T_MODULUS => 1,
416 + T_POW => 2,
417 + T_SPACESHIP => 3,
418 + T_COALESCE => 2,
419 + T_COALESCE_EQUAL => 3,
420 + T_BITWISE_AND => 1,
421 + T_BITWISE_OR => 1,
422 + T_BITWISE_XOR => 1,
423 + T_SL => 2,
424 + T_SR => 2,
425 + T_SL_EQUAL => 3,
426 + T_SR_EQUAL => 3,
427 + T_GREATER_THAN => 1,
428 + T_LESS_THAN => 1,
429 + T_BOOLEAN_NOT => 1,
430 + T_SELF => 4,
431 + T_PARENT => 6,
432 + T_COMMA => 1,
433 + T_THIS => 4,
434 + T_CLOSURE => 8,
435 + T_BACKTICK => 1,
436 + T_OPEN_SHORT_ARRAY => 1,
437 + T_CLOSE_SHORT_ARRAY => 1,
438 + ];
440 439
441 - /**
442 - * A cache of different token types, resolved into arrays.
443 - *
444 - * @var array
445 - * @see standardiseToken()
446 - */
447 - private static $resolveTokenCache = [];
440 + /**
441 + * A cache of different token types, resolved into arrays.
442 + *
443 + * @var array
444 + * @see standardiseToken()
445 + */
446 + private static $resolveTokenCache = [];
448 447
449 448
450 - /**
451 - * Creates an array of tokens when given some PHP code.
452 - *
453 - * Starts by using token_get_all() but does a lot of extra processing
454 - * to insert information about the context of the token.
455 - *
456 - * @param string $string The string to tokenize.
457 - *
458 - * @return array
459 - */
460 - protected function tokenize($string)
461 - {
462 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
463 - echo "\t*** START PHP TOKENIZING ***".PHP_EOL;
464 - $isWin = false;
465 - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
466 - $isWin = true;
467 - }
468 - }
449 + /**
450 + * Creates an array of tokens when given some PHP code.
451 + *
452 + * Starts by using token_get_all() but does a lot of extra processing
453 + * to insert information about the context of the token.
454 + *
455 + * @param string $string The string to tokenize.
456 + *
457 + * @return array
458 + */
459 + protected function tokenize( $string ) {
460 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
461 + echo "\t*** START PHP TOKENIZING ***" . PHP_EOL;
462 + $isWin = false;
463 + if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
464 + $isWin = true;
465 + }
466 + }
469 467
470 - $tokens = @token_get_all($string);
471 - $finalTokens = [];
468 + $tokens = @token_get_all( $string );
469 + $finalTokens = [];
472 470
473 - $newStackPtr = 0;
474 - $numTokens = count($tokens);
475 - $lastNotEmptyToken = 0;
471 + $newStackPtr = 0;
472 + $numTokens = count( $tokens );
473 + $lastNotEmptyToken = 0;
476 474
477 - $insideInlineIf = [];
478 - $insideUseGroup = false;
475 + $insideInlineIf = [];
476 + $insideUseGroup = false;
479 477
480 - $commentTokenizer = new Comment();
478 + $commentTokenizer = new Comment();
481 479
482 - for ($stackPtr = 0; $stackPtr < $numTokens; $stackPtr++) {
483 - // Special case for tokens we have needed to blank out.
484 - if ($tokens[$stackPtr] === null) {
485 - continue;
486 - }
480 + for ( $stackPtr = 0; $stackPtr < $numTokens; $stackPtr ++ ) {
481 + // Special case for tokens we have needed to blank out.
482 + if ( $tokens[ $stackPtr ] === null ) {
483 + continue;
484 + }
487 485
488 - $token = (array) $tokens[$stackPtr];
489 - $tokenIsArray = isset($token[1]);
486 + $token = (array) $tokens[ $stackPtr ];
487 + $tokenIsArray = isset( $token[1] );
490 488
491 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
492 - if ($tokenIsArray === true) {
493 - $type = Util\Tokens::tokenName($token[0]);
494 - $content = Util\Common::prepareForOutput($token[1]);
495 - } else {
496 - $newToken = self::resolveSimpleToken($token[0]);
497 - $type = $newToken['type'];
498 - $content = Util\Common::prepareForOutput($token[0]);
499 - }
489 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
490 + if ( $tokenIsArray === true ) {
491 + $type = Util\Tokens::tokenName( $token[0] );
492 + $content = Util\Common::prepareForOutput( $token[1] );
493 + } else {
494 + $newToken = self::resolveSimpleToken( $token[0] );
495 + $type = $newToken['type'];
496 + $content = Util\Common::prepareForOutput( $token[0] );
497 + }
500 498
501 - echo "\tProcess token ";
502 - if ($tokenIsArray === true) {
503 - echo "[$stackPtr]";
504 - } else {
505 - echo " $stackPtr ";
506 - }
499 + echo "\tProcess token ";
500 + if ( $tokenIsArray === true ) {
501 + echo "[$stackPtr]";
502 + } else {
503 + echo " $stackPtr ";
504 + }
507 505
508 - echo ": $type => $content";
509 - }//end if
506 + echo ": $type => $content";
507 + }//end if
510 508
511 - if ($newStackPtr > 0
512 - && isset(Util\Tokens::$emptyTokens[$finalTokens[($newStackPtr - 1)]['code']]) === false
513 - ) {
514 - $lastNotEmptyToken = ($newStackPtr - 1);
515 - }
509 + if ( $newStackPtr > 0
510 + && isset( Util\Tokens::$emptyTokens[ $finalTokens[ ( $newStackPtr - 1 ) ]['code'] ] ) === false
511 + ) {
512 + $lastNotEmptyToken = ( $newStackPtr - 1 );
513 + }
516 514
517 - /*
515 + /*
518 516 If we are using \r\n newline characters, the \r and \n are sometimes
519 517 split over two tokens. This normally occurs after comments. We need
520 518 to merge these two characters together so that our line endings are
521 519 consistent for all lines.
@@ -520,54 +518,54 @@
520 518 to merge these two characters together so that our line endings are
521 519 consistent for all lines.
522 520 */
523 521
524 - if ($tokenIsArray === true && substr($token[1], -1) === "\r") {
525 - if (isset($tokens[($stackPtr + 1)]) === true
526 - && is_array($tokens[($stackPtr + 1)]) === true
527 - && $tokens[($stackPtr + 1)][1][0] === "\n"
528 - ) {
529 - $token[1] .= "\n";
530 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
531 - if ($isWin === true) {
532 - echo '\n';
533 - } else {
534 - echo "\033[30;1m\\n\033[0m";
535 - }
536 - }
522 + if ( $tokenIsArray === true && substr( $token[1], - 1 ) === "\r" ) {
523 + if ( isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
524 + && is_array( $tokens[ ( $stackPtr + 1 ) ] ) === true
525 + && $tokens[ ( $stackPtr + 1 ) ][1][0] === "\n"
526 + ) {
527 + $token[1] .= "\n";
528 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
529 + if ( $isWin === true ) {
530 + echo '\n';
531 + } else {
532 + echo "\033[30;1m\\n\033[0m";
533 + }
534 + }
537 535
538 - if ($tokens[($stackPtr + 1)][1] === "\n") {
539 - // This token's content has been merged into the previous,
540 - // so we can skip it.
541 - $tokens[($stackPtr + 1)] = '';
542 - } else {
543 - $tokens[($stackPtr + 1)][1] = substr($tokens[($stackPtr + 1)][1], 1);
544 - }
545 - }
546 - }//end if
536 + if ( $tokens[ ( $stackPtr + 1 ) ][1] === "\n" ) {
537 + // This token's content has been merged into the previous,
538 + // so we can skip it.
539 + $tokens[ ( $stackPtr + 1 ) ] = '';
540 + } else {
541 + $tokens[ ( $stackPtr + 1 ) ][1] = substr( $tokens[ ( $stackPtr + 1 ) ][1], 1 );
542 + }
543 + }
544 + }//end if
547 545
548 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
549 - echo PHP_EOL;
550 - }
546 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
547 + echo PHP_EOL;
548 + }
551 549
552 - /*
550 + /*
553 551 Parse doc blocks into something that can be easily iterated over.
554 552 */
555 553
556 - if ($tokenIsArray === true
557 - && ($token[0] === T_DOC_COMMENT
558 - || ($token[0] === T_COMMENT && strpos($token[1], '/**') === 0))
559 - ) {
560 - $commentTokens = $commentTokenizer->tokenizeString($token[1], $this->eolChar, $newStackPtr);
561 - foreach ($commentTokens as $commentToken) {
562 - $finalTokens[$newStackPtr] = $commentToken;
563 - $newStackPtr++;
564 - }
554 + if ( $tokenIsArray === true
555 + && ( $token[0] === T_DOC_COMMENT
556 + || ( $token[0] === T_COMMENT && strpos( $token[1], '/**' ) === 0 ) )
557 + ) {
558 + $commentTokens = $commentTokenizer->tokenizeString( $token[1], $this->eolChar, $newStackPtr );
559 + foreach ( $commentTokens as $commentToken ) {
560 + $finalTokens[ $newStackPtr ] = $commentToken;
561 + $newStackPtr ++;
562 + }
565 563
566 - continue;
567 - }
564 + continue;
565 + }
568 566
569 - /*
567 + /*
570 568 If this is a double quoted string, PHP will tokenize the whole
571 569 thing which causes problems with the scope map when braces are
572 570 within the string. So we need to merge the tokens together to
573 571 provide a single string.
@@ -572,108 +570,108 @@
572 570 within the string. So we need to merge the tokens together to
573 571 provide a single string.
574 572 */
575 573
576 - if ($tokenIsArray === false && ($token[0] === '"' || $token[0] === 'b"')) {
577 - // Binary casts need a special token.
578 - if ($token[0] === 'b"') {
579 - $finalTokens[$newStackPtr] = [
580 - 'code' => T_BINARY_CAST,
581 - 'type' => 'T_BINARY_CAST',
582 - 'content' => 'b',
583 - ];
584 - $newStackPtr++;
585 - }
574 + if ( $tokenIsArray === false && ( $token[0] === '"' || $token[0] === 'b"' ) ) {
575 + // Binary casts need a special token.
576 + if ( $token[0] === 'b"' ) {
577 + $finalTokens[ $newStackPtr ] = [
578 + 'code' => T_BINARY_CAST,
579 + 'type' => 'T_BINARY_CAST',
580 + 'content' => 'b',
581 + ];
582 + $newStackPtr ++;
583 + }
586 584
587 - $tokenContent = '"';
588 - $nestedVars = [];
589 - for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
590 - $subToken = (array) $tokens[$i];
591 - $subTokenIsArray = isset($subToken[1]);
585 + $tokenContent = '"';
586 + $nestedVars = [];
587 + for ( $i = ( $stackPtr + 1 ); $i < $numTokens; $i ++ ) {
588 + $subToken = (array) $tokens[ $i ];
589 + $subTokenIsArray = isset( $subToken[1] );
592 590
593 - if ($subTokenIsArray === true) {
594 - $tokenContent .= $subToken[1];
595 - if ($subToken[1] === '{'
596 - && $subToken[0] !== T_ENCAPSED_AND_WHITESPACE
597 - ) {
598 - $nestedVars[] = $i;
599 - }
600 - } else {
601 - $tokenContent .= $subToken[0];
602 - if ($subToken[0] === '}') {
603 - array_pop($nestedVars);
604 - }
605 - }
591 + if ( $subTokenIsArray === true ) {
592 + $tokenContent .= $subToken[1];
593 + if ( $subToken[1] === '{'
594 + && $subToken[0] !== T_ENCAPSED_AND_WHITESPACE
595 + ) {
596 + $nestedVars[] = $i;
597 + }
598 + } else {
599 + $tokenContent .= $subToken[0];
600 + if ( $subToken[0] === '}' ) {
601 + array_pop( $nestedVars );
602 + }
603 + }
606 604
607 - if ($subTokenIsArray === false
608 - && $subToken[0] === '"'
609 - && empty($nestedVars) === true
610 - ) {
611 - // We found the other end of the double quoted string.
612 - break;
613 - }
614 - }//end for
605 + if ( $subTokenIsArray === false
606 + && $subToken[0] === '"'
607 + && empty( $nestedVars ) === true
608 + ) {
609 + // We found the other end of the double quoted string.
610 + break;
611 + }
612 + }//end for
615 613
616 - $stackPtr = $i;
614 + $stackPtr = $i;
617 615
618 - // Convert each line within the double quoted string to a
619 - // new token, so it conforms with other multiple line tokens.
620 - $tokenLines = explode($this->eolChar, $tokenContent);
621 - $numLines = count($tokenLines);
622 - $newToken = [];
616 + // Convert each line within the double quoted string to a
617 + // new token, so it conforms with other multiple line tokens.
618 + $tokenLines = explode( $this->eolChar, $tokenContent );
619 + $numLines = count( $tokenLines );
620 + $newToken = [];
623 621
624 - for ($j = 0; $j < $numLines; $j++) {
625 - $newToken['content'] = $tokenLines[$j];
626 - if ($j === ($numLines - 1)) {
627 - if ($tokenLines[$j] === '') {
628 - break;
629 - }
630 - } else {
631 - $newToken['content'] .= $this->eolChar;
632 - }
622 + for ( $j = 0; $j < $numLines; $j ++ ) {
623 + $newToken['content'] = $tokenLines[ $j ];
624 + if ( $j === ( $numLines - 1 ) ) {
625 + if ( $tokenLines[ $j ] === '' ) {
626 + break;
627 + }
628 + } else {
629 + $newToken['content'] .= $this->eolChar;
630 + }
633 631
634 - $newToken['code'] = T_DOUBLE_QUOTED_STRING;
635 - $newToken['type'] = 'T_DOUBLE_QUOTED_STRING';
636 - $finalTokens[$newStackPtr] = $newToken;
637 - $newStackPtr++;
638 - }
632 + $newToken['code'] = T_DOUBLE_QUOTED_STRING;
633 + $newToken['type'] = 'T_DOUBLE_QUOTED_STRING';
634 + $finalTokens[ $newStackPtr ] = $newToken;
635 + $newStackPtr ++;
636 + }
639 637
640 - // Continue, as we're done with this token.
641 - continue;
642 - }//end if
638 + // Continue, as we're done with this token.
639 + continue;
640 + }//end if
643 641
644 - /*
642 + /*
645 643 Detect binary casting and assign the casts their own token.
646 644 */
647 645
648 - if ($tokenIsArray === true
649 - && $token[0] === T_CONSTANT_ENCAPSED_STRING
650 - && (substr($token[1], 0, 2) === 'b"'
651 - || substr($token[1], 0, 2) === "b'")
652 - ) {
653 - $finalTokens[$newStackPtr] = [
654 - 'code' => T_BINARY_CAST,
655 - 'type' => 'T_BINARY_CAST',
656 - 'content' => 'b',
657 - ];
658 - $newStackPtr++;
659 - $token[1] = substr($token[1], 1);
660 - }
646 + if ( $tokenIsArray === true
647 + && $token[0] === T_CONSTANT_ENCAPSED_STRING
648 + && ( substr( $token[1], 0, 2 ) === 'b"'
649 + || substr( $token[1], 0, 2 ) === "b'" )
650 + ) {
651 + $finalTokens[ $newStackPtr ] = [
652 + 'code' => T_BINARY_CAST,
653 + 'type' => 'T_BINARY_CAST',
654 + 'content' => 'b',
655 + ];
656 + $newStackPtr ++;
657 + $token[1] = substr( $token[1], 1 );
658 + }
661 659
662 - if ($tokenIsArray === true
663 - && $token[0] === T_STRING_CAST
664 - && preg_match('`^\(\s*binary\s*\)$`i', $token[1]) === 1
665 - ) {
666 - $finalTokens[$newStackPtr] = [
667 - 'code' => T_BINARY_CAST,
668 - 'type' => 'T_BINARY_CAST',
669 - 'content' => $token[1],
670 - ];
671 - $newStackPtr++;
672 - continue;
673 - }
660 + if ( $tokenIsArray === true
661 + && $token[0] === T_STRING_CAST
662 + && preg_match( '`^\(\s*binary\s*\)$`i', $token[1] ) === 1
663 + ) {
664 + $finalTokens[ $newStackPtr ] = [
665 + 'code' => T_BINARY_CAST,
666 + 'type' => 'T_BINARY_CAST',
667 + 'content' => $token[1],
668 + ];
669 + $newStackPtr ++;
670 + continue;
671 + }
674 672
675 - /*
673 + /*
676 674 If this is a heredoc, PHP will tokenize the whole
677 675 thing which causes problems when heredocs don't
678 676 contain real PHP code, which is almost never.
679 677 We want to leave the start and end heredoc tokens
@@ -679,132 +677,132 @@
679 677 We want to leave the start and end heredoc tokens
680 678 alone though.
681 679 */
682 680
683 - if ($tokenIsArray === true && $token[0] === T_START_HEREDOC) {
684 - // Add the start heredoc token to the final array.
685 - $finalTokens[$newStackPtr] = self::standardiseToken($token);
681 + if ( $tokenIsArray === true && $token[0] === T_START_HEREDOC ) {
682 + // Add the start heredoc token to the final array.
683 + $finalTokens[ $newStackPtr ] = self::standardiseToken( $token );
686 684
687 - // Check if this is actually a nowdoc and use a different token
688 - // to help the sniffs.
689 - $nowdoc = false;
690 - if (strpos($token[1], "'") !== false) {
691 - $finalTokens[$newStackPtr]['code'] = T_START_NOWDOC;
692 - $finalTokens[$newStackPtr]['type'] = 'T_START_NOWDOC';
693 - $nowdoc = true;
694 - }
685 + // Check if this is actually a nowdoc and use a different token
686 + // to help the sniffs.
687 + $nowdoc = false;
688 + if ( strpos( $token[1], "'" ) !== false ) {
689 + $finalTokens[ $newStackPtr ]['code'] = T_START_NOWDOC;
690 + $finalTokens[ $newStackPtr ]['type'] = 'T_START_NOWDOC';
691 + $nowdoc = true;
692 + }
695 693
696 - $tokenContent = '';
697 - for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
698 - $subTokenIsArray = is_array($tokens[$i]);
699 - if ($subTokenIsArray === true
700 - && $tokens[$i][0] === T_END_HEREDOC
701 - ) {
702 - // We found the other end of the heredoc.
703 - break;
704 - }
694 + $tokenContent = '';
695 + for ( $i = ( $stackPtr + 1 ); $i < $numTokens; $i ++ ) {
696 + $subTokenIsArray = is_array( $tokens[ $i ] );
697 + if ( $subTokenIsArray === true
698 + && $tokens[ $i ][0] === T_END_HEREDOC
699 + ) {
700 + // We found the other end of the heredoc.
701 + break;
702 + }
705 703
706 - if ($subTokenIsArray === true) {
707 - $tokenContent .= $tokens[$i][1];
708 - } else {
709 - $tokenContent .= $tokens[$i];
710 - }
711 - }
704 + if ( $subTokenIsArray === true ) {
705 + $tokenContent .= $tokens[ $i ][1];
706 + } else {
707 + $tokenContent .= $tokens[ $i ];
708 + }
709 + }
712 710
713 - if ($i === $numTokens) {
714 - // We got to the end of the file and never
715 - // found the closing token, so this probably wasn't
716 - // a heredoc.
717 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
718 - $type = $finalTokens[$newStackPtr]['type'];
719 - echo "\t\t* failed to find the end of the here/nowdoc".PHP_EOL;
720 - echo "\t\t* token $stackPtr changed from $type to T_STRING".PHP_EOL;
721 - }
711 + if ( $i === $numTokens ) {
712 + // We got to the end of the file and never
713 + // found the closing token, so this probably wasn't
714 + // a heredoc.
715 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
716 + $type = $finalTokens[ $newStackPtr ]['type'];
717 + echo "\t\t* failed to find the end of the here/nowdoc" . PHP_EOL;
718 + echo "\t\t* token $stackPtr changed from $type to T_STRING" . PHP_EOL;
719 + }
722 720
723 - $finalTokens[$newStackPtr]['code'] = T_STRING;
724 - $finalTokens[$newStackPtr]['type'] = 'T_STRING';
725 - $newStackPtr++;
726 - continue;
727 - }
721 + $finalTokens[ $newStackPtr ]['code'] = T_STRING;
722 + $finalTokens[ $newStackPtr ]['type'] = 'T_STRING';
723 + $newStackPtr ++;
724 + continue;
725 + }
728 726
729 - $stackPtr = $i;
730 - $newStackPtr++;
727 + $stackPtr = $i;
728 + $newStackPtr ++;
731 729
732 - // Convert each line within the heredoc to a
733 - // new token, so it conforms with other multiple line tokens.
734 - $tokenLines = explode($this->eolChar, $tokenContent);
735 - $numLines = count($tokenLines);
736 - $newToken = [];
730 + // Convert each line within the heredoc to a
731 + // new token, so it conforms with other multiple line tokens.
732 + $tokenLines = explode( $this->eolChar, $tokenContent );
733 + $numLines = count( $tokenLines );
734 + $newToken = [];
737 735
738 - for ($j = 0; $j < $numLines; $j++) {
739 - $newToken['content'] = $tokenLines[$j];
740 - if ($j === ($numLines - 1)) {
741 - if ($tokenLines[$j] === '') {
742 - break;
743 - }
744 - } else {
745 - $newToken['content'] .= $this->eolChar;
746 - }
736 + for ( $j = 0; $j < $numLines; $j ++ ) {
737 + $newToken['content'] = $tokenLines[ $j ];
738 + if ( $j === ( $numLines - 1 ) ) {
739 + if ( $tokenLines[ $j ] === '' ) {
740 + break;
741 + }
742 + } else {
743 + $newToken['content'] .= $this->eolChar;
744 + }
747 745
748 - if ($nowdoc === true) {
749 - $newToken['code'] = T_NOWDOC;
750 - $newToken['type'] = 'T_NOWDOC';
751 - } else {
752 - $newToken['code'] = T_HEREDOC;
753 - $newToken['type'] = 'T_HEREDOC';
754 - }
746 + if ( $nowdoc === true ) {
747 + $newToken['code'] = T_NOWDOC;
748 + $newToken['type'] = 'T_NOWDOC';
749 + } else {
750 + $newToken['code'] = T_HEREDOC;
751 + $newToken['type'] = 'T_HEREDOC';
752 + }
755 753
756 - $finalTokens[$newStackPtr] = $newToken;
757 - $newStackPtr++;
758 - }//end for
754 + $finalTokens[ $newStackPtr ] = $newToken;
755 + $newStackPtr ++;
756 + }//end for
759 757
760 - // Add the end heredoc token to the final array.
761 - $finalTokens[$newStackPtr] = self::standardiseToken($tokens[$stackPtr]);
758 + // Add the end heredoc token to the final array.
759 + $finalTokens[ $newStackPtr ] = self::standardiseToken( $tokens[ $stackPtr ] );
762 760
763 - if ($nowdoc === true) {
764 - $finalTokens[$newStackPtr]['code'] = T_END_NOWDOC;
765 - $finalTokens[$newStackPtr]['type'] = 'T_END_NOWDOC';
766 - }
761 + if ( $nowdoc === true ) {
762 + $finalTokens[ $newStackPtr ]['code'] = T_END_NOWDOC;
763 + $finalTokens[ $newStackPtr ]['type'] = 'T_END_NOWDOC';
764 + }
767 765
768 - $newStackPtr++;
766 + $newStackPtr ++;
769 767
770 - // Continue, as we're done with this token.
771 - continue;
772 - }//end if
768 + // Continue, as we're done with this token.
769 + continue;
770 + }//end if
773 771
774 - /*
772 + /*
775 773 Before PHP 7.0, the "yield from" was tokenized as
776 774 T_YIELD, T_WHITESPACE and T_STRING. So look for
777 775 and change this token in earlier versions.
778 776 */
779 777
780 - if (PHP_VERSION_ID < 70000
781 - && PHP_VERSION_ID >= 50500
782 - && $tokenIsArray === true
783 - && $token[0] === T_YIELD
784 - && isset($tokens[($stackPtr + 1)]) === true
785 - && isset($tokens[($stackPtr + 2)]) === true
786 - && $tokens[($stackPtr + 1)][0] === T_WHITESPACE
787 - && $tokens[($stackPtr + 2)][0] === T_STRING
788 - && strtolower($tokens[($stackPtr + 2)][1]) === 'from'
789 - ) {
790 - // Could be multi-line, so just the token stack.
791 - $token[0] = T_YIELD_FROM;
792 - $token[1] .= $tokens[($stackPtr + 1)][1].$tokens[($stackPtr + 2)][1];
778 + if ( PHP_VERSION_ID < 70000
779 + && PHP_VERSION_ID >= 50500
780 + && $tokenIsArray === true
781 + && $token[0] === T_YIELD
782 + && isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
783 + && isset( $tokens[ ( $stackPtr + 2 ) ] ) === true
784 + && $tokens[ ( $stackPtr + 1 ) ][0] === T_WHITESPACE
785 + && $tokens[ ( $stackPtr + 2 ) ][0] === T_STRING
786 + && strtolower( $tokens[ ( $stackPtr + 2 ) ][1] ) === 'from'
787 + ) {
788 + // Could be multi-line, so just the token stack.
789 + $token[0] = T_YIELD_FROM;
790 + $token[1] .= $tokens[ ( $stackPtr + 1 ) ][1] . $tokens[ ( $stackPtr + 2 ) ][1];
793 791
794 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
795 - for ($i = ($stackPtr + 1); $i <= ($stackPtr + 2); $i++) {
796 - $type = Util\Tokens::tokenName($tokens[$i][0]);
797 - $content = Util\Common::prepareForOutput($tokens[$i][1]);
798 - echo "\t\t* token $i merged into T_YIELD_FROM; was: $type => $content".PHP_EOL;
799 - }
800 - }
792 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
793 + for ( $i = ( $stackPtr + 1 ); $i <= ( $stackPtr + 2 ); $i ++ ) {
794 + $type = Util\Tokens::tokenName( $tokens[ $i ][0] );
795 + $content = Util\Common::prepareForOutput( $tokens[ $i ][1] );
796 + echo "\t\t* token $i merged into T_YIELD_FROM; was: $type => $content" . PHP_EOL;
797 + }
798 + }
801 799
802 - $tokens[($stackPtr + 1)] = null;
803 - $tokens[($stackPtr + 2)] = null;
804 - }
800 + $tokens[ ( $stackPtr + 1 ) ] = null;
801 + $tokens[ ( $stackPtr + 2 ) ] = null;
802 + }
805 803
806 - /*
804 + /*
807 805 Before PHP 5.5, the yield keyword was tokenized as
808 806 T_STRING. So look for and change this token in
809 807 earlier versions.
810 808 Checks also if it is just "yield" or "yield from".
@@ -809,115 +807,115 @@
809 807 earlier versions.
810 808 Checks also if it is just "yield" or "yield from".
811 809 */
812 810
813 - if (PHP_VERSION_ID < 50500
814 - && $tokenIsArray === true
815 - && $token[0] === T_STRING
816 - && strtolower($token[1]) === 'yield'
817 - ) {
818 - if (isset($tokens[($stackPtr + 1)]) === true
819 - && isset($tokens[($stackPtr + 2)]) === true
820 - && $tokens[($stackPtr + 1)][0] === T_WHITESPACE
821 - && $tokens[($stackPtr + 2)][0] === T_STRING
822 - && strtolower($tokens[($stackPtr + 2)][1]) === 'from'
823 - ) {
824 - // Could be multi-line, so just just the token stack.
825 - $token[0] = T_YIELD_FROM;
826 - $token[1] .= $tokens[($stackPtr + 1)][1].$tokens[($stackPtr + 2)][1];
811 + if ( PHP_VERSION_ID < 50500
812 + && $tokenIsArray === true
813 + && $token[0] === T_STRING
814 + && strtolower( $token[1] ) === 'yield'
815 + ) {
816 + if ( isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
817 + && isset( $tokens[ ( $stackPtr + 2 ) ] ) === true
818 + && $tokens[ ( $stackPtr + 1 ) ][0] === T_WHITESPACE
819 + && $tokens[ ( $stackPtr + 2 ) ][0] === T_STRING
820 + && strtolower( $tokens[ ( $stackPtr + 2 ) ][1] ) === 'from'
821 + ) {
822 + // Could be multi-line, so just just the token stack.
823 + $token[0] = T_YIELD_FROM;
824 + $token[1] .= $tokens[ ( $stackPtr + 1 ) ][1] . $tokens[ ( $stackPtr + 2 ) ][1];
827 825
828 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
829 - for ($i = ($stackPtr + 1); $i <= ($stackPtr + 2); $i++) {
830 - $type = Util\Tokens::tokenName($tokens[$i][0]);
831 - $content = Util\Common::prepareForOutput($tokens[$i][1]);
832 - echo "\t\t* token $i merged into T_YIELD_FROM; was: $type => $content".PHP_EOL;
833 - }
834 - }
826 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
827 + for ( $i = ( $stackPtr + 1 ); $i <= ( $stackPtr + 2 ); $i ++ ) {
828 + $type = Util\Tokens::tokenName( $tokens[ $i ][0] );
829 + $content = Util\Common::prepareForOutput( $tokens[ $i ][1] );
830 + echo "\t\t* token $i merged into T_YIELD_FROM; was: $type => $content" . PHP_EOL;
831 + }
832 + }
835 833
836 - $tokens[($stackPtr + 1)] = null;
837 - $tokens[($stackPtr + 2)] = null;
838 - } else {
839 - $newToken = [];
840 - $newToken['code'] = T_YIELD;
841 - $newToken['type'] = 'T_YIELD';
842 - $newToken['content'] = $token[1];
843 - $finalTokens[$newStackPtr] = $newToken;
834 + $tokens[ ( $stackPtr + 1 ) ] = null;
835 + $tokens[ ( $stackPtr + 2 ) ] = null;
836 + } else {
837 + $newToken = [];
838 + $newToken['code'] = T_YIELD;
839 + $newToken['type'] = 'T_YIELD';
840 + $newToken['content'] = $token[1];
841 + $finalTokens[ $newStackPtr ] = $newToken;
844 842
845 - $newStackPtr++;
846 - continue;
847 - }//end if
848 - }//end if
843 + $newStackPtr ++;
844 + continue;
845 + }//end if
846 + }//end if
849 847
850 - /*
848 + /*
851 849 Before PHP 5.6, the ... operator was tokenized as three
852 850 T_STRING_CONCAT tokens in a row. So look for and combine
853 851 these tokens in earlier versions.
854 852 */
855 853
856 - if ($tokenIsArray === false
857 - && $token[0] === '.'
858 - && isset($tokens[($stackPtr + 1)]) === true
859 - && isset($tokens[($stackPtr + 2)]) === true
860 - && $tokens[($stackPtr + 1)] === '.'
861 - && $tokens[($stackPtr + 2)] === '.'
862 - ) {
863 - $newToken = [];
864 - $newToken['code'] = T_ELLIPSIS;
865 - $newToken['type'] = 'T_ELLIPSIS';
866 - $newToken['content'] = '...';
867 - $finalTokens[$newStackPtr] = $newToken;
854 + if ( $tokenIsArray === false
855 + && $token[0] === '.'
856 + && isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
857 + && isset( $tokens[ ( $stackPtr + 2 ) ] ) === true
858 + && $tokens[ ( $stackPtr + 1 ) ] === '.'
859 + && $tokens[ ( $stackPtr + 2 ) ] === '.'
860 + ) {
861 + $newToken = [];
862 + $newToken['code'] = T_ELLIPSIS;
863 + $newToken['type'] = 'T_ELLIPSIS';
864 + $newToken['content'] = '...';
865 + $finalTokens[ $newStackPtr ] = $newToken;
868 866
869 - $newStackPtr++;
870 - $stackPtr += 2;
871 - continue;
872 - }
867 + $newStackPtr ++;
868 + $stackPtr += 2;
869 + continue;
870 + }
873 871
874 - /*
872 + /*
875 873 Before PHP 5.6, the ** operator was tokenized as two
876 874 T_MULTIPLY tokens in a row. So look for and combine
877 875 these tokens in earlier versions.
878 876 */
879 877
880 - if ($tokenIsArray === false
881 - && $token[0] === '*'
882 - && isset($tokens[($stackPtr + 1)]) === true
883 - && $tokens[($stackPtr + 1)] === '*'
884 - ) {
885 - $newToken = [];
886 - $newToken['code'] = T_POW;
887 - $newToken['type'] = 'T_POW';
888 - $newToken['content'] = '**';
889 - $finalTokens[$newStackPtr] = $newToken;
878 + if ( $tokenIsArray === false
879 + && $token[0] === '*'
880 + && isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
881 + && $tokens[ ( $stackPtr + 1 ) ] === '*'
882 + ) {
883 + $newToken = [];
884 + $newToken['code'] = T_POW;
885 + $newToken['type'] = 'T_POW';
886 + $newToken['content'] = '**';
887 + $finalTokens[ $newStackPtr ] = $newToken;
890 888
891 - $newStackPtr++;
892 - $stackPtr++;
893 - continue;
894 - }
889 + $newStackPtr ++;
890 + $stackPtr ++;
891 + continue;
892 + }
895 893
896 - /*
894 + /*
897 895 Before PHP 5.6, the **= operator was tokenized as
898 896 T_MULTIPLY followed by T_MUL_EQUAL. So look for and combine
899 897 these tokens in earlier versions.
900 898 */
901 899
902 - if ($tokenIsArray === false
903 - && $token[0] === '*'
904 - && isset($tokens[($stackPtr + 1)]) === true
905 - && is_array($tokens[($stackPtr + 1)]) === true
906 - && $tokens[($stackPtr + 1)][1] === '*='
907 - ) {
908 - $newToken = [];
909 - $newToken['code'] = T_POW_EQUAL;
910 - $newToken['type'] = 'T_POW_EQUAL';
911 - $newToken['content'] = '**=';
912 - $finalTokens[$newStackPtr] = $newToken;
900 + if ( $tokenIsArray === false
901 + && $token[0] === '*'
902 + && isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
903 + && is_array( $tokens[ ( $stackPtr + 1 ) ] ) === true
904 + && $tokens[ ( $stackPtr + 1 ) ][1] === '*='
905 + ) {
906 + $newToken = [];
907 + $newToken['code'] = T_POW_EQUAL;
908 + $newToken['type'] = 'T_POW_EQUAL';
909 + $newToken['content'] = '**=';
910 + $finalTokens[ $newStackPtr ] = $newToken;
913 911
914 - $newStackPtr++;
915 - $stackPtr++;
916 - continue;
917 - }
912 + $newStackPtr ++;
913 + $stackPtr ++;
914 + continue;
915 + }
918 916
919 - /*
917 + /*
920 918 Before PHP 7, the ??= operator was tokenized as
921 919 T_INLINE_THEN, T_INLINE_THEN, T_EQUAL.
922 920 Between PHP 7.0 and 7.2, the ??= operator was tokenized as
923 921 T_COALESCE, T_EQUAL.
@@ -923,145 +921,145 @@
923 921 T_COALESCE, T_EQUAL.
924 922 So look for and combine these tokens in earlier versions.
925 923 */
926 924
927 - if (($tokenIsArray === false
928 - && $token[0] === '?'
929 - && isset($tokens[($stackPtr + 1)]) === true
930 - && $tokens[($stackPtr + 1)][0] === '?'
931 - && isset($tokens[($stackPtr + 2)]) === true
932 - && $tokens[($stackPtr + 2)][0] === '=')
933 - || ($tokenIsArray === true
934 - && $token[0] === T_COALESCE
935 - && isset($tokens[($stackPtr + 1)]) === true
936 - && $tokens[($stackPtr + 1)][0] === '=')
937 - ) {
938 - $newToken = [];
939 - $newToken['code'] = T_COALESCE_EQUAL;
940 - $newToken['type'] = 'T_COALESCE_EQUAL';
941 - $newToken['content'] = '??=';
942 - $finalTokens[$newStackPtr] = $newToken;
925 + if ( ( $tokenIsArray === false
926 + && $token[0] === '?'
927 + && isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
928 + && $tokens[ ( $stackPtr + 1 ) ][0] === '?'
929 + && isset( $tokens[ ( $stackPtr + 2 ) ] ) === true
930 + && $tokens[ ( $stackPtr + 2 ) ][0] === '=' )
931 + || ( $tokenIsArray === true
932 + && $token[0] === T_COALESCE
933 + && isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
934 + && $tokens[ ( $stackPtr + 1 ) ][0] === '=' )
935 + ) {
936 + $newToken = [];
937 + $newToken['code'] = T_COALESCE_EQUAL;
938 + $newToken['type'] = 'T_COALESCE_EQUAL';
939 + $newToken['content'] = '??=';
940 + $finalTokens[ $newStackPtr ] = $newToken;
943 941
944 - $newStackPtr++;
945 - $stackPtr++;
942 + $newStackPtr ++;
943 + $stackPtr ++;
946 944
947 - if ($tokenIsArray === false) {
948 - // Pre PHP 7.
949 - $stackPtr++;
950 - }
945 + if ( $tokenIsArray === false ) {
946 + // Pre PHP 7.
947 + $stackPtr ++;
948 + }
951 949
952 - continue;
953 - }
950 + continue;
951 + }
954 952
955 - /*
953 + /*
956 954 Before PHP 7, the ?? operator was tokenized as
957 955 T_INLINE_THEN followed by T_INLINE_THEN.
958 956 So look for and combine these tokens in earlier versions.
959 957 */
960 958
961 - if ($tokenIsArray === false
962 - && $token[0] === '?'
963 - && isset($tokens[($stackPtr + 1)]) === true
964 - && $tokens[($stackPtr + 1)][0] === '?'
965 - ) {
966 - $newToken = [];
967 - $newToken['code'] = T_COALESCE;
968 - $newToken['type'] = 'T_COALESCE';
969 - $newToken['content'] = '??';
970 - $finalTokens[$newStackPtr] = $newToken;
959 + if ( $tokenIsArray === false
960 + && $token[0] === '?'
961 + && isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
962 + && $tokens[ ( $stackPtr + 1 ) ][0] === '?'
963 + ) {
964 + $newToken = [];
965 + $newToken['code'] = T_COALESCE;
966 + $newToken['type'] = 'T_COALESCE';
967 + $newToken['content'] = '??';
968 + $finalTokens[ $newStackPtr ] = $newToken;
971 969
972 - $newStackPtr++;
973 - $stackPtr++;
974 - continue;
975 - }
970 + $newStackPtr ++;
971 + $stackPtr ++;
972 + continue;
973 + }
976 974
977 - /*
975 + /*
978 976 Before PHP 7.4, underscores inside T_LNUMBER and T_DNUMBER
979 977 tokens split the token with a T_STRING. So look for
980 978 and change these tokens in earlier versions.
981 979 */
982 980
983 - if (PHP_VERSION_ID < 70400
984 - && ($tokenIsArray === true
985 - && ($token[0] === T_LNUMBER
986 - || $token[0] === T_DNUMBER)
987 - && isset($tokens[($stackPtr + 1)]) === true
988 - && is_array($tokens[($stackPtr + 1)]) === true
989 - && $tokens[($stackPtr + 1)][0] === T_STRING
990 - && $tokens[($stackPtr + 1)][1][0] === '_')
991 - ) {
992 - $newContent = $token[1];
993 - $newType = $token[0];
994 - for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
995 - if (is_array($tokens[$i]) === false) {
996 - break;
997 - }
981 + if ( PHP_VERSION_ID < 70400
982 + && ( $tokenIsArray === true
983 + && ( $token[0] === T_LNUMBER
984 + || $token[0] === T_DNUMBER )
985 + && isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
986 + && is_array( $tokens[ ( $stackPtr + 1 ) ] ) === true
987 + && $tokens[ ( $stackPtr + 1 ) ][0] === T_STRING
988 + && $tokens[ ( $stackPtr + 1 ) ][1][0] === '_' )
989 + ) {
990 + $newContent = $token[1];
991 + $newType = $token[0];
992 + for ( $i = ( $stackPtr + 1 ); $i < $numTokens; $i ++ ) {
993 + if ( is_array( $tokens[ $i ] ) === false ) {
994 + break;
995 + }
998 996
999 - if ($tokens[$i][0] === T_LNUMBER
1000 - || $tokens[$i][0] === T_DNUMBER
1001 - ) {
1002 - $newContent .= $tokens[$i][1];
1003 - continue;
1004 - }
997 + if ( $tokens[ $i ][0] === T_LNUMBER
998 + || $tokens[ $i ][0] === T_DNUMBER
999 + ) {
1000 + $newContent .= $tokens[ $i ][1];
1001 + continue;
1002 + }
1005 1003
1006 - if ($tokens[$i][0] === T_STRING
1007 - && $tokens[$i][1][0] === '_'
1008 - && ((strpos($newContent, '0x') === 0
1009 - && preg_match('`^((?<!\.)_[0-9A-F][0-9A-F\.]*)+$`iD', $tokens[$i][1]) === 1)
1010 - || (strpos($newContent, '0x') !== 0
1011 - && substr($newContent, -1) !== '.'
1012 - && substr(strtolower($newContent), -1) !== 'e'
1013 - && preg_match('`^(?:(?<![\.e])_[0-9][0-9e\.]*)+$`iD', $tokens[$i][1]) === 1))
1014 - ) {
1015 - $newContent .= $tokens[$i][1];
1004 + if ( $tokens[ $i ][0] === T_STRING
1005 + && $tokens[ $i ][1][0] === '_'
1006 + && ( ( strpos( $newContent, '0x' ) === 0
1007 + && preg_match( '`^((?<!\.)_[0-9A-F][0-9A-F\.]*)+$`iD', $tokens[ $i ][1] ) === 1 )
1008 + || ( strpos( $newContent, '0x' ) !== 0
1009 + && substr( $newContent, - 1 ) !== '.'
1010 + && substr( strtolower( $newContent ), - 1 ) !== 'e'
1011 + && preg_match( '`^(?:(?<![\.e])_[0-9][0-9e\.]*)+$`iD', $tokens[ $i ][1] ) === 1 ) )
1012 + ) {
1013 + $newContent .= $tokens[ $i ][1];
1016 1014
1017 - // Support floats.
1018 - if (substr(strtolower($tokens[$i][1]), -1) === 'e'
1019 - && ($tokens[($i + 1)] === '-'
1020 - || $tokens[($i + 1)] === '+')
1021 - ) {
1022 - $newContent .= $tokens[($i + 1)];
1023 - $i++;
1024 - }
1015 + // Support floats.
1016 + if ( substr( strtolower( $tokens[ $i ][1] ), - 1 ) === 'e'
1017 + && ( $tokens[ ( $i + 1 ) ] === '-'
1018 + || $tokens[ ( $i + 1 ) ] === '+' )
1019 + ) {
1020 + $newContent .= $tokens[ ( $i + 1 ) ];
1021 + $i ++;
1022 + }
1025 1023
1026 - continue;
1027 - }//end if
1024 + continue;
1025 + }//end if
1028 1026
1029 - break;
1030 - }//end for
1027 + break;
1028 + }//end for
1031 1029
1032 - if ($newType === T_LNUMBER
1033 - && ((stripos($newContent, '0x') === 0 && hexdec(str_replace('_', '', $newContent)) > PHP_INT_MAX)
1034 - || (stripos($newContent, '0b') === 0 && bindec(str_replace('_', '', $newContent)) > PHP_INT_MAX)
1035 - || (stripos($newContent, '0x') !== 0
1036 - && stripos($newContent, 'e') !== false || strpos($newContent, '.') !== false)
1037 - || (strpos($newContent, '0') === 0 && stripos($newContent, '0x') !== 0
1038 - && stripos($newContent, '0b') !== 0 && octdec(str_replace('_', '', $newContent)) > PHP_INT_MAX)
1039 - || (strpos($newContent, '0') !== 0 && str_replace('_', '', $newContent) > PHP_INT_MAX))
1040 - ) {
1041 - $newType = T_DNUMBER;
1042 - }
1030 + if ( $newType === T_LNUMBER
1031 + && ( ( stripos( $newContent, '0x' ) === 0 && hexdec( str_replace( '_', '', $newContent ) ) > PHP_INT_MAX )
1032 + || ( stripos( $newContent, '0b' ) === 0 && bindec( str_replace( '_', '', $newContent ) ) > PHP_INT_MAX )
1033 + || ( stripos( $newContent, '0x' ) !== 0
1034 + && stripos( $newContent, 'e' ) !== false || strpos( $newContent, '.' ) !== false )
1035 + || ( strpos( $newContent, '0' ) === 0 && stripos( $newContent, '0x' ) !== 0
1036 + && stripos( $newContent, '0b' ) !== 0 && octdec( str_replace( '_', '', $newContent ) ) > PHP_INT_MAX )
1037 + || ( strpos( $newContent, '0' ) !== 0 && str_replace( '_', '', $newContent ) > PHP_INT_MAX ) )
1038 + ) {
1039 + $newType = T_DNUMBER;
1040 + }
1043 1041
1044 - $newToken = [];
1045 - $newToken['code'] = $newType;
1046 - $newToken['type'] = Util\Tokens::tokenName($newType);
1047 - $newToken['content'] = $newContent;
1048 - $finalTokens[$newStackPtr] = $newToken;
1042 + $newToken = [];
1043 + $newToken['code'] = $newType;
1044 + $newToken['type'] = Util\Tokens::tokenName( $newType );
1045 + $newToken['content'] = $newContent;
1046 + $finalTokens[ $newStackPtr ] = $newToken;
1049 1047
1050 - $newStackPtr++;
1051 - $stackPtr = ($i - 1);
1052 - continue;
1053 - }//end if
1048 + $newStackPtr ++;
1049 + $stackPtr = ( $i - 1 );
1050 + continue;
1051 + }//end if
1054 1052
1055 - /*
1053 + /*
1056 1054 Convert ? to T_NULLABLE OR T_INLINE_THEN
1057 1055 */
1058 1056
1059 - if ($tokenIsArray === false && $token[0] === '?') {
1060 - $newToken = [];
1061 - $newToken['content'] = '?';
1057 + if ( $tokenIsArray === false && $token[0] === '?' ) {
1058 + $newToken = [];
1059 + $newToken['content'] = '?';
1062 1060
1063 - /*
1061 + /*
1064 1062 * Check if the next non-empty token is one of the tokens which can be used
1065 1063 * in type declarations. If not, it's definitely a ternary.
1066 1064 * At this point, the only token types which need to be taken into consideration
1067 1065 * as potential type declarations are T_STRING, T_ARRAY, T_CALLABLE and T_NS_SEPARATOR.
@@ -1066,171 +1064,178 @@
1066 1064 * At this point, the only token types which need to be taken into consideration
1067 1065 * as potential type declarations are T_STRING, T_ARRAY, T_CALLABLE and T_NS_SEPARATOR.
1068 1066 */
1069 1067
1070 - $lastRelevantNonEmpty = null;
1068 + $lastRelevantNonEmpty = null;
1071 1069
1072 - for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
1073 - if (is_array($tokens[$i]) === true) {
1074 - $tokenType = $tokens[$i][0];
1075 - } else {
1076 - $tokenType = $tokens[$i];
1077 - }
1070 + for ( $i = ( $stackPtr + 1 ); $i < $numTokens; $i ++ ) {
1071 + if ( is_array( $tokens[ $i ] ) === true ) {
1072 + $tokenType = $tokens[ $i ][0];
1073 + } else {
1074 + $tokenType = $tokens[ $i ];
1075 + }
1078 1076
1079 - if (isset(Util\Tokens::$emptyTokens[$tokenType]) === true) {
1080 - continue;
1081 - }
1077 + if ( isset( Util\Tokens::$emptyTokens[ $tokenType ] ) === true ) {
1078 + continue;
1079 + }
1082 1080
1083 - if ($tokenType === T_STRING
1084 - || $tokenType === T_ARRAY
1085 - || $tokenType === T_NS_SEPARATOR
1086 - ) {
1087 - $lastRelevantNonEmpty = $tokenType;
1088 - continue;
1089 - }
1081 + if ( $tokenType === T_STRING
1082 + || $tokenType === T_ARRAY
1083 + || $tokenType === T_NS_SEPARATOR
1084 + ) {
1085 + $lastRelevantNonEmpty = $tokenType;
1086 + continue;
1087 + }
1090 1088
1091 - if (($tokenType !== T_CALLABLE
1092 - && isset($lastRelevantNonEmpty) === false)
1093 - || ($lastRelevantNonEmpty === T_ARRAY
1094 - && $tokenType === '(')
1095 - || ($lastRelevantNonEmpty === T_STRING
1096 - && ($tokenType === T_DOUBLE_COLON
1097 - || $tokenType === '('
1098 - || $tokenType === ':'))
1099 - ) {
1100 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1101 - echo "\t\t* token $stackPtr changed from ? to T_INLINE_THEN".PHP_EOL;
1102 - }
1089 + if ( ( $tokenType !== T_CALLABLE
1090 + && isset( $lastRelevantNonEmpty ) === false )
1091 + || ( $lastRelevantNonEmpty === T_ARRAY
1092 + && $tokenType === '(' )
1093 + || ( $lastRelevantNonEmpty === T_STRING
1094 + && ( $tokenType === T_DOUBLE_COLON
1095 + || $tokenType === '('
1096 + || $tokenType === ':' ) )
1097 + ) {
1098 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1099 + echo "\t\t* token $stackPtr changed from ? to T_INLINE_THEN" . PHP_EOL;
1100 + }
1103 1101
1104 - $newToken['code'] = T_INLINE_THEN;
1105 - $newToken['type'] = 'T_INLINE_THEN';
1102 + $newToken['code'] = T_INLINE_THEN;
1103 + $newToken['type'] = 'T_INLINE_THEN';
1106 1104
1107 - $insideInlineIf[] = $stackPtr;
1105 + $insideInlineIf[] = $stackPtr;
1108 1106
1109 - $finalTokens[$newStackPtr] = $newToken;
1110 - $newStackPtr++;
1111 - continue 2;
1112 - }
1107 + $finalTokens[ $newStackPtr ] = $newToken;
1108 + $newStackPtr ++;
1109 + continue 2;
1110 + }
1113 1111
1114 - break;
1115 - }//end for
1112 + break;
1113 + }//end for
1116 1114
1117 - /*
1115 + /*
1118 1116 * This can still be a nullable type or a ternary.
1119 1117 * Do additional checking.
1120 1118 */
1121 1119
1122 - $prevNonEmpty = null;
1123 - $lastSeenNonEmpty = null;
1120 + $prevNonEmpty = null;
1121 + $lastSeenNonEmpty = null;
1124 1122
1125 - for ($i = ($stackPtr - 1); $i >= 0; $i--) {
1126 - if (is_array($tokens[$i]) === true) {
1127 - $tokenType = $tokens[$i][0];
1128 - } else {
1129 - $tokenType = $tokens[$i];
1130 - }
1123 + for ( $i = ( $stackPtr - 1 ); $i >= 0; $i -- ) {
1124 + if ( is_array( $tokens[ $i ] ) === true ) {
1125 + $tokenType = $tokens[ $i ][0];
1126 + } else {
1127 + $tokenType = $tokens[ $i ];
1128 + }
1131 1129
1132 - if ($tokenType === T_STATIC
1133 - && ($lastSeenNonEmpty === T_DOUBLE_COLON
1134 - || $lastSeenNonEmpty === '(')
1135 - ) {
1136 - $lastSeenNonEmpty = $tokenType;
1137 - continue;
1138 - }
1130 + if ( $tokenType === T_STATIC
1131 + && ( $lastSeenNonEmpty === T_DOUBLE_COLON
1132 + || $lastSeenNonEmpty === '(' )
1133 + ) {
1134 + $lastSeenNonEmpty = $tokenType;
1135 + continue;
1136 + }
1139 1137
1140 - if ($prevNonEmpty === null
1141 - && isset(Util\Tokens::$emptyTokens[$tokenType]) === false
1142 - ) {
1143 - // Found the previous non-empty token.
1144 - if ($tokenType === ':' || $tokenType === ',') {
1145 - $newToken['code'] = T_NULLABLE;
1146 - $newToken['type'] = 'T_NULLABLE';
1138 + if ( $prevNonEmpty === null
1139 + && isset( Util\Tokens::$emptyTokens[ $tokenType ] ) === false
1140 + ) {
1141 + // Found the previous non-empty token.
1142 + if ( $tokenType === ':' || $tokenType === ',' ) {
1143 + $newToken['code'] = T_NULLABLE;
1144 + $newToken['type'] = 'T_NULLABLE';
1147 1145
1148 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1149 - echo "\t\t* token $stackPtr changed from ? to T_NULLABLE".PHP_EOL;
1150 - }
1146 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1147 + echo "\t\t* token $stackPtr changed from ? to T_NULLABLE" . PHP_EOL;
1148 + }
1151 1149
1152 - break;
1153 - }
1150 + break;
1151 + }
1154 1152
1155 - $prevNonEmpty = $tokenType;
1156 - }
1153 + $prevNonEmpty = $tokenType;
1154 + }
1157 1155
1158 - if ($tokenType === T_FUNCTION
1159 - || $tokenType === T_FN
1160 - || isset(Util\Tokens::$methodPrefixes[$tokenType]) === true
1161 - || $tokenType === T_VAR
1162 - ) {
1163 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1164 - echo "\t\t* token $stackPtr changed from ? to T_NULLABLE".PHP_EOL;
1165 - }
1156 + if ( $tokenType === T_FUNCTION
1157 + || $tokenType === T_FN
1158 + || isset( Util\Tokens::$methodPrefixes[ $tokenType ] ) === true
1159 + || $tokenType === T_VAR
1160 + ) {
1161 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1162 + echo "\t\t* token $stackPtr changed from ? to T_NULLABLE" . PHP_EOL;
1163 + }
1166 1164
1167 - $newToken['code'] = T_NULLABLE;
1168 - $newToken['type'] = 'T_NULLABLE';
1169 - break;
1170 - } else if (in_array($tokenType, [T_DOUBLE_ARROW, T_OPEN_TAG, T_OPEN_TAG_WITH_ECHO, '=', '{', ';'], true) === true) {
1171 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1172 - echo "\t\t* token $stackPtr changed from ? to T_INLINE_THEN".PHP_EOL;
1173 - }
1165 + $newToken['code'] = T_NULLABLE;
1166 + $newToken['type'] = 'T_NULLABLE';
1167 + break;
1168 + } else if ( in_array( $tokenType, [
1169 + T_DOUBLE_ARROW,
1170 + T_OPEN_TAG,
1171 + T_OPEN_TAG_WITH_ECHO,
1172 + '=',
1173 + '{',
1174 + ';'
1175 + ], true ) === true ) {
1176 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1177 + echo "\t\t* token $stackPtr changed from ? to T_INLINE_THEN" . PHP_EOL;
1178 + }
1174 1179
1175 - $newToken['code'] = T_INLINE_THEN;
1176 - $newToken['type'] = 'T_INLINE_THEN';
1180 + $newToken['code'] = T_INLINE_THEN;
1181 + $newToken['type'] = 'T_INLINE_THEN';
1177 1182
1178 - $insideInlineIf[] = $stackPtr;
1179 - break;
1180 - }
1183 + $insideInlineIf[] = $stackPtr;
1184 + break;
1185 + }
1181 1186
1182 - if (isset(Util\Tokens::$emptyTokens[$tokenType]) === false) {
1183 - $lastSeenNonEmpty = $tokenType;
1184 - }
1185 - }//end for
1187 + if ( isset( Util\Tokens::$emptyTokens[ $tokenType ] ) === false ) {
1188 + $lastSeenNonEmpty = $tokenType;
1189 + }
1190 + }//end for
1186 1191
1187 - $finalTokens[$newStackPtr] = $newToken;
1188 - $newStackPtr++;
1189 - continue;
1190 - }//end if
1192 + $finalTokens[ $newStackPtr ] = $newToken;
1193 + $newStackPtr ++;
1194 + continue;
1195 + }//end if
1191 1196
1192 - /*
1197 + /*
1193 1198 Tokens after a double colon may look like scope openers,
1194 1199 such as when writing code like Foo::NAMESPACE, but they are
1195 1200 only ever variables or strings.
1196 1201 */
1197 1202
1198 - if ($stackPtr > 1
1199 - && (is_array($tokens[($stackPtr - 1)]) === true
1200 - && $tokens[($stackPtr - 1)][0] === T_PAAMAYIM_NEKUDOTAYIM)
1201 - && $tokenIsArray === true
1202 - && $token[0] !== T_STRING
1203 - && $token[0] !== T_VARIABLE
1204 - && $token[0] !== T_DOLLAR
1205 - && isset(Util\Tokens::$emptyTokens[$token[0]]) === false
1206 - ) {
1207 - $newToken = [];
1208 - $newToken['code'] = T_STRING;
1209 - $newToken['type'] = 'T_STRING';
1210 - $newToken['content'] = $token[1];
1211 - $finalTokens[$newStackPtr] = $newToken;
1203 + if ( $stackPtr > 1
1204 + && ( is_array( $tokens[ ( $stackPtr - 1 ) ] ) === true
1205 + && $tokens[ ( $stackPtr - 1 ) ][0] === T_PAAMAYIM_NEKUDOTAYIM )
1206 + && $tokenIsArray === true
1207 + && $token[0] !== T_STRING
1208 + && $token[0] !== T_VARIABLE
1209 + && $token[0] !== T_DOLLAR
1210 + && isset( Util\Tokens::$emptyTokens[ $token[0] ] ) === false
1211 + ) {
1212 + $newToken = [];
1213 + $newToken['code'] = T_STRING;
1214 + $newToken['type'] = 'T_STRING';
1215 + $newToken['content'] = $token[1];
1216 + $finalTokens[ $newStackPtr ] = $newToken;
1212 1217
1213 - $newStackPtr++;
1214 - continue;
1215 - }
1218 + $newStackPtr ++;
1219 + continue;
1220 + }
1216 1221
1217 - /*
1222 + /*
1218 1223 Backfill the T_FN token for PHP versions < 7.4.
1219 1224 */
1220 1225
1221 - if ($tokenIsArray === true
1222 - && $token[0] === T_STRING
1223 - && strtolower($token[1]) === 'fn'
1224 - ) {
1225 - // Modify the original token stack so that
1226 - // future checks (like looking for T_NULLABLE) can
1227 - // detect the T_FN token more easily.
1228 - $tokens[$stackPtr][0] = T_FN;
1229 - $token[0] = T_FN;
1230 - }
1226 + if ( $tokenIsArray === true
1227 + && $token[0] === T_STRING
1228 + && strtolower( $token[1] ) === 'fn'
1229 + ) {
1230 + // Modify the original token stack so that
1231 + // future checks (like looking for T_NULLABLE) can
1232 + // detect the T_FN token more easily.
1233 + $tokens[ $stackPtr ][0] = T_FN;
1234 + $token[0] = T_FN;
1235 + }
1231 1236
1232 - /*
1237 + /*
1233 1238 The string-like token after a function keyword should always be
1234 1239 tokenized as T_STRING even if it appears to be a different token,
1235 1240 such as when writing code like: function default(): foo
1236 1241 so go forward and change the token type before it is processed.
@@ -1235,151 +1240,151 @@
1235 1240 such as when writing code like: function default(): foo
1236 1241 so go forward and change the token type before it is processed.
1237 1242 */
1238 1243
1239 - if ($tokenIsArray === true
1240 - && ($token[0] === T_FUNCTION
1241 - || $token[0] === T_FN)
1242 - && $finalTokens[$lastNotEmptyToken]['code'] !== T_USE
1243 - ) {
1244 - for ($x = ($stackPtr + 1); $x < $numTokens; $x++) {
1245 - if (is_array($tokens[$x]) === false
1246 - || isset(Util\Tokens::$emptyTokens[$tokens[$x][0]]) === false
1247 - ) {
1248 - // Non-empty content.
1249 - break;
1250 - }
1251 - }
1244 + if ( $tokenIsArray === true
1245 + && ( $token[0] === T_FUNCTION
1246 + || $token[0] === T_FN )
1247 + && $finalTokens[ $lastNotEmptyToken ]['code'] !== T_USE
1248 + ) {
1249 + for ( $x = ( $stackPtr + 1 ); $x < $numTokens; $x ++ ) {
1250 + if ( is_array( $tokens[ $x ] ) === false
1251 + || isset( Util\Tokens::$emptyTokens[ $tokens[ $x ][0] ] ) === false
1252 + ) {
1253 + // Non-empty content.
1254 + break;
1255 + }
1256 + }
1252 1257
1253 - if ($x < $numTokens && is_array($tokens[$x]) === true) {
1254 - $tokens[$x][0] = T_STRING;
1255 - }
1258 + if ( $x < $numTokens && is_array( $tokens[ $x ] ) === true ) {
1259 + $tokens[ $x ][0] = T_STRING;
1260 + }
1256 1261
1257 - /*
1262 + /*
1258 1263 This is a special condition for T_ARRAY tokens used for
1259 1264 function return types. We want to keep the parenthesis map clean,
1260 1265 so let's tag these tokens as T_STRING.
1261 1266 */
1262 1267
1263 - // Go looking for the colon to start the return type hint.
1264 - // Start by finding the closing parenthesis of the function.
1265 - $parenthesisStack = [];
1266 - $parenthesisCloser = false;
1267 - for ($x = ($stackPtr + 1); $x < $numTokens; $x++) {
1268 - if (is_array($tokens[$x]) === false && $tokens[$x] === '(') {
1269 - $parenthesisStack[] = $x;
1270 - } else if (is_array($tokens[$x]) === false && $tokens[$x] === ')') {
1271 - array_pop($parenthesisStack);
1272 - if (empty($parenthesisStack) === true) {
1273 - $parenthesisCloser = $x;
1274 - break;
1275 - }
1276 - }
1277 - }
1268 + // Go looking for the colon to start the return type hint.
1269 + // Start by finding the closing parenthesis of the function.
1270 + $parenthesisStack = [];
1271 + $parenthesisCloser = false;
1272 + for ( $x = ( $stackPtr + 1 ); $x < $numTokens; $x ++ ) {
1273 + if ( is_array( $tokens[ $x ] ) === false && $tokens[ $x ] === '(' ) {
1274 + $parenthesisStack[] = $x;
1275 + } else if ( is_array( $tokens[ $x ] ) === false && $tokens[ $x ] === ')' ) {
1276 + array_pop( $parenthesisStack );
1277 + if ( empty( $parenthesisStack ) === true ) {
1278 + $parenthesisCloser = $x;
1279 + break;
1280 + }
1281 + }
1282 + }
1278 1283
1279 - if ($parenthesisCloser !== false) {
1280 - for ($x = ($parenthesisCloser + 1); $x < $numTokens; $x++) {
1281 - if (is_array($tokens[$x]) === false
1282 - || isset(Util\Tokens::$emptyTokens[$tokens[$x][0]]) === false
1283 - ) {
1284 - // Non-empty content.
1285 - if (is_array($tokens[$x]) === true && $tokens[$x][0] === T_USE) {
1286 - // Found a use statements, so search ahead for the closing parenthesis.
1287 - for ($x += 1; $x < $numTokens; $x++) {
1288 - if (is_array($tokens[$x]) === false && $tokens[$x] === ')') {
1289 - continue(2);
1290 - }
1291 - }
1292 - }
1284 + if ( $parenthesisCloser !== false ) {
1285 + for ( $x = ( $parenthesisCloser + 1 ); $x < $numTokens; $x ++ ) {
1286 + if ( is_array( $tokens[ $x ] ) === false
1287 + || isset( Util\Tokens::$emptyTokens[ $tokens[ $x ][0] ] ) === false
1288 + ) {
1289 + // Non-empty content.
1290 + if ( is_array( $tokens[ $x ] ) === true && $tokens[ $x ][0] === T_USE ) {
1291 + // Found a use statements, so search ahead for the closing parenthesis.
1292 + for ( $x += 1; $x < $numTokens; $x ++ ) {
1293 + if ( is_array( $tokens[ $x ] ) === false && $tokens[ $x ] === ')' ) {
1294 + continue( 2 );
1295 + }
1296 + }
1297 + }
1293 1298
1294 - break;
1295 - }
1296 - }
1299 + break;
1300 + }
1301 + }
1297 1302
1298 - if (isset($tokens[$x]) === true
1299 - && is_array($tokens[$x]) === false
1300 - && $tokens[$x] === ':'
1301 - ) {
1302 - $allowed = [
1303 - T_STRING => T_STRING,
1304 - T_ARRAY => T_ARRAY,
1305 - T_CALLABLE => T_CALLABLE,
1306 - T_SELF => T_SELF,
1307 - T_PARENT => T_PARENT,
1308 - T_NS_SEPARATOR => T_NS_SEPARATOR,
1309 - ];
1303 + if ( isset( $tokens[ $x ] ) === true
1304 + && is_array( $tokens[ $x ] ) === false
1305 + && $tokens[ $x ] === ':'
1306 + ) {
1307 + $allowed = [
1308 + T_STRING => T_STRING,
1309 + T_ARRAY => T_ARRAY,
1310 + T_CALLABLE => T_CALLABLE,
1311 + T_SELF => T_SELF,
1312 + T_PARENT => T_PARENT,
1313 + T_NS_SEPARATOR => T_NS_SEPARATOR,
1314 + ];
1310 1315
1311 - $allowed += Util\Tokens::$emptyTokens;
1316 + $allowed += Util\Tokens::$emptyTokens;
1312 1317
1313 - // Find the start of the return type.
1314 - for ($x += 1; $x < $numTokens; $x++) {
1315 - if (is_array($tokens[$x]) === true
1316 - && isset(Util\Tokens::$emptyTokens[$tokens[$x][0]]) === true
1317 - ) {
1318 - // Whitespace or comments before the return type.
1319 - continue;
1320 - }
1318 + // Find the start of the return type.
1319 + for ( $x += 1; $x < $numTokens; $x ++ ) {
1320 + if ( is_array( $tokens[ $x ] ) === true
1321 + && isset( Util\Tokens::$emptyTokens[ $tokens[ $x ][0] ] ) === true
1322 + ) {
1323 + // Whitespace or comments before the return type.
1324 + continue;
1325 + }
1321 1326
1322 - if (is_array($tokens[$x]) === false && $tokens[$x] === '?') {
1323 - // Found a nullable operator, so skip it.
1324 - // But also covert the token to save the tokenizer
1325 - // a bit of time later on.
1326 - $tokens[$x] = [
1327 - T_NULLABLE,
1328 - '?',
1329 - ];
1327 + if ( is_array( $tokens[ $x ] ) === false && $tokens[ $x ] === '?' ) {
1328 + // Found a nullable operator, so skip it.
1329 + // But also covert the token to save the tokenizer
1330 + // a bit of time later on.
1331 + $tokens[ $x ] = [
1332 + T_NULLABLE,
1333 + '?',
1334 + ];
1330 1335
1331 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1332 - echo "\t\t* token $x changed from ? to T_NULLABLE".PHP_EOL;
1333 - }
1336 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1337 + echo "\t\t* token $x changed from ? to T_NULLABLE" . PHP_EOL;
1338 + }
1334 1339
1335 - continue;
1336 - }
1340 + continue;
1341 + }
1337 1342
1338 - break;
1339 - }//end for
1343 + break;
1344 + }//end for
1340 1345
1341 - // Any T_ARRAY tokens we find between here and the next
1342 - // token that can't be part of the return type need to be
1343 - // converted to T_STRING tokens.
1344 - for ($x; $x < $numTokens; $x++) {
1345 - if (is_array($tokens[$x]) === false || isset($allowed[$tokens[$x][0]]) === false) {
1346 - break;
1347 - } else if ($tokens[$x][0] === T_ARRAY) {
1348 - $tokens[$x][0] = T_STRING;
1346 + // Any T_ARRAY tokens we find between here and the next
1347 + // token that can't be part of the return type need to be
1348 + // converted to T_STRING tokens.
1349 + for ( $x; $x < $numTokens; $x ++ ) {
1350 + if ( is_array( $tokens[ $x ] ) === false || isset( $allowed[ $tokens[ $x ][0] ] ) === false ) {
1351 + break;
1352 + } else if ( $tokens[ $x ][0] === T_ARRAY ) {
1353 + $tokens[ $x ][0] = T_STRING;
1349 1354
1350 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1351 - echo "\t\t* token $x changed from T_ARRAY to T_STRING".PHP_EOL;
1352 - }
1353 - }
1354 - }
1355 - }//end if
1356 - }//end if
1357 - }//end if
1355 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1356 + echo "\t\t* token $x changed from T_ARRAY to T_STRING" . PHP_EOL;
1357 + }
1358 + }
1359 + }
1360 + }//end if
1361 + }//end if
1362 + }//end if
1358 1363
1359 - /*
1364 + /*
1360 1365 Before PHP 7, the <=> operator was tokenized as
1361 1366 T_IS_SMALLER_OR_EQUAL followed by T_GREATER_THAN.
1362 1367 So look for and combine these tokens in earlier versions.
1363 1368 */
1364 1369
1365 - if ($tokenIsArray === true
1366 - && $token[0] === T_IS_SMALLER_OR_EQUAL
1367 - && isset($tokens[($stackPtr + 1)]) === true
1368 - && $tokens[($stackPtr + 1)][0] === '>'
1369 - ) {
1370 - $newToken = [];
1371 - $newToken['code'] = T_SPACESHIP;
1372 - $newToken['type'] = 'T_SPACESHIP';
1373 - $newToken['content'] = '<=>';
1374 - $finalTokens[$newStackPtr] = $newToken;
1370 + if ( $tokenIsArray === true
1371 + && $token[0] === T_IS_SMALLER_OR_EQUAL
1372 + && isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
1373 + && $tokens[ ( $stackPtr + 1 ) ][0] === '>'
1374 + ) {
1375 + $newToken = [];
1376 + $newToken['code'] = T_SPACESHIP;
1377 + $newToken['type'] = 'T_SPACESHIP';
1378 + $newToken['content'] = '<=>';
1379 + $finalTokens[ $newStackPtr ] = $newToken;
1375 1380
1376 - $newStackPtr++;
1377 - $stackPtr++;
1378 - continue;
1379 - }
1381 + $newStackPtr ++;
1382 + $stackPtr ++;
1383 + continue;
1384 + }
1380 1385
1381 - /*
1386 + /*
1382 1387 PHP doesn't assign a token to goto labels, so we have to.
1383 1388 These are just string tokens with a single colon after them. Double
1384 1389 colons are already tokenized and so don't interfere with this check.
1385 1390 But we do have to account for CASE statements, that look just like
@@ -1385,48 +1390,48 @@
1385 1390 But we do have to account for CASE statements, that look just like
1386 1391 goto labels.
1387 1392 */
1388 1393
1389 - if ($tokenIsArray === true
1390 - && $token[0] === T_STRING
1391 - && isset($tokens[($stackPtr + 1)]) === true
1392 - && $tokens[($stackPtr + 1)] === ':'
1393 - && $tokens[($stackPtr - 1)][0] !== T_PAAMAYIM_NEKUDOTAYIM
1394 - ) {
1395 - $stopTokens = [
1396 - T_CASE => true,
1397 - T_SEMICOLON => true,
1398 - T_OPEN_CURLY_BRACKET => true,
1399 - T_INLINE_THEN => true,
1400 - ];
1394 + if ( $tokenIsArray === true
1395 + && $token[0] === T_STRING
1396 + && isset( $tokens[ ( $stackPtr + 1 ) ] ) === true
1397 + && $tokens[ ( $stackPtr + 1 ) ] === ':'
1398 + && $tokens[ ( $stackPtr - 1 ) ][0] !== T_PAAMAYIM_NEKUDOTAYIM
1399 + ) {
1400 + $stopTokens = [
1401 + T_CASE => true,
1402 + T_SEMICOLON => true,
1403 + T_OPEN_CURLY_BRACKET => true,
1404 + T_INLINE_THEN => true,
1405 + ];
1401 1406
1402 - for ($x = ($newStackPtr - 1); $x > 0; $x--) {
1403 - if (isset($stopTokens[$finalTokens[$x]['code']]) === true) {
1404 - break;
1405 - }
1406 - }
1407 + for ( $x = ( $newStackPtr - 1 ); $x > 0; $x -- ) {
1408 + if ( isset( $stopTokens[ $finalTokens[ $x ]['code'] ] ) === true ) {
1409 + break;
1410 + }
1411 + }
1407 1412
1408 - if ($finalTokens[$x]['code'] !== T_CASE
1409 - && $finalTokens[$x]['code'] !== T_INLINE_THEN
1410 - ) {
1411 - $finalTokens[$newStackPtr] = [
1412 - 'content' => $token[1].':',
1413 - 'code' => T_GOTO_LABEL,
1414 - 'type' => 'T_GOTO_LABEL',
1415 - ];
1413 + if ( $finalTokens[ $x ]['code'] !== T_CASE
1414 + && $finalTokens[ $x ]['code'] !== T_INLINE_THEN
1415 + ) {
1416 + $finalTokens[ $newStackPtr ] = [
1417 + 'content' => $token[1] . ':',
1418 + 'code' => T_GOTO_LABEL,
1419 + 'type' => 'T_GOTO_LABEL',
1420 + ];
1416 1421
1417 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1418 - echo "\t\t* token $stackPtr changed from T_STRING to T_GOTO_LABEL".PHP_EOL;
1419 - echo "\t\t* skipping T_COLON token ".($stackPtr + 1).PHP_EOL;
1420 - }
1422 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1423 + echo "\t\t* token $stackPtr changed from T_STRING to T_GOTO_LABEL" . PHP_EOL;
1424 + echo "\t\t* skipping T_COLON token " . ( $stackPtr + 1 ) . PHP_EOL;
1425 + }
1421 1426
1422 - $newStackPtr++;
1423 - $stackPtr++;
1424 - continue;
1425 - }
1426 - }//end if
1427 + $newStackPtr ++;
1428 + $stackPtr ++;
1429 + continue;
1430 + }
1431 + }//end if
1427 1432
1428 - /*
1433 + /*
1429 1434 If this token has newlines in its content, split each line up
1430 1435 and create a new token for each line. We do this so it's easier
1431 1436 to ascertain where errors occur on a line.
1432 1437 Note that $token[1] is the token's content.
@@ -1431,943 +1436,943 @@
1431 1436 to ascertain where errors occur on a line.
1432 1437 Note that $token[1] is the token's content.
1433 1438 */
1434 1439
1435 - if ($tokenIsArray === true && strpos($token[1], $this->eolChar) !== false) {
1436 - $tokenLines = explode($this->eolChar, $token[1]);
1437 - $numLines = count($tokenLines);
1438 - $newToken = [
1439 - 'type' => Util\Tokens::tokenName($token[0]),
1440 - 'code' => $token[0],
1441 - 'content' => '',
1442 - ];
1440 + if ( $tokenIsArray === true && strpos( $token[1], $this->eolChar ) !== false ) {
1441 + $tokenLines = explode( $this->eolChar, $token[1] );
1442 + $numLines = count( $tokenLines );
1443 + $newToken = [
1444 + 'type' => Util\Tokens::tokenName( $token[0] ),
1445 + 'code' => $token[0],
1446 + 'content' => '',
1447 + ];
1443 1448
1444 - for ($i = 0; $i < $numLines; $i++) {
1445 - $newToken['content'] = $tokenLines[$i];
1446 - if ($i === ($numLines - 1)) {
1447 - if ($tokenLines[$i] === '') {
1448 - break;
1449 - }
1450 - } else {
1451 - $newToken['content'] .= $this->eolChar;
1452 - }
1449 + for ( $i = 0; $i < $numLines; $i ++ ) {
1450 + $newToken['content'] = $tokenLines[ $i ];
1451 + if ( $i === ( $numLines - 1 ) ) {
1452 + if ( $tokenLines[ $i ] === '' ) {
1453 + break;
1454 + }
1455 + } else {
1456 + $newToken['content'] .= $this->eolChar;
1457 + }
1453 1458
1454 - $finalTokens[$newStackPtr] = $newToken;
1455 - $newStackPtr++;
1456 - }
1457 - } else {
1458 - if ($tokenIsArray === true && $token[0] === T_STRING) {
1459 - // Some T_STRING tokens should remain that way
1460 - // due to their context.
1461 - $context = [
1462 - T_OBJECT_OPERATOR => true,
1463 - T_FUNCTION => true,
1464 - T_CLASS => true,
1465 - T_EXTENDS => true,
1466 - T_IMPLEMENTS => true,
1467 - T_NEW => true,
1468 - T_CONST => true,
1469 - T_NS_SEPARATOR => true,
1470 - T_USE => true,
1471 - T_NAMESPACE => true,
1472 - T_PAAMAYIM_NEKUDOTAYIM => true,
1473 - ];
1459 + $finalTokens[ $newStackPtr ] = $newToken;
1460 + $newStackPtr ++;
1461 + }
1462 + } else {
1463 + if ( $tokenIsArray === true && $token[0] === T_STRING ) {
1464 + // Some T_STRING tokens should remain that way
1465 + // due to their context.
1466 + $context = [
1467 + T_OBJECT_OPERATOR => true,
1468 + T_FUNCTION => true,
1469 + T_CLASS => true,
1470 + T_EXTENDS => true,
1471 + T_IMPLEMENTS => true,
1472 + T_NEW => true,
1473 + T_CONST => true,
1474 + T_NS_SEPARATOR => true,
1475 + T_USE => true,
1476 + T_NAMESPACE => true,
1477 + T_PAAMAYIM_NEKUDOTAYIM => true,
1478 + ];
1474 1479
1475 - if (isset($context[$finalTokens[$lastNotEmptyToken]['code']]) === true) {
1476 - // Special case for syntax like: return new self
1477 - // where self should not be a string.
1478 - if ($finalTokens[$lastNotEmptyToken]['code'] === T_NEW
1479 - && strtolower($token[1]) === 'self'
1480 - ) {
1481 - $finalTokens[$newStackPtr] = [
1482 - 'content' => $token[1],
1483 - 'code' => T_SELF,
1484 - 'type' => 'T_SELF',
1485 - ];
1486 - } else {
1487 - $finalTokens[$newStackPtr] = [
1488 - 'content' => $token[1],
1489 - 'code' => T_STRING,
1490 - 'type' => 'T_STRING',
1491 - ];
1492 - }
1480 + if ( isset( $context[ $finalTokens[ $lastNotEmptyToken ]['code'] ] ) === true ) {
1481 + // Special case for syntax like: return new self
1482 + // where self should not be a string.
1483 + if ( $finalTokens[ $lastNotEmptyToken ]['code'] === T_NEW
1484 + && strtolower( $token[1] ) === 'self'
1485 + ) {
1486 + $finalTokens[ $newStackPtr ] = [
1487 + 'content' => $token[1],
1488 + 'code' => T_SELF,
1489 + 'type' => 'T_SELF',
1490 + ];
1491 + } else {
1492 + $finalTokens[ $newStackPtr ] = [
1493 + 'content' => $token[1],
1494 + 'code' => T_STRING,
1495 + 'type' => 'T_STRING',
1496 + ];
1497 + }
1493 1498
1494 - $newStackPtr++;
1495 - continue;
1496 - }//end if
1497 - }//end if
1499 + $newStackPtr ++;
1500 + continue;
1501 + }//end if
1502 + }//end if
1498 1503
1499 - $newToken = null;
1500 - if ($tokenIsArray === false) {
1501 - if (isset(self::$resolveTokenCache[$token[0]]) === true) {
1502 - $newToken = self::$resolveTokenCache[$token[0]];
1503 - }
1504 - } else {
1505 - $cacheKey = null;
1506 - if ($token[0] === T_STRING) {
1507 - $cacheKey = strtolower($token[1]);
1508 - } else if ($token[0] !== T_CURLY_OPEN) {
1509 - $cacheKey = $token[0];
1510 - }
1504 + $newToken = null;
1505 + if ( $tokenIsArray === false ) {
1506 + if ( isset( self::$resolveTokenCache[ $token[0] ] ) === true ) {
1507 + $newToken = self::$resolveTokenCache[ $token[0] ];
1508 + }
1509 + } else {
1510 + $cacheKey = null;
1511 + if ( $token[0] === T_STRING ) {
1512 + $cacheKey = strtolower( $token[1] );
1513 + } else if ( $token[0] !== T_CURLY_OPEN ) {
1514 + $cacheKey = $token[0];
1515 + }
1511 1516
1512 - if ($cacheKey !== null && isset(self::$resolveTokenCache[$cacheKey]) === true) {
1513 - $newToken = self::$resolveTokenCache[$cacheKey];
1514 - $newToken['content'] = $token[1];
1515 - }
1516 - }
1517 + if ( $cacheKey !== null && isset( self::$resolveTokenCache[ $cacheKey ] ) === true ) {
1518 + $newToken = self::$resolveTokenCache[ $cacheKey ];
1519 + $newToken['content'] = $token[1];
1520 + }
1521 + }
1517 1522
1518 - if ($newToken === null) {
1519 - $newToken = self::standardiseToken($token);
1520 - }
1523 + if ( $newToken === null ) {
1524 + $newToken = self::standardiseToken( $token );
1525 + }
1521 1526
1522 - // Convert colons that are actually the ELSE component of an
1523 - // inline IF statement.
1524 - if (empty($insideInlineIf) === false && $newToken['code'] === T_COLON) {
1525 - // Make sure this isn't the return type separator of a closure.
1526 - $isInlineIf = true;
1527 - for ($i = ($stackPtr - 1); $i > 0; $i--) {
1528 - if (is_array($tokens[$i]) === false
1529 - || ($tokens[$i][0] !== T_DOC_COMMENT
1530 - && $tokens[$i][0] !== T_COMMENT
1531 - && $tokens[$i][0] !== T_WHITESPACE)
1532 - ) {
1533 - break;
1534 - }
1535 - }
1527 + // Convert colons that are actually the ELSE component of an
1528 + // inline IF statement.
1529 + if ( empty( $insideInlineIf ) === false && $newToken['code'] === T_COLON ) {
1530 + // Make sure this isn't the return type separator of a closure.
1531 + $isInlineIf = true;
1532 + for ( $i = ( $stackPtr - 1 ); $i > 0; $i -- ) {
1533 + if ( is_array( $tokens[ $i ] ) === false
1534 + || ( $tokens[ $i ][0] !== T_DOC_COMMENT
1535 + && $tokens[ $i ][0] !== T_COMMENT
1536 + && $tokens[ $i ][0] !== T_WHITESPACE )
1537 + ) {
1538 + break;
1539 + }
1540 + }
1536 1541
1537 - if ($tokens[$i] === ')') {
1538 - $parenCount = 1;
1539 - for ($i--; $i > 0; $i--) {
1540 - if ($tokens[$i] === '(') {
1541 - $parenCount--;
1542 - if ($parenCount === 0) {
1543 - break;
1544 - }
1545 - } else if ($tokens[$i] === ')') {
1546 - $parenCount++;
1547 - }
1548 - }
1542 + if ( $tokens[ $i ] === ')' ) {
1543 + $parenCount = 1;
1544 + for ( $i --; $i > 0; $i -- ) {
1545 + if ( $tokens[ $i ] === '(' ) {
1546 + $parenCount --;
1547 + if ( $parenCount === 0 ) {
1548 + break;
1549 + }
1550 + } else if ( $tokens[ $i ] === ')' ) {
1551 + $parenCount ++;
1552 + }
1553 + }
1549 1554
1550 - // We've found the open parenthesis, so if the previous
1551 - // non-empty token is FUNCTION or USE, this is a closure.
1552 - for ($i--; $i > 0; $i--) {
1553 - if (is_array($tokens[$i]) === false
1554 - || ($tokens[$i][0] !== T_DOC_COMMENT
1555 - && $tokens[$i][0] !== T_COMMENT
1556 - && $tokens[$i][0] !== T_WHITESPACE)
1557 - ) {
1558 - break;
1559 - }
1560 - }
1555 + // We've found the open parenthesis, so if the previous
1556 + // non-empty token is FUNCTION or USE, this is a closure.
1557 + for ( $i --; $i > 0; $i -- ) {
1558 + if ( is_array( $tokens[ $i ] ) === false
1559 + || ( $tokens[ $i ][0] !== T_DOC_COMMENT
1560 + && $tokens[ $i ][0] !== T_COMMENT
1561 + && $tokens[ $i ][0] !== T_WHITESPACE )
1562 + ) {
1563 + break;
1564 + }
1565 + }
1561 1566
1562 - if ($tokens[$i][0] === T_FUNCTION || $tokens[$i][0] === T_FN || $tokens[$i][0] === T_USE) {
1563 - $isInlineIf = false;
1564 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1565 - echo "\t\t* token is function return type, not T_INLINE_ELSE".PHP_EOL;
1566 - }
1567 - }
1568 - }//end if
1567 + if ( $tokens[ $i ][0] === T_FUNCTION || $tokens[ $i ][0] === T_FN || $tokens[ $i ][0] === T_USE ) {
1568 + $isInlineIf = false;
1569 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1570 + echo "\t\t* token is function return type, not T_INLINE_ELSE" . PHP_EOL;
1571 + }
1572 + }
1573 + }//end if
1569 1574
1570 - // Check to see if this is a CASE or DEFAULT opener.
1571 - $inlineIfToken = $insideInlineIf[(count($insideInlineIf) - 1)];
1572 - for ($i = $stackPtr; $i > $inlineIfToken; $i--) {
1573 - if (is_array($tokens[$i]) === true
1574 - && ($tokens[$i][0] === T_CASE
1575 - || $tokens[$i][0] === T_DEFAULT)
1576 - ) {
1577 - $isInlineIf = false;
1578 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1579 - echo "\t\t* token is T_CASE or T_DEFAULT opener, not T_INLINE_ELSE".PHP_EOL;
1580 - }
1575 + // Check to see if this is a CASE or DEFAULT opener.
1576 + $inlineIfToken = $insideInlineIf[ ( count( $insideInlineIf ) - 1 ) ];
1577 + for ( $i = $stackPtr; $i > $inlineIfToken; $i -- ) {
1578 + if ( is_array( $tokens[ $i ] ) === true
1579 + && ( $tokens[ $i ][0] === T_CASE
1580 + || $tokens[ $i ][0] === T_DEFAULT )
1581 + ) {
1582 + $isInlineIf = false;
1583 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1584 + echo "\t\t* token is T_CASE or T_DEFAULT opener, not T_INLINE_ELSE" . PHP_EOL;
1585 + }
1581 1586
1582 - break;
1583 - }
1587 + break;
1588 + }
1584 1589
1585 - if (is_array($tokens[$i]) === false
1586 - && ($tokens[$i] === ';'
1587 - || $tokens[$i] === '{')
1588 - ) {
1589 - break;
1590 - }
1591 - }
1590 + if ( is_array( $tokens[ $i ] ) === false
1591 + && ( $tokens[ $i ] === ';'
1592 + || $tokens[ $i ] === '{' )
1593 + ) {
1594 + break;
1595 + }
1596 + }
1592 1597
1593 - if ($isInlineIf === true) {
1594 - array_pop($insideInlineIf);
1595 - $newToken['code'] = T_INLINE_ELSE;
1596 - $newToken['type'] = 'T_INLINE_ELSE';
1598 + if ( $isInlineIf === true ) {
1599 + array_pop( $insideInlineIf );
1600 + $newToken['code'] = T_INLINE_ELSE;
1601 + $newToken['type'] = 'T_INLINE_ELSE';
1597 1602
1598 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1599 - echo "\t\t* token changed from T_COLON to T_INLINE_ELSE".PHP_EOL;
1600 - }
1601 - }
1602 - }//end if
1603 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1604 + echo "\t\t* token changed from T_COLON to T_INLINE_ELSE" . PHP_EOL;
1605 + }
1606 + }
1607 + }//end if
1603 1608
1604 - // This is a special condition for T_ARRAY tokens used for
1605 - // type hinting function arguments as being arrays. We want to keep
1606 - // the parenthesis map clean, so let's tag these tokens as
1607 - // T_STRING.
1608 - if ($newToken['code'] === T_ARRAY) {
1609 - for ($i = $stackPtr; $i < $numTokens; $i++) {
1610 - if ($tokens[$i] === '(') {
1611 - break;
1612 - } else if ($tokens[$i][0] === T_VARIABLE) {
1613 - $newToken['code'] = T_STRING;
1614 - $newToken['type'] = 'T_STRING';
1615 - break;
1616 - }
1617 - }
1618 - }
1609 + // This is a special condition for T_ARRAY tokens used for
1610 + // type hinting function arguments as being arrays. We want to keep
1611 + // the parenthesis map clean, so let's tag these tokens as
1612 + // T_STRING.
1613 + if ( $newToken['code'] === T_ARRAY ) {
1614 + for ( $i = $stackPtr; $i < $numTokens; $i ++ ) {
1615 + if ( $tokens[ $i ] === '(' ) {
1616 + break;
1617 + } else if ( $tokens[ $i ][0] === T_VARIABLE ) {
1618 + $newToken['code'] = T_STRING;
1619 + $newToken['type'] = 'T_STRING';
1620 + break;
1621 + }
1622 + }
1623 + }
1619 1624
1620 - // This is a special case when checking PHP 5.5+ code in PHP < 5.5
1621 - // where "finally" should be T_FINALLY instead of T_STRING.
1622 - if ($newToken['code'] === T_STRING
1623 - && strtolower($newToken['content']) === 'finally'
1624 - ) {
1625 - $newToken['code'] = T_FINALLY;
1626 - $newToken['type'] = 'T_FINALLY';
1627 - }
1625 + // This is a special case when checking PHP 5.5+ code in PHP < 5.5
1626 + // where "finally" should be T_FINALLY instead of T_STRING.
1627 + if ( $newToken['code'] === T_STRING
1628 + && strtolower( $newToken['content'] ) === 'finally'
1629 + ) {
1630 + $newToken['code'] = T_FINALLY;
1631 + $newToken['type'] = 'T_FINALLY';
1632 + }
1628 1633
1629 - // This is a special case for the PHP 5.5 classname::class syntax
1630 - // where "class" should be T_STRING instead of T_CLASS.
1631 - if (($newToken['code'] === T_CLASS
1632 - || $newToken['code'] === T_FUNCTION)
1633 - && $finalTokens[$lastNotEmptyToken]['code'] === T_DOUBLE_COLON
1634 - ) {
1635 - $newToken['code'] = T_STRING;
1636 - $newToken['type'] = 'T_STRING';
1637 - }
1634 + // This is a special case for the PHP 5.5 classname::class syntax
1635 + // where "class" should be T_STRING instead of T_CLASS.
1636 + if ( ( $newToken['code'] === T_CLASS
1637 + || $newToken['code'] === T_FUNCTION )
1638 + && $finalTokens[ $lastNotEmptyToken ]['code'] === T_DOUBLE_COLON
1639 + ) {
1640 + $newToken['code'] = T_STRING;
1641 + $newToken['type'] = 'T_STRING';
1642 + }
1638 1643
1639 - // This is a special case for PHP 5.6 use function and use const
1640 - // where "function" and "const" should be T_STRING instead of T_FUNCTION
1641 - // and T_CONST.
1642 - if (($newToken['code'] === T_FUNCTION
1643 - || $newToken['code'] === T_CONST)
1644 - && ($finalTokens[$lastNotEmptyToken]['code'] === T_USE || $insideUseGroup === true)
1645 - ) {
1646 - $newToken['code'] = T_STRING;
1647 - $newToken['type'] = 'T_STRING';
1648 - }
1644 + // This is a special case for PHP 5.6 use function and use const
1645 + // where "function" and "const" should be T_STRING instead of T_FUNCTION
1646 + // and T_CONST.
1647 + if ( ( $newToken['code'] === T_FUNCTION
1648 + || $newToken['code'] === T_CONST )
1649 + && ( $finalTokens[ $lastNotEmptyToken ]['code'] === T_USE || $insideUseGroup === true )
1650 + ) {
1651 + $newToken['code'] = T_STRING;
1652 + $newToken['type'] = 'T_STRING';
1653 + }
1649 1654
1650 - // This is a special case for use groups in PHP 7+ where leaving
1651 - // the curly braces as their normal tokens would confuse
1652 - // the scope map and sniffs.
1653 - if ($newToken['code'] === T_OPEN_CURLY_BRACKET
1654 - && $finalTokens[$lastNotEmptyToken]['code'] === T_NS_SEPARATOR
1655 - ) {
1656 - $newToken['code'] = T_OPEN_USE_GROUP;
1657 - $newToken['type'] = 'T_OPEN_USE_GROUP';
1658 - $insideUseGroup = true;
1659 - }
1655 + // This is a special case for use groups in PHP 7+ where leaving
1656 + // the curly braces as their normal tokens would confuse
1657 + // the scope map and sniffs.
1658 + if ( $newToken['code'] === T_OPEN_CURLY_BRACKET
1659 + && $finalTokens[ $lastNotEmptyToken ]['code'] === T_NS_SEPARATOR
1660 + ) {
1661 + $newToken['code'] = T_OPEN_USE_GROUP;
1662 + $newToken['type'] = 'T_OPEN_USE_GROUP';
1663 + $insideUseGroup = true;
1664 + }
1660 1665
1661 - if ($insideUseGroup === true && $newToken['code'] === T_CLOSE_CURLY_BRACKET) {
1662 - $newToken['code'] = T_CLOSE_USE_GROUP;
1663 - $newToken['type'] = 'T_CLOSE_USE_GROUP';
1664 - $insideUseGroup = false;
1665 - }
1666 + if ( $insideUseGroup === true && $newToken['code'] === T_CLOSE_CURLY_BRACKET ) {
1667 + $newToken['code'] = T_CLOSE_USE_GROUP;
1668 + $newToken['type'] = 'T_CLOSE_USE_GROUP';
1669 + $insideUseGroup = false;
1670 + }
1666 1671
1667 - $finalTokens[$newStackPtr] = $newToken;
1668 - $newStackPtr++;
1669 - }//end if
1670 - }//end for
1672 + $finalTokens[ $newStackPtr ] = $newToken;
1673 + $newStackPtr ++;
1674 + }//end if
1675 + }//end for
1671 1676
1672 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1673 - echo "\t*** END PHP TOKENIZING ***".PHP_EOL;
1674 - }
1677 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1678 + echo "\t*** END PHP TOKENIZING ***" . PHP_EOL;
1679 + }
1675 1680
1676 - return $finalTokens;
1681 + return $finalTokens;
1677 1682
1678 - }//end tokenize()
1683 + }//end tokenize()
1679 1684
1680 1685
1681 - /**
1682 - * Performs additional processing after main tokenizing.
1683 - *
1684 - * This additional processing checks for CASE statements that are using curly
1685 - * braces for scope openers and closers. It also turns some T_FUNCTION tokens
1686 - * into T_CLOSURE when they are not standard function definitions. It also
1687 - * detects short array syntax and converts those square brackets into new tokens.
1688 - * It also corrects some usage of the static and class keywords. It also
1689 - * assigns tokens to function return types.
1690 - *
1691 - * @return void
1692 - */
1693 - protected function processAdditional()
1694 - {
1695 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1696 - echo "\t*** START ADDITIONAL PHP PROCESSING ***".PHP_EOL;
1697 - }
1686 + /**
1687 + * Performs additional processing after main tokenizing.
1688 + *
1689 + * This additional processing checks for CASE statements that are using curly
1690 + * braces for scope openers and closers. It also turns some T_FUNCTION tokens
1691 + * into T_CLOSURE when they are not standard function definitions. It also
1692 + * detects short array syntax and converts those square brackets into new tokens.
1693 + * It also corrects some usage of the static and class keywords. It also
1694 + * assigns tokens to function return types.
1695 + *
1696 + * @return void
1697 + */
1698 + protected function processAdditional() {
1699 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1700 + echo "\t*** START ADDITIONAL PHP PROCESSING ***" . PHP_EOL;
1701 + }
1698 1702
1699 - $numTokens = count($this->tokens);
1700 - for ($i = ($numTokens - 1); $i >= 0; $i--) {
1701 - // Check for any unset scope conditions due to alternate IF/ENDIF syntax.
1702 - if (isset($this->tokens[$i]['scope_opener']) === true
1703 - && isset($this->tokens[$i]['scope_condition']) === false
1704 - ) {
1705 - $this->tokens[$i]['scope_condition'] = $this->tokens[$this->tokens[$i]['scope_opener']]['scope_condition'];
1706 - }
1703 + $numTokens = count( $this->tokens );
1704 + for ( $i = ( $numTokens - 1 ); $i >= 0; $i -- ) {
1705 + // Check for any unset scope conditions due to alternate IF/ENDIF syntax.
1706 + if ( isset( $this->tokens[ $i ]['scope_opener'] ) === true
1707 + && isset( $this->tokens[ $i ]['scope_condition'] ) === false
1708 + ) {
1709 + $this->tokens[ $i ]['scope_condition'] = $this->tokens[ $this->tokens[ $i ]['scope_opener'] ]['scope_condition'];
1710 + }
1707 1711
1708 - if ($this->tokens[$i]['code'] === T_FUNCTION) {
1709 - /*
1712 + if ( $this->tokens[ $i ]['code'] === T_FUNCTION ) {
1713 + /*
1710 1714 Detect functions that are actually closures and
1711 1715 assign them a different token.
1712 1716 */
1713 1717
1714 - if (isset($this->tokens[$i]['scope_opener']) === true) {
1715 - for ($x = ($i + 1); $x < $numTokens; $x++) {
1716 - if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false
1717 - && $this->tokens[$x]['code'] !== T_BITWISE_AND
1718 - ) {
1719 - break;
1720 - }
1721 - }
1718 + if ( isset( $this->tokens[ $i ]['scope_opener'] ) === true ) {
1719 + for ( $x = ( $i + 1 ); $x < $numTokens; $x ++ ) {
1720 + if ( isset( Util\Tokens::$emptyTokens[ $this->tokens[ $x ]['code'] ] ) === false
1721 + && $this->tokens[ $x ]['code'] !== T_BITWISE_AND
1722 + ) {
1723 + break;
1724 + }
1725 + }
1722 1726
1723 - if ($this->tokens[$x]['code'] === T_OPEN_PARENTHESIS) {
1724 - $this->tokens[$i]['code'] = T_CLOSURE;
1725 - $this->tokens[$i]['type'] = 'T_CLOSURE';
1726 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1727 - $line = $this->tokens[$i]['line'];
1728 - echo "\t* token $i on line $line changed from T_FUNCTION to T_CLOSURE".PHP_EOL;
1729 - }
1727 + if ( $this->tokens[ $x ]['code'] === T_OPEN_PARENTHESIS ) {
1728 + $this->tokens[ $i ]['code'] = T_CLOSURE;
1729 + $this->tokens[ $i ]['type'] = 'T_CLOSURE';
1730 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1731 + $line = $this->tokens[ $i ]['line'];
1732 + echo "\t* token $i on line $line changed from T_FUNCTION to T_CLOSURE" . PHP_EOL;
1733 + }
1730 1734
1731 - for ($x = ($this->tokens[$i]['scope_opener'] + 1); $x < $this->tokens[$i]['scope_closer']; $x++) {
1732 - if (isset($this->tokens[$x]['conditions'][$i]) === false) {
1733 - continue;
1734 - }
1735 + for ( $x = ( $this->tokens[ $i ]['scope_opener'] + 1 ); $x < $this->tokens[ $i ]['scope_closer']; $x ++ ) {
1736 + if ( isset( $this->tokens[ $x ]['conditions'][ $i ] ) === false ) {
1737 + continue;
1738 + }
1735 1739
1736 - $this->tokens[$x]['conditions'][$i] = T_CLOSURE;
1737 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1738 - $type = $this->tokens[$x]['type'];
1739 - echo "\t\t* cleaned $x ($type) *".PHP_EOL;
1740 - }
1741 - }
1742 - }
1743 - }//end if
1740 + $this->tokens[ $x ]['conditions'][ $i ] = T_CLOSURE;
1741 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1742 + $type = $this->tokens[ $x ]['type'];
1743 + echo "\t\t* cleaned $x ($type) *" . PHP_EOL;
1744 + }
1745 + }
1746 + }
1747 + }//end if
1744 1748
1745 - continue;
1746 - } else if ($this->tokens[$i]['code'] === T_CLASS && isset($this->tokens[$i]['scope_opener']) === true) {
1747 - /*
1749 + continue;
1750 + } else if ( $this->tokens[ $i ]['code'] === T_CLASS && isset( $this->tokens[ $i ]['scope_opener'] ) === true ) {
1751 + /*
1748 1752 Detect anonymous classes and assign them a different token.
1749 1753 */
1750 1754
1751 - for ($x = ($i + 1); $x < $numTokens; $x++) {
1752 - if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
1753 - break;
1754 - }
1755 - }
1755 + for ( $x = ( $i + 1 ); $x < $numTokens; $x ++ ) {
1756 + if ( isset( Util\Tokens::$emptyTokens[ $this->tokens[ $x ]['code'] ] ) === false ) {
1757 + break;
1758 + }
1759 + }
1756 1760
1757 - if ($this->tokens[$x]['code'] === T_OPEN_PARENTHESIS
1758 - || $this->tokens[$x]['code'] === T_OPEN_CURLY_BRACKET
1759 - || $this->tokens[$x]['code'] === T_EXTENDS
1760 - || $this->tokens[$x]['code'] === T_IMPLEMENTS
1761 - ) {
1762 - $this->tokens[$i]['code'] = T_ANON_CLASS;
1763 - $this->tokens[$i]['type'] = 'T_ANON_CLASS';
1764 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1765 - $line = $this->tokens[$i]['line'];
1766 - echo "\t* token $i on line $line changed from T_CLASS to T_ANON_CLASS".PHP_EOL;
1767 - }
1761 + if ( $this->tokens[ $x ]['code'] === T_OPEN_PARENTHESIS
1762 + || $this->tokens[ $x ]['code'] === T_OPEN_CURLY_BRACKET
1763 + || $this->tokens[ $x ]['code'] === T_EXTENDS
1764 + || $this->tokens[ $x ]['code'] === T_IMPLEMENTS
1765 + ) {
1766 + $this->tokens[ $i ]['code'] = T_ANON_CLASS;
1767 + $this->tokens[ $i ]['type'] = 'T_ANON_CLASS';
1768 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1769 + $line = $this->tokens[ $i ]['line'];
1770 + echo "\t* token $i on line $line changed from T_CLASS to T_ANON_CLASS" . PHP_EOL;
1771 + }
1768 1772
1769 - if ($this->tokens[$x]['code'] === T_OPEN_PARENTHESIS
1770 - && isset($this->tokens[$x]['parenthesis_closer']) === true
1771 - ) {
1772 - $closer = $this->tokens[$x]['parenthesis_closer'];
1773 + if ( $this->tokens[ $x ]['code'] === T_OPEN_PARENTHESIS
1774 + && isset( $this->tokens[ $x ]['parenthesis_closer'] ) === true
1775 + ) {
1776 + $closer = $this->tokens[ $x ]['parenthesis_closer'];
1773 1777
1774 - $this->tokens[$i]['parenthesis_opener'] = $x;
1775 - $this->tokens[$i]['parenthesis_closer'] = $closer;
1776 - $this->tokens[$i]['parenthesis_owner'] = $i;
1777 - $this->tokens[$x]['parenthesis_owner'] = $i;
1778 - $this->tokens[$closer]['parenthesis_owner'] = $i;
1778 + $this->tokens[ $i ]['parenthesis_opener'] = $x;
1779 + $this->tokens[ $i ]['parenthesis_closer'] = $closer;
1780 + $this->tokens[ $i ]['parenthesis_owner'] = $i;
1781 + $this->tokens[ $x ]['parenthesis_owner'] = $i;
1782 + $this->tokens[ $closer ]['parenthesis_owner'] = $i;
1779 1783
1780 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1781 - $line = $this->tokens[$i]['line'];
1782 - echo "\t\t* added parenthesis keys to T_ANON_CLASS token $i on line $line".PHP_EOL;
1783 - }
1784 - }
1784 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1785 + $line = $this->tokens[ $i ]['line'];
1786 + echo "\t\t* added parenthesis keys to T_ANON_CLASS token $i on line $line" . PHP_EOL;
1787 + }
1788 + }
1785 1789
1786 - for ($x = ($this->tokens[$i]['scope_opener'] + 1); $x < $this->tokens[$i]['scope_closer']; $x++) {
1787 - if (isset($this->tokens[$x]['conditions'][$i]) === false) {
1788 - continue;
1789 - }
1790 + for ( $x = ( $this->tokens[ $i ]['scope_opener'] + 1 ); $x < $this->tokens[ $i ]['scope_closer']; $x ++ ) {
1791 + if ( isset( $this->tokens[ $x ]['conditions'][ $i ] ) === false ) {
1792 + continue;
1793 + }
1790 1794
1791 - $this->tokens[$x]['conditions'][$i] = T_ANON_CLASS;
1792 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1793 - $type = $this->tokens[$x]['type'];
1794 - echo "\t\t* cleaned $x ($type) *".PHP_EOL;
1795 - }
1796 - }
1797 - }//end if
1795 + $this->tokens[ $x ]['conditions'][ $i ] = T_ANON_CLASS;
1796 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1797 + $type = $this->tokens[ $x ]['type'];
1798 + echo "\t\t* cleaned $x ($type) *" . PHP_EOL;
1799 + }
1800 + }
1801 + }//end if
1798 1802
1799 - continue;
1800 - } else if ($this->tokens[$i]['code'] === T_FN && isset($this->tokens[($i + 1)]) === true) {
1801 - // Possible arrow function.
1802 - for ($x = ($i + 1); $x < $numTokens; $x++) {
1803 - if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false
1804 - && $this->tokens[$x]['code'] !== T_BITWISE_AND
1805 - ) {
1806 - // Non-whitespace content.
1807 - break;
1808 - }
1809 - }
1803 + continue;
1804 + } else if ( $this->tokens[ $i ]['code'] === T_FN && isset( $this->tokens[ ( $i + 1 ) ] ) === true ) {
1805 + // Possible arrow function.
1806 + for ( $x = ( $i + 1 ); $x < $numTokens; $x ++ ) {
1807 + if ( isset( Util\Tokens::$emptyTokens[ $this->tokens[ $x ]['code'] ] ) === false
1808 + && $this->tokens[ $x ]['code'] !== T_BITWISE_AND
1809 + ) {
1810 + // Non-whitespace content.
1811 + break;
1812 + }
1813 + }
1810 1814
1811 - if (isset($this->tokens[$x]) === true && $this->tokens[$x]['code'] === T_OPEN_PARENTHESIS) {
1812 - $ignore = Util\Tokens::$emptyTokens;
1813 - $ignore += [
1814 - T_STRING => T_STRING,
1815 - T_ARRAY => T_ARRAY,
1816 - T_COLON => T_COLON,
1817 - T_NS_SEPARATOR => T_NS_SEPARATOR,
1818 - T_NULLABLE => T_NULLABLE,
1819 - T_CALLABLE => T_CALLABLE,
1820 - T_PARENT => T_PARENT,
1821 - T_SELF => T_SELF,
1822 - ];
1815 + if ( isset( $this->tokens[ $x ] ) === true && $this->tokens[ $x ]['code'] === T_OPEN_PARENTHESIS ) {
1816 + $ignore = Util\Tokens::$emptyTokens;
1817 + $ignore += [
1818 + T_STRING => T_STRING,
1819 + T_ARRAY => T_ARRAY,
1820 + T_COLON => T_COLON,
1821 + T_NS_SEPARATOR => T_NS_SEPARATOR,
1822 + T_NULLABLE => T_NULLABLE,
1823 + T_CALLABLE => T_CALLABLE,
1824 + T_PARENT => T_PARENT,
1825 + T_SELF => T_SELF,
1826 + ];
1823 1827
1824 - $closer = $this->tokens[$x]['parenthesis_closer'];
1825 - for ($arrow = ($closer + 1); $arrow < $numTokens; $arrow++) {
1826 - if (isset($ignore[$this->tokens[$arrow]['code']]) === false) {
1827 - break;
1828 - }
1829 - }
1828 + $closer = $this->tokens[ $x ]['parenthesis_closer'];
1829 + for ( $arrow = ( $closer + 1 ); $arrow < $numTokens; $arrow ++ ) {
1830 + if ( isset( $ignore[ $this->tokens[ $arrow ]['code'] ] ) === false ) {
1831 + break;
1832 + }
1833 + }
1830 1834
1831 - if ($this->tokens[$arrow]['code'] === T_DOUBLE_ARROW) {
1832 - $endTokens = [
1833 - T_COLON => true,
1834 - T_COMMA => true,
1835 - T_SEMICOLON => true,
1836 - T_CLOSE_PARENTHESIS => true,
1837 - T_CLOSE_SQUARE_BRACKET => true,
1838 - T_CLOSE_CURLY_BRACKET => true,
1839 - T_CLOSE_SHORT_ARRAY => true,
1840 - T_OPEN_TAG => true,
1841 - T_CLOSE_TAG => true,
1842 - ];
1835 + if ( $this->tokens[ $arrow ]['code'] === T_DOUBLE_ARROW ) {
1836 + $endTokens = [
1837 + T_COLON => true,
1838 + T_COMMA => true,
1839 + T_SEMICOLON => true,
1840 + T_CLOSE_PARENTHESIS => true,
1841 + T_CLOSE_SQUARE_BRACKET => true,
1842 + T_CLOSE_CURLY_BRACKET => true,
1843 + T_CLOSE_SHORT_ARRAY => true,
1844 + T_OPEN_TAG => true,
1845 + T_CLOSE_TAG => true,
1846 + ];
1843 1847
1844 - $inTernary = false;
1848 + $inTernary = false;
1845 1849
1846 - for ($scopeCloser = ($arrow + 1); $scopeCloser < $numTokens; $scopeCloser++) {
1847 - if (isset($endTokens[$this->tokens[$scopeCloser]['code']]) === true) {
1848 - break;
1849 - }
1850 + for ( $scopeCloser = ( $arrow + 1 ); $scopeCloser < $numTokens; $scopeCloser ++ ) {
1851 + if ( isset( $endTokens[ $this->tokens[ $scopeCloser ]['code'] ] ) === true ) {
1852 + break;
1853 + }
1850 1854
1851 - if (isset($this->tokens[$scopeCloser]['scope_closer']) === true
1852 - && $this->tokens[$scopeCloser]['code'] !== T_INLINE_ELSE
1853 - ) {
1854 - // We minus 1 here in case the closer can be shared with us.
1855 - $scopeCloser = ($this->tokens[$scopeCloser]['scope_closer'] - 1);
1856 - continue;
1857 - }
1855 + if ( isset( $this->tokens[ $scopeCloser ]['scope_closer'] ) === true
1856 + && $this->tokens[ $scopeCloser ]['code'] !== T_INLINE_ELSE
1857 + ) {
1858 + // We minus 1 here in case the closer can be shared with us.
1859 + $scopeCloser = ( $this->tokens[ $scopeCloser ]['scope_closer'] - 1 );
1860 + continue;
1861 + }
1858 1862
1859 - if (isset($this->tokens[$scopeCloser]['parenthesis_closer']) === true) {
1860 - $scopeCloser = $this->tokens[$scopeCloser]['parenthesis_closer'];
1861 - continue;
1862 - }
1863 + if ( isset( $this->tokens[ $scopeCloser ]['parenthesis_closer'] ) === true ) {
1864 + $scopeCloser = $this->tokens[ $scopeCloser ]['parenthesis_closer'];
1865 + continue;
1866 + }
1863 1867
1864 - if (isset($this->tokens[$scopeCloser]['bracket_closer']) === true) {
1865 - $scopeCloser = $this->tokens[$scopeCloser]['bracket_closer'];
1866 - continue;
1867 - }
1868 + if ( isset( $this->tokens[ $scopeCloser ]['bracket_closer'] ) === true ) {
1869 + $scopeCloser = $this->tokens[ $scopeCloser ]['bracket_closer'];
1870 + continue;
1871 + }
1868 1872
1869 - if ($this->tokens[$scopeCloser]['code'] === T_INLINE_THEN) {
1870 - $inTernary = true;
1871 - continue;
1872 - }
1873 + if ( $this->tokens[ $scopeCloser ]['code'] === T_INLINE_THEN ) {
1874 + $inTernary = true;
1875 + continue;
1876 + }
1873 1877
1874 - if ($this->tokens[$scopeCloser]['code'] === T_INLINE_ELSE) {
1875 - if ($inTernary === false) {
1876 - break;
1877 - }
1878 + if ( $this->tokens[ $scopeCloser ]['code'] === T_INLINE_ELSE ) {
1879 + if ( $inTernary === false ) {
1880 + break;
1881 + }
1878 1882
1879 - $inTernary = false;
1880 - continue;
1881 - }
1882 - }//end for
1883 + $inTernary = false;
1884 + continue;
1885 + }
1886 + }//end for
1883 1887
1884 - if ($scopeCloser !== $numTokens) {
1885 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1886 - $line = $this->tokens[$i]['line'];
1887 - echo "\t=> token $i on line $line processed as arrow function".PHP_EOL;
1888 - }
1888 + if ( $scopeCloser !== $numTokens ) {
1889 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1890 + $line = $this->tokens[ $i ]['line'];
1891 + echo "\t=> token $i on line $line processed as arrow function" . PHP_EOL;
1892 + }
1889 1893
1890 - $this->tokens[$i]['code'] = T_FN;
1891 - $this->tokens[$i]['type'] = 'T_FN';
1892 - $this->tokens[$i]['scope_condition'] = $i;
1893 - $this->tokens[$i]['scope_opener'] = $arrow;
1894 - $this->tokens[$i]['scope_closer'] = $scopeCloser;
1895 - $this->tokens[$i]['parenthesis_owner'] = $i;
1896 - $this->tokens[$i]['parenthesis_opener'] = $x;
1897 - $this->tokens[$i]['parenthesis_closer'] = $this->tokens[$x]['parenthesis_closer'];
1894 + $this->tokens[ $i ]['code'] = T_FN;
1895 + $this->tokens[ $i ]['type'] = 'T_FN';
1896 + $this->tokens[ $i ]['scope_condition'] = $i;
1897 + $this->tokens[ $i ]['scope_opener'] = $arrow;
1898 + $this->tokens[ $i ]['scope_closer'] = $scopeCloser;
1899 + $this->tokens[ $i ]['parenthesis_owner'] = $i;
1900 + $this->tokens[ $i ]['parenthesis_opener'] = $x;
1901 + $this->tokens[ $i ]['parenthesis_closer'] = $this->tokens[ $x ]['parenthesis_closer'];
1898 1902
1899 - $this->tokens[$arrow]['code'] = T_FN_ARROW;
1900 - $this->tokens[$arrow]['type'] = 'T_FN_ARROW';
1903 + $this->tokens[ $arrow ]['code'] = T_FN_ARROW;
1904 + $this->tokens[ $arrow ]['type'] = 'T_FN_ARROW';
1901 1905
1902 - $this->tokens[$arrow]['scope_condition'] = $i;
1903 - $this->tokens[$arrow]['scope_opener'] = $arrow;
1904 - $this->tokens[$arrow]['scope_closer'] = $scopeCloser;
1905 - $this->tokens[$scopeCloser]['scope_condition'] = $i;
1906 - $this->tokens[$scopeCloser]['scope_opener'] = $arrow;
1907 - $this->tokens[$scopeCloser]['scope_closer'] = $scopeCloser;
1906 + $this->tokens[ $arrow ]['scope_condition'] = $i;
1907 + $this->tokens[ $arrow ]['scope_opener'] = $arrow;
1908 + $this->tokens[ $arrow ]['scope_closer'] = $scopeCloser;
1909 + $this->tokens[ $scopeCloser ]['scope_condition'] = $i;
1910 + $this->tokens[ $scopeCloser ]['scope_opener'] = $arrow;
1911 + $this->tokens[ $scopeCloser ]['scope_closer'] = $scopeCloser;
1908 1912
1909 - $opener = $this->tokens[$i]['parenthesis_opener'];
1910 - $closer = $this->tokens[$i]['parenthesis_closer'];
1911 - $this->tokens[$opener]['parenthesis_owner'] = $i;
1912 - $this->tokens[$closer]['parenthesis_owner'] = $i;
1913 + $opener = $this->tokens[ $i ]['parenthesis_opener'];
1914 + $closer = $this->tokens[ $i ]['parenthesis_closer'];
1915 + $this->tokens[ $opener ]['parenthesis_owner'] = $i;
1916 + $this->tokens[ $closer ]['parenthesis_owner'] = $i;
1913 1917
1914 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1915 - $line = $this->tokens[$arrow]['line'];
1916 - echo "\t\t* token $arrow on line $line changed from T_DOUBLE_ARROW to T_FN_ARROW".PHP_EOL;
1917 - }
1918 - }//end if
1919 - }//end if
1920 - }//end if
1921 - } else if ($this->tokens[$i]['code'] === T_OPEN_SQUARE_BRACKET) {
1922 - if (isset($this->tokens[$i]['bracket_closer']) === false) {
1923 - continue;
1924 - }
1918 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1919 + $line = $this->tokens[ $arrow ]['line'];
1920 + echo "\t\t* token $arrow on line $line changed from T_DOUBLE_ARROW to T_FN_ARROW" . PHP_EOL;
1921 + }
1922 + }//end if
1923 + }//end if
1924 + }//end if
1925 + } else if ( $this->tokens[ $i ]['code'] === T_OPEN_SQUARE_BRACKET ) {
1926 + if ( isset( $this->tokens[ $i ]['bracket_closer'] ) === false ) {
1927 + continue;
1928 + }
1925 1929
1926 - // Unless there is a variable or a bracket before this token,
1927 - // it is the start of an array being defined using the short syntax.
1928 - $isShortArray = false;
1929 - $allowed = [
1930 - T_CLOSE_SQUARE_BRACKET => T_CLOSE_SQUARE_BRACKET,
1931 - T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
1932 - T_CLOSE_PARENTHESIS => T_CLOSE_PARENTHESIS,
1933 - T_VARIABLE => T_VARIABLE,
1934 - T_OBJECT_OPERATOR => T_OBJECT_OPERATOR,
1935 - T_STRING => T_STRING,
1936 - T_CONSTANT_ENCAPSED_STRING => T_CONSTANT_ENCAPSED_STRING,
1937 - ];
1930 + // Unless there is a variable or a bracket before this token,
1931 + // it is the start of an array being defined using the short syntax.
1932 + $isShortArray = false;
1933 + $allowed = [
1934 + T_CLOSE_SQUARE_BRACKET => T_CLOSE_SQUARE_BRACKET,
1935 + T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
1936 + T_CLOSE_PARENTHESIS => T_CLOSE_PARENTHESIS,
1937 + T_VARIABLE => T_VARIABLE,
1938 + T_OBJECT_OPERATOR => T_OBJECT_OPERATOR,
1939 + T_STRING => T_STRING,
1940 + T_CONSTANT_ENCAPSED_STRING => T_CONSTANT_ENCAPSED_STRING,
1941 + ];
1938 1942
1939 - for ($x = ($i - 1); $x >= 0; $x--) {
1940 - // If we hit a scope opener, the statement has ended
1941 - // without finding anything, so it's probably an array
1942 - // using PHP 7.1 short list syntax.
1943 - if (isset($this->tokens[$x]['scope_opener']) === true) {
1944 - $isShortArray = true;
1945 - break;
1946 - }
1943 + for ( $x = ( $i - 1 ); $x >= 0; $x -- ) {
1944 + // If we hit a scope opener, the statement has ended
1945 + // without finding anything, so it's probably an array
1946 + // using PHP 7.1 short list syntax.
1947 + if ( isset( $this->tokens[ $x ]['scope_opener'] ) === true ) {
1948 + $isShortArray = true;
1949 + break;
1950 + }
1947 1951
1948 - if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
1949 - if (isset($allowed[$this->tokens[$x]['code']]) === false) {
1950 - $isShortArray = true;
1951 - }
1952 + if ( isset( Util\Tokens::$emptyTokens[ $this->tokens[ $x ]['code'] ] ) === false ) {
1953 + if ( isset( $allowed[ $this->tokens[ $x ]['code'] ] ) === false ) {
1954 + $isShortArray = true;
1955 + }
1952 1956
1953 - break;
1954 - }
1955 - }
1957 + break;
1958 + }
1959 + }
1956 1960
1957 - if ($isShortArray === true) {
1958 - $this->tokens[$i]['code'] = T_OPEN_SHORT_ARRAY;
1959 - $this->tokens[$i]['type'] = 'T_OPEN_SHORT_ARRAY';
1961 + if ( $isShortArray === true ) {
1962 + $this->tokens[ $i ]['code'] = T_OPEN_SHORT_ARRAY;
1963 + $this->tokens[ $i ]['type'] = 'T_OPEN_SHORT_ARRAY';
1960 1964
1961 - $closer = $this->tokens[$i]['bracket_closer'];
1962 - $this->tokens[$closer]['code'] = T_CLOSE_SHORT_ARRAY;
1963 - $this->tokens[$closer]['type'] = 'T_CLOSE_SHORT_ARRAY';
1964 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1965 - $line = $this->tokens[$i]['line'];
1966 - echo "\t* token $i on line $line changed from T_OPEN_SQUARE_BRACKET to T_OPEN_SHORT_ARRAY".PHP_EOL;
1967 - $line = $this->tokens[$closer]['line'];
1968 - echo "\t* token $closer on line $line changed from T_CLOSE_SQUARE_BRACKET to T_CLOSE_SHORT_ARRAY".PHP_EOL;
1969 - }
1970 - }
1965 + $closer = $this->tokens[ $i ]['bracket_closer'];
1966 + $this->tokens[ $closer ]['code'] = T_CLOSE_SHORT_ARRAY;
1967 + $this->tokens[ $closer ]['type'] = 'T_CLOSE_SHORT_ARRAY';
1968 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1969 + $line = $this->tokens[ $i ]['line'];
1970 + echo "\t* token $i on line $line changed from T_OPEN_SQUARE_BRACKET to T_OPEN_SHORT_ARRAY" . PHP_EOL;
1971 + $line = $this->tokens[ $closer ]['line'];
1972 + echo "\t* token $closer on line $line changed from T_CLOSE_SQUARE_BRACKET to T_CLOSE_SHORT_ARRAY" . PHP_EOL;
1973 + }
1974 + }
1971 1975
1972 - continue;
1973 - } else if ($this->tokens[$i]['code'] === T_STATIC) {
1974 - for ($x = ($i - 1); $x > 0; $x--) {
1975 - if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
1976 - break;
1977 - }
1978 - }
1976 + continue;
1977 + } else if ( $this->tokens[ $i ]['code'] === T_STATIC ) {
1978 + for ( $x = ( $i - 1 ); $x > 0; $x -- ) {
1979 + if ( isset( Util\Tokens::$emptyTokens[ $this->tokens[ $x ]['code'] ] ) === false ) {
1980 + break;
1981 + }
1982 + }
1979 1983
1980 - if ($this->tokens[$x]['code'] === T_INSTANCEOF) {
1981 - $this->tokens[$i]['code'] = T_STRING;
1982 - $this->tokens[$i]['type'] = 'T_STRING';
1984 + if ( $this->tokens[ $x ]['code'] === T_INSTANCEOF ) {
1985 + $this->tokens[ $i ]['code'] = T_STRING;
1986 + $this->tokens[ $i ]['type'] = 'T_STRING';
1983 1987
1984 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
1985 - $line = $this->tokens[$i]['line'];
1986 - echo "\t* token $i on line $line changed from T_STATIC to T_STRING".PHP_EOL;
1987 - }
1988 - }
1988 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
1989 + $line = $this->tokens[ $i ]['line'];
1990 + echo "\t* token $i on line $line changed from T_STATIC to T_STRING" . PHP_EOL;
1991 + }
1992 + }
1989 1993
1990 - continue;
1991 - } else if ($this->tokens[$i]['code'] === T_TRUE
1992 - || $this->tokens[$i]['code'] === T_FALSE
1993 - || $this->tokens[$i]['code'] === T_NULL
1994 - ) {
1995 - for ($x = ($i + 1); $i < $numTokens; $x++) {
1996 - if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
1997 - // Non-whitespace content.
1998 - break;
1999 - }
2000 - }
1994 + continue;
1995 + } else if ( $this->tokens[ $i ]['code'] === T_TRUE
1996 + || $this->tokens[ $i ]['code'] === T_FALSE
1997 + || $this->tokens[ $i ]['code'] === T_NULL
1998 + ) {
1999 + for ( $x = ( $i + 1 ); $i < $numTokens; $x ++ ) {
2000 + if ( isset( Util\Tokens::$emptyTokens[ $this->tokens[ $x ]['code'] ] ) === false ) {
2001 + // Non-whitespace content.
2002 + break;
2003 + }
2004 + }
2001 2005
2002 - $context = [
2003 - T_OBJECT_OPERATOR => true,
2004 - T_NS_SEPARATOR => true,
2005 - T_PAAMAYIM_NEKUDOTAYIM => true,
2006 - ];
2007 - if (isset($context[$this->tokens[$x]['code']]) === true) {
2008 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
2009 - $line = $this->tokens[$i]['line'];
2010 - $type = $this->tokens[$i]['type'];
2011 - echo "\t* token $i on line $line changed from $type to T_STRING".PHP_EOL;
2012 - }
2006 + $context = [
2007 + T_OBJECT_OPERATOR => true,
2008 + T_NS_SEPARATOR => true,
2009 + T_PAAMAYIM_NEKUDOTAYIM => true,
2010 + ];
2011 + if ( isset( $context[ $this->tokens[ $x ]['code'] ] ) === true ) {
2012 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
2013 + $line = $this->tokens[ $i ]['line'];
2014 + $type = $this->tokens[ $i ]['type'];
2015 + echo "\t* token $i on line $line changed from $type to T_STRING" . PHP_EOL;
2016 + }
2013 2017
2014 - $this->tokens[$i]['code'] = T_STRING;
2015 - $this->tokens[$i]['type'] = 'T_STRING';
2016 - }
2017 - } else if ($this->tokens[$i]['code'] === T_CONST) {
2018 - // Context sensitive keywords support.
2019 - for ($x = ($i + 1); $i < $numTokens; $x++) {
2020 - if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
2021 - // Non-whitespace content.
2022 - break;
2023 - }
2024 - }
2018 + $this->tokens[ $i ]['code'] = T_STRING;
2019 + $this->tokens[ $i ]['type'] = 'T_STRING';
2020 + }
2021 + } else if ( $this->tokens[ $i ]['code'] === T_CONST ) {
2022 + // Context sensitive keywords support.
2023 + for ( $x = ( $i + 1 ); $i < $numTokens; $x ++ ) {
2024 + if ( isset( Util\Tokens::$emptyTokens[ $this->tokens[ $x ]['code'] ] ) === false ) {
2025 + // Non-whitespace content.
2026 + break;
2027 + }
2028 + }
2025 2029
2026 - if ($this->tokens[$x]['code'] !== T_STRING) {
2027 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
2028 - $line = $this->tokens[$x]['line'];
2029 - $type = $this->tokens[$x]['type'];
2030 - echo "\t* token $x on line $line changed from $type to T_STRING".PHP_EOL;
2031 - }
2030 + if ( $this->tokens[ $x ]['code'] !== T_STRING ) {
2031 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
2032 + $line = $this->tokens[ $x ]['line'];
2033 + $type = $this->tokens[ $x ]['type'];
2034 + echo "\t* token $x on line $line changed from $type to T_STRING" . PHP_EOL;
2035 + }
2032 2036
2033 - $this->tokens[$x]['code'] = T_STRING;
2034 - $this->tokens[$x]['type'] = 'T_STRING';
2035 - }
2036 - }//end if
2037 + $this->tokens[ $x ]['code'] = T_STRING;
2038 + $this->tokens[ $x ]['type'] = 'T_STRING';
2039 + }
2040 + }//end if
2037 2041
2038 - if (($this->tokens[$i]['code'] !== T_CASE
2039 - && $this->tokens[$i]['code'] !== T_DEFAULT)
2040 - || isset($this->tokens[$i]['scope_opener']) === false
2041 - ) {
2042 - // Only interested in CASE and DEFAULT statements from here on in.
2043 - continue;
2044 - }
2042 + if ( ( $this->tokens[ $i ]['code'] !== T_CASE
2043 + && $this->tokens[ $i ]['code'] !== T_DEFAULT )
2044 + || isset( $this->tokens[ $i ]['scope_opener'] ) === false
2045 + ) {
2046 + // Only interested in CASE and DEFAULT statements from here on in.
2047 + continue;
2048 + }
2045 2049
2046 - $scopeOpener = $this->tokens[$i]['scope_opener'];
2047 - $scopeCloser = $this->tokens[$i]['scope_closer'];
2050 + $scopeOpener = $this->tokens[ $i ]['scope_opener'];
2051 + $scopeCloser = $this->tokens[ $i ]['scope_closer'];
2048 2052
2049 - // If the first char after the opener is a curly brace
2050 - // and that brace has been ignored, it is actually
2051 - // opening this case statement and the opener and closer are
2052 - // probably set incorrectly.
2053 - for ($x = ($scopeOpener + 1); $x < $numTokens; $x++) {
2054 - if (isset(Util\Tokens::$emptyTokens[$this->tokens[$x]['code']]) === false) {
2055 - // Non-whitespace content.
2056 - break;
2057 - }
2058 - }
2053 + // If the first char after the opener is a curly brace
2054 + // and that brace has been ignored, it is actually
2055 + // opening this case statement and the opener and closer are
2056 + // probably set incorrectly.
2057 + for ( $x = ( $scopeOpener + 1 ); $x < $numTokens; $x ++ ) {
2058 + if ( isset( Util\Tokens::$emptyTokens[ $this->tokens[ $x ]['code'] ] ) === false ) {
2059 + // Non-whitespace content.
2060 + break;
2061 + }
2062 + }
2059 2063
2060 - if ($this->tokens[$x]['code'] === T_CASE || $this->tokens[$x]['code'] === T_DEFAULT) {
2061 - // Special case for multiple CASE statements that share the same
2062 - // closer. Because we are going backwards through the file, this next
2063 - // CASE statement is already fixed, so just use its closer and don't
2064 - // worry about fixing anything.
2065 - $newCloser = $this->tokens[$x]['scope_closer'];
2066 - $this->tokens[$i]['scope_closer'] = $newCloser;
2067 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
2068 - $oldType = $this->tokens[$scopeCloser]['type'];
2069 - $newType = $this->tokens[$newCloser]['type'];
2070 - $line = $this->tokens[$i]['line'];
2071 - echo "\t* token $i (T_CASE) on line $line closer changed from $scopeCloser ($oldType) to $newCloser ($newType)".PHP_EOL;
2072 - }
2064 + if ( $this->tokens[ $x ]['code'] === T_CASE || $this->tokens[ $x ]['code'] === T_DEFAULT ) {
2065 + // Special case for multiple CASE statements that share the same
2066 + // closer. Because we are going backwards through the file, this next
2067 + // CASE statement is already fixed, so just use its closer and don't
2068 + // worry about fixing anything.
2069 + $newCloser = $this->tokens[ $x ]['scope_closer'];
2070 + $this->tokens[ $i ]['scope_closer'] = $newCloser;
2071 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
2072 + $oldType = $this->tokens[ $scopeCloser ]['type'];
2073 + $newType = $this->tokens[ $newCloser ]['type'];
2074 + $line = $this->tokens[ $i ]['line'];
2075 + echo "\t* token $i (T_CASE) on line $line closer changed from $scopeCloser ($oldType) to $newCloser ($newType)" . PHP_EOL;
2076 + }
2073 2077
2074 - continue;
2075 - }
2078 + continue;
2079 + }
2076 2080
2077 - if ($this->tokens[$x]['code'] !== T_OPEN_CURLY_BRACKET
2078 - || isset($this->tokens[$x]['scope_condition']) === true
2079 - ) {
2080 - // Not a CASE/DEFAULT with a curly brace opener.
2081 - continue;
2082 - }
2081 + if ( $this->tokens[ $x ]['code'] !== T_OPEN_CURLY_BRACKET
2082 + || isset( $this->tokens[ $x ]['scope_condition'] ) === true
2083 + ) {
2084 + // Not a CASE/DEFAULT with a curly brace opener.
2085 + continue;
2086 + }
2083 2087
2084 - // The closer for this CASE/DEFAULT should be the closing curly brace and
2085 - // not whatever it already is. The opener needs to be the opening curly
2086 - // brace so everything matches up.
2087 - $newCloser = $this->tokens[$x]['bracket_closer'];
2088 - foreach ([$i, $x, $newCloser] as $index) {
2089 - $this->tokens[$index]['scope_condition'] = $i;
2090 - $this->tokens[$index]['scope_opener'] = $x;
2091 - $this->tokens[$index]['scope_closer'] = $newCloser;
2092 - }
2088 + // The closer for this CASE/DEFAULT should be the closing curly brace and
2089 + // not whatever it already is. The opener needs to be the opening curly
2090 + // brace so everything matches up.
2091 + $newCloser = $this->tokens[ $x ]['bracket_closer'];
2092 + foreach ( [ $i, $x, $newCloser ] as $index ) {
2093 + $this->tokens[ $index ]['scope_condition'] = $i;
2094 + $this->tokens[ $index ]['scope_opener'] = $x;
2095 + $this->tokens[ $index ]['scope_closer'] = $newCloser;
2096 + }
2093 2097
2094 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
2095 - $line = $this->tokens[$i]['line'];
2096 - $tokenType = $this->tokens[$i]['type'];
2098 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
2099 + $line = $this->tokens[ $i ]['line'];
2100 + $tokenType = $this->tokens[ $i ]['type'];
2097 2101
2098 - $oldType = $this->tokens[$scopeOpener]['type'];
2099 - $newType = $this->tokens[$x]['type'];
2100 - echo "\t* token $i ($tokenType) on line $line opener changed from $scopeOpener ($oldType) to $x ($newType)".PHP_EOL;
2102 + $oldType = $this->tokens[ $scopeOpener ]['type'];
2103 + $newType = $this->tokens[ $x ]['type'];
2104 + echo "\t* token $i ($tokenType) on line $line opener changed from $scopeOpener ($oldType) to $x ($newType)" . PHP_EOL;
2101 2105
2102 - $oldType = $this->tokens[$scopeCloser]['type'];
2103 - $newType = $this->tokens[$newCloser]['type'];
2104 - echo "\t* token $i ($tokenType) on line $line closer changed from $scopeCloser ($oldType) to $newCloser ($newType)".PHP_EOL;
2105 - }
2106 + $oldType = $this->tokens[ $scopeCloser ]['type'];
2107 + $newType = $this->tokens[ $newCloser ]['type'];
2108 + echo "\t* token $i ($tokenType) on line $line closer changed from $scopeCloser ($oldType) to $newCloser ($newType)" . PHP_EOL;
2109 + }
2106 2110
2107 - if ($this->tokens[$scopeOpener]['scope_condition'] === $i) {
2108 - unset($this->tokens[$scopeOpener]['scope_condition']);
2109 - unset($this->tokens[$scopeOpener]['scope_opener']);
2110 - unset($this->tokens[$scopeOpener]['scope_closer']);
2111 - }
2111 + if ( $this->tokens[ $scopeOpener ]['scope_condition'] === $i ) {
2112 + unset( $this->tokens[ $scopeOpener ]['scope_condition'] );
2113 + unset( $this->tokens[ $scopeOpener ]['scope_opener'] );
2114 + unset( $this->tokens[ $scopeOpener ]['scope_closer'] );
2115 + }
2112 2116
2113 - if ($this->tokens[$scopeCloser]['scope_condition'] === $i) {
2114 - unset($this->tokens[$scopeCloser]['scope_condition']);
2115 - unset($this->tokens[$scopeCloser]['scope_opener']);
2116 - unset($this->tokens[$scopeCloser]['scope_closer']);
2117 - } else {
2118 - // We were using a shared closer. All tokens that were
2119 - // sharing this closer with us, except for the scope condition
2120 - // and it's opener, need to now point to the new closer.
2121 - $condition = $this->tokens[$scopeCloser]['scope_condition'];
2122 - $start = ($this->tokens[$condition]['scope_opener'] + 1);
2123 - for ($y = $start; $y < $scopeCloser; $y++) {
2124 - if (isset($this->tokens[$y]['scope_closer']) === true
2125 - && $this->tokens[$y]['scope_closer'] === $scopeCloser
2126 - ) {
2127 - $this->tokens[$y]['scope_closer'] = $newCloser;
2117 + if ( $this->tokens[ $scopeCloser ]['scope_condition'] === $i ) {
2118 + unset( $this->tokens[ $scopeCloser ]['scope_condition'] );
2119 + unset( $this->tokens[ $scopeCloser ]['scope_opener'] );
2120 + unset( $this->tokens[ $scopeCloser ]['scope_closer'] );
2121 + } else {
2122 + // We were using a shared closer. All tokens that were
2123 + // sharing this closer with us, except for the scope condition
2124 + // and it's opener, need to now point to the new closer.
2125 + $condition = $this->tokens[ $scopeCloser ]['scope_condition'];
2126 + $start = ( $this->tokens[ $condition ]['scope_opener'] + 1 );
2127 + for ( $y = $start; $y < $scopeCloser; $y ++ ) {
2128 + if ( isset( $this->tokens[ $y ]['scope_closer'] ) === true
2129 + && $this->tokens[ $y ]['scope_closer'] === $scopeCloser
2130 + ) {
2131 + $this->tokens[ $y ]['scope_closer'] = $newCloser;
2128 2132
2129 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
2130 - $line = $this->tokens[$y]['line'];
2131 - $tokenType = $this->tokens[$y]['type'];
2132 - $oldType = $this->tokens[$scopeCloser]['type'];
2133 - $newType = $this->tokens[$newCloser]['type'];
2134 - echo "\t\t* token $y ($tokenType) on line $line closer changed from $scopeCloser ($oldType) to $newCloser ($newType)".PHP_EOL;
2135 - }
2136 - }
2137 - }
2138 - }//end if
2133 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
2134 + $line = $this->tokens[ $y ]['line'];
2135 + $tokenType = $this->tokens[ $y ]['type'];
2136 + $oldType = $this->tokens[ $scopeCloser ]['type'];
2137 + $newType = $this->tokens[ $newCloser ]['type'];
2138 + echo "\t\t* token $y ($tokenType) on line $line closer changed from $scopeCloser ($oldType) to $newCloser ($newType)" . PHP_EOL;
2139 + }
2140 + }
2141 + }
2142 + }//end if
2139 2143
2140 - unset($this->tokens[$x]['bracket_opener']);
2141 - unset($this->tokens[$x]['bracket_closer']);
2142 - unset($this->tokens[$newCloser]['bracket_opener']);
2143 - unset($this->tokens[$newCloser]['bracket_closer']);
2144 - $this->tokens[$scopeCloser]['conditions'][] = $i;
2144 + unset( $this->tokens[ $x ]['bracket_opener'] );
2145 + unset( $this->tokens[ $x ]['bracket_closer'] );
2146 + unset( $this->tokens[ $newCloser ]['bracket_opener'] );
2147 + unset( $this->tokens[ $newCloser ]['bracket_closer'] );
2148 + $this->tokens[ $scopeCloser ]['conditions'][] = $i;
2145 2149
2146 - // Now fix up all the tokens that think they are
2147 - // inside the CASE/DEFAULT statement when they are really outside.
2148 - for ($x = $newCloser; $x < $scopeCloser; $x++) {
2149 - foreach ($this->tokens[$x]['conditions'] as $num => $oldCond) {
2150 - if ($oldCond === $this->tokens[$i]['code']) {
2151 - $oldConditions = $this->tokens[$x]['conditions'];
2152 - unset($this->tokens[$x]['conditions'][$num]);
2150 + // Now fix up all the tokens that think they are
2151 + // inside the CASE/DEFAULT statement when they are really outside.
2152 + for ( $x = $newCloser; $x < $scopeCloser; $x ++ ) {
2153 + foreach ( $this->tokens[ $x ]['conditions'] as $num => $oldCond ) {
2154 + if ( $oldCond === $this->tokens[ $i ]['code'] ) {
2155 + $oldConditions = $this->tokens[ $x ]['conditions'];
2156 + unset( $this->tokens[ $x ]['conditions'][ $num ] );
2153 2157
2154 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
2155 - $type = $this->tokens[$x]['type'];
2156 - $oldConds = '';
2157 - foreach ($oldConditions as $condition) {
2158 - $oldConds .= Util\Tokens::tokenName($condition).',';
2159 - }
2158 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
2159 + $type = $this->tokens[ $x ]['type'];
2160 + $oldConds = '';
2161 + foreach ( $oldConditions as $condition ) {
2162 + $oldConds .= Util\Tokens::tokenName( $condition ) . ',';
2163 + }
2160 2164
2161 - $oldConds = rtrim($oldConds, ',');
2165 + $oldConds = rtrim( $oldConds, ',' );
2162 2166
2163 - $newConds = '';
2164 - foreach ($this->tokens[$x]['conditions'] as $condition) {
2165 - $newConds .= Util\Tokens::tokenName($condition).',';
2166 - }
2167 + $newConds = '';
2168 + foreach ( $this->tokens[ $x ]['conditions'] as $condition ) {
2169 + $newConds .= Util\Tokens::tokenName( $condition ) . ',';
2170 + }
2167 2171
2168 - $newConds = rtrim($newConds, ',');
2172 + $newConds = rtrim( $newConds, ',' );
2169 2173
2170 - echo "\t\t* cleaned $x ($type) *".PHP_EOL;
2171 - echo "\t\t\t=> conditions changed from $oldConds to $newConds".PHP_EOL;
2172 - }
2174 + echo "\t\t* cleaned $x ($type) *" . PHP_EOL;
2175 + echo "\t\t\t=> conditions changed from $oldConds to $newConds" . PHP_EOL;
2176 + }
2173 2177
2174 - break;
2175 - }//end if
2176 - }//end foreach
2177 - }//end for
2178 - }//end for
2178 + break;
2179 + }//end if
2180 + }//end foreach
2181 + }//end for
2182 + }//end for
2179 2183
2180 - if (PHP_CODESNIFFER_VERBOSITY > 1) {
2181 - echo "\t*** END ADDITIONAL PHP PROCESSING ***".PHP_EOL;
2182 - }
2184 + if ( PHP_CODESNIFFER_VERBOSITY > 1 ) {
2185 + echo "\t*** END ADDITIONAL PHP PROCESSING ***" . PHP_EOL;
2186 + }
2183 2187
2184 - }//end processAdditional()
2188 + }//end processAdditional()
2185 2189
2186 2190
2187 - /**
2188 - * Takes a token produced from <code>token_get_all()</code> and produces a
2189 - * more uniform token.
2190 - *
2191 - * @param string|array $token The token to convert.
2192 - *
2193 - * @return array The new token.
2194 - */
2195 - public static function standardiseToken($token)
2196 - {
2197 - if (isset($token[1]) === false) {
2198 - if (isset(self::$resolveTokenCache[$token[0]]) === true) {
2199 - return self::$resolveTokenCache[$token[0]];
2200 - }
2201 - } else {
2202 - $cacheKey = null;
2203 - if ($token[0] === T_STRING) {
2204 - $cacheKey = strtolower($token[1]);
2205 - } else if ($token[0] !== T_CURLY_OPEN) {
2206 - $cacheKey = $token[0];
2207 - }
2191 + /**
2192 + * Takes a token produced from <code>token_get_all()</code> and produces a
2193 + * more uniform token.
2194 + *
2195 + * @param string|array $token The token to convert.
2196 + *
2197 + * @return array The new token.
2198 + */
2199 + public static function standardiseToken( $token ) {
2200 + if ( isset( $token[1] ) === false ) {
2201 + if ( isset( self::$resolveTokenCache[ $token[0] ] ) === true ) {
2202 + return self::$resolveTokenCache[ $token[0] ];
2203 + }
2204 + } else {
2205 + $cacheKey = null;
2206 + if ( $token[0] === T_STRING ) {
2207 + $cacheKey = strtolower( $token[1] );
2208 + } else if ( $token[0] !== T_CURLY_OPEN ) {
2209 + $cacheKey = $token[0];
2210 + }
2208 2211
2209 - if ($cacheKey !== null && isset(self::$resolveTokenCache[$cacheKey]) === true) {
2210 - $newToken = self::$resolveTokenCache[$cacheKey];
2211 - $newToken['content'] = $token[1];
2212 - return $newToken;
2213 - }
2214 - }
2212 + if ( $cacheKey !== null && isset( self::$resolveTokenCache[ $cacheKey ] ) === true ) {
2213 + $newToken = self::$resolveTokenCache[ $cacheKey ];
2214 + $newToken['content'] = $token[1];
2215 2215
2216 - if (isset($token[1]) === false) {
2217 - return self::resolveSimpleToken($token[0]);
2218 - }
2216 + return $newToken;
2217 + }
2218 + }
2219 2219
2220 - if ($token[0] === T_STRING) {
2221 - switch ($cacheKey) {
2222 - case 'false':
2223 - $newToken['type'] = 'T_FALSE';
2224 - break;
2225 - case 'true':
2226 - $newToken['type'] = 'T_TRUE';
2227 - break;
2228 - case 'null':
2229 - $newToken['type'] = 'T_NULL';
2230 - break;
2231 - case 'self':
2232 - $newToken['type'] = 'T_SELF';
2233 - break;
2234 - case 'parent':
2235 - $newToken['type'] = 'T_PARENT';
2236 - break;
2237 - default:
2238 - $newToken['type'] = 'T_STRING';
2239 - break;
2240 - }
2220 + if ( isset( $token[1] ) === false ) {
2221 + return self::resolveSimpleToken( $token[0] );
2222 + }
2241 2223
2242 - $newToken['code'] = constant($newToken['type']);
2224 + if ( $token[0] === T_STRING ) {
2225 + switch ( $cacheKey ) {
2226 + case 'false':
2227 + $newToken['type'] = 'T_FALSE';
2228 + break;
2229 + case 'true':
2230 + $newToken['type'] = 'T_TRUE';
2231 + break;
2232 + case 'null':
2233 + $newToken['type'] = 'T_NULL';
2234 + break;
2235 + case 'self':
2236 + $newToken['type'] = 'T_SELF';
2237 + break;
2238 + case 'parent':
2239 + $newToken['type'] = 'T_PARENT';
2240 + break;
2241 + default:
2242 + $newToken['type'] = 'T_STRING';
2243 + break;
2244 + }
2243 2245
2244 - self::$resolveTokenCache[$cacheKey] = $newToken;
2245 - } else if ($token[0] === T_CURLY_OPEN) {
2246 - $newToken = [
2247 - 'code' => T_OPEN_CURLY_BRACKET,
2248 - 'type' => 'T_OPEN_CURLY_BRACKET',
2249 - ];
2250 - } else {
2251 - $newToken = [
2252 - 'code' => $token[0],
2253 - 'type' => Util\Tokens::tokenName($token[0]),
2254 - ];
2246 + $newToken['code'] = constant( $newToken['type'] );
2255 2247
2256 - self::$resolveTokenCache[$token[0]] = $newToken;
2257 - }//end if
2248 + self::$resolveTokenCache[ $cacheKey ] = $newToken;
2249 + } else if ( $token[0] === T_CURLY_OPEN ) {
2250 + $newToken = [
2251 + 'code' => T_OPEN_CURLY_BRACKET,
2252 + 'type' => 'T_OPEN_CURLY_BRACKET',
2253 + ];
2254 + } else {
2255 + $newToken = [
2256 + 'code' => $token[0],
2257 + 'type' => Util\Tokens::tokenName( $token[0] ),
2258 + ];
2258 2259
2259 - $newToken['content'] = $token[1];
2260 - return $newToken;
2260 + self::$resolveTokenCache[ $token[0] ] = $newToken;
2261 + }//end if
2261 2262
2262 - }//end standardiseToken()
2263 + $newToken['content'] = $token[1];
2263 2264
2265 + return $newToken;
2264 2266
2265 - /**
2266 - * Converts simple tokens into a format that conforms to complex tokens
2267 - * produced by token_get_all().
2268 - *
2269 - * Simple tokens are tokens that are not in array form when produced from
2270 - * token_get_all().
2271 - *
2272 - * @param string $token The simple token to convert.
2273 - *
2274 - * @return array The new token in array format.
2275 - */
2276 - public static function resolveSimpleToken($token)
2277 - {
2278 - $newToken = [];
2267 + }//end standardiseToken()
2279 2268
2280 - switch ($token) {
2281 - case '{':
2282 - $newToken['type'] = 'T_OPEN_CURLY_BRACKET';
2283 - break;
2284 - case '}':
2285 - $newToken['type'] = 'T_CLOSE_CURLY_BRACKET';
2286 - break;
2287 - case '[':
2288 - $newToken['type'] = 'T_OPEN_SQUARE_BRACKET';
2289 - break;
2290 - case ']':
2291 - $newToken['type'] = 'T_CLOSE_SQUARE_BRACKET';
2292 - break;
2293 - case '(':
2294 - $newToken['type'] = 'T_OPEN_PARENTHESIS';
2295 - break;
2296 - case ')':
2297 - $newToken['type'] = 'T_CLOSE_PARENTHESIS';
2298 - break;
2299 - case ':':
2300 - $newToken['type'] = 'T_COLON';
2301 - break;
2302 - case '.':
2303 - $newToken['type'] = 'T_STRING_CONCAT';
2304 - break;
2305 - case ';':
2306 - $newToken['type'] = 'T_SEMICOLON';
2307 - break;
2308 - case '=':
2309 - $newToken['type'] = 'T_EQUAL';
2310 - break;
2311 - case '*':
2312 - $newToken['type'] = 'T_MULTIPLY';
2313 - break;
2314 - case '/':
2315 - $newToken['type'] = 'T_DIVIDE';
2316 - break;
2317 - case '+':
2318 - $newToken['type'] = 'T_PLUS';
2319 - break;
2320 - case '-':
2321 - $newToken['type'] = 'T_MINUS';
2322 - break;
2323 - case '%':
2324 - $newToken['type'] = 'T_MODULUS';
2325 - break;
2326 - case '^':
2327 - $newToken['type'] = 'T_BITWISE_XOR';
2328 - break;
2329 - case '&':
2330 - $newToken['type'] = 'T_BITWISE_AND';
2331 - break;
2332 - case '|':
2333 - $newToken['type'] = 'T_BITWISE_OR';
2334 - break;
2335 - case '~':
2336 - $newToken['type'] = 'T_BITWISE_NOT';
2337 - break;
2338 - case '<':
2339 - $newToken['type'] = 'T_LESS_THAN';
2340 - break;
2341 - case '>':
2342 - $newToken['type'] = 'T_GREATER_THAN';
2343 - break;
2344 - case '!':
2345 - $newToken['type'] = 'T_BOOLEAN_NOT';
2346 - break;
2347 - case ',':
2348 - $newToken['type'] = 'T_COMMA';
2349 - break;
2350 - case '@':
2351 - $newToken['type'] = 'T_ASPERAND';
2352 - break;
2353 - case '$':
2354 - $newToken['type'] = 'T_DOLLAR';
2355 - break;
2356 - case '`':
2357 - $newToken['type'] = 'T_BACKTICK';
2358 - break;
2359 - default:
2360 - $newToken['type'] = 'T_NONE';
2361 - break;
2362 - }//end switch
2363 2269
2364 - $newToken['code'] = constant($newToken['type']);
2365 - $newToken['content'] = $token;
2270 + /**
2271 + * Converts simple tokens into a format that conforms to complex tokens
2272 + * produced by token_get_all().
2273 + *
2274 + * Simple tokens are tokens that are not in array form when produced from
2275 + * token_get_all().
2276 + *
2277 + * @param string $token The simple token to convert.
2278 + *
2279 + * @return array The new token in array format.
2280 + */
2281 + public static function resolveSimpleToken( $token ) {
2282 + $newToken = [];
2366 2283
2367 - self::$resolveTokenCache[$token] = $newToken;
2368 - return $newToken;
2284 + switch ( $token ) {
2285 + case '{':
2286 + $newToken['type'] = 'T_OPEN_CURLY_BRACKET';
2287 + break;
2288 + case '}':
2289 + $newToken['type'] = 'T_CLOSE_CURLY_BRACKET';
2290 + break;
2291 + case '[':
2292 + $newToken['type'] = 'T_OPEN_SQUARE_BRACKET';
2293 + break;
2294 + case ']':
2295 + $newToken['type'] = 'T_CLOSE_SQUARE_BRACKET';
2296 + break;
2297 + case '(':
2298 + $newToken['type'] = 'T_OPEN_PARENTHESIS';
2299 + break;
2300 + case ')':
2301 + $newToken['type'] = 'T_CLOSE_PARENTHESIS';
2302 + break;
2303 + case ':':
2304 + $newToken['type'] = 'T_COLON';
2305 + break;
2306 + case '.':
2307 + $newToken['type'] = 'T_STRING_CONCAT';
2308 + break;
2309 + case ';':
2310 + $newToken['type'] = 'T_SEMICOLON';
2311 + break;
2312 + case '=':
2313 + $newToken['type'] = 'T_EQUAL';
2314 + break;
2315 + case '*':
2316 + $newToken['type'] = 'T_MULTIPLY';
2317 + break;
2318 + case '/':
2319 + $newToken['type'] = 'T_DIVIDE';
2320 + break;
2321 + case '+':
2322 + $newToken['type'] = 'T_PLUS';
2323 + break;
2324 + case '-':
2325 + $newToken['type'] = 'T_MINUS';
2326 + break;
2327 + case '%':
2328 + $newToken['type'] = 'T_MODULUS';
2329 + break;
2330 + case '^':
2331 + $newToken['type'] = 'T_BITWISE_XOR';
2332 + break;
2333 + case '&':
2334 + $newToken['type'] = 'T_BITWISE_AND';
2335 + break;
2336 + case '|':
2337 + $newToken['type'] = 'T_BITWISE_OR';
2338 + break;
2339 + case '~':
2340 + $newToken['type'] = 'T_BITWISE_NOT';
2341 + break;
2342 + case '<':
2343 + $newToken['type'] = 'T_LESS_THAN';
2344 + break;
2345 + case '>':
2346 + $newToken['type'] = 'T_GREATER_THAN';
2347 + break;
2348 + case '!':
2349 + $newToken['type'] = 'T_BOOLEAN_NOT';
2350 + break;
2351 + case ',':
2352 + $newToken['type'] = 'T_COMMA';
2353 + break;
2354 + case '@':
2355 + $newToken['type'] = 'T_ASPERAND';
2356 + break;
2357 + case '$':
2358 + $newToken['type'] = 'T_DOLLAR';
2359 + break;
2360 + case '`':
2361 + $newToken['type'] = 'T_BACKTICK';
2362 + break;
2363 + default:
2364 + $newToken['type'] = 'T_NONE';
2365 + break;
2366 + }//end switch
2369 2367
2370 - }//end resolveSimpleToken()
2368 + $newToken['code'] = constant( $newToken['type'] );
2369 + $newToken['content'] = $token;
2370 +
2371 + self::$resolveTokenCache[ $token ] = $newToken;
2372 +
2373 + return $newToken;
2374 +
2375 + }//end resolveSimpleToken()
2371 2376
2372 2377
2373 2378 }//end class