Completed
Pull Request — develop (#1492)
by Zack
08:22
created
PHPCompatibility/Sniffs/FunctionUse/NewFunctionParametersSniff.php 1 patch
Indentation   +1032 added lines, -1032 removed lines patch added patch discarded remove patch
@@ -22,1065 +22,1065 @@
 block discarded – undo
22 22
  */
23 23
 class NewFunctionParametersSniff extends AbstractNewFeatureSniff
24 24
 {
25
-    /**
26
-     * A list of new functions, not present in older versions.
27
-     *
28
-     * The array lists : version number with false (not present) or true (present).
29
-     * The index is the location of the parameter in the parameter list, starting at 0 !
30
-     * If's sufficient to list the first version where the function appears.
31
-     *
32
-     * @var array
33
-     */
34
-    protected $newFunctionParameters = array(
35
-        'array_filter' => array(
36
-            2 => array(
37
-                'name' => 'flag',
38
-                '5.5'  => false,
39
-                '5.6'  => true,
40
-            ),
41
-        ),
42
-        'array_slice' => array(
43
-            1 => array(
44
-                'name'  => 'preserve_keys',
45
-                '5.0.1' => false,
46
-                '5.0.2' => true,
47
-            ),
48
-        ),
49
-        'array_unique' => array(
50
-            1 => array(
51
-                'name'  => 'sort_flags',
52
-                '5.2.8' => false,
53
-                '5.2.9' => true,
54
-            ),
55
-        ),
56
-        'assert' => array(
57
-            1 => array(
58
-                'name'  => 'description',
59
-                '5.4.7' => false,
60
-                '5.4.8' => true,
61
-            ),
62
-        ),
63
-        'base64_decode' => array(
64
-            1 => array(
65
-                'name' => 'strict',
66
-                '5.1'  => false,
67
-                '5.2'  => true,
68
-            ),
69
-        ),
70
-        'bcmod' => array(
71
-            2 => array(
72
-                'name' => 'scale',
73
-                '7.1'  => false,
74
-                '7.2'  => true,
75
-            ),
76
-        ),
77
-        'class_implements' => array(
78
-            1 => array(
79
-                'name' => 'autoload',
80
-                '5.0'  => false,
81
-                '5.1'  => true,
82
-            ),
83
-        ),
84
-        'class_parents' => array(
85
-            1 => array(
86
-                'name' => 'autoload',
87
-                '5.0'  => false,
88
-                '5.1'  => true,
89
-            ),
90
-        ),
91
-        'clearstatcache' => array(
92
-            0 => array(
93
-                'name' => 'clear_realpath_cache',
94
-                '5.2'  => false,
95
-                '5.3'  => true,
96
-            ),
97
-            1 => array(
98
-                'name' => 'filename',
99
-                '5.2'  => false,
100
-                '5.3'  => true,
101
-            ),
102
-        ),
103
-        'copy' => array(
104
-            2 => array(
105
-                'name' => 'context',
106
-                '5.2'  => false,
107
-                '5.3'  => true,
108
-            ),
109
-        ),
110
-        'curl_multi_info_read' => array(
111
-            1 => array(
112
-                'name' => 'msgs_in_queue',
113
-                '5.1'  => false,
114
-                '5.2'  => true,
115
-            ),
116
-        ),
117
-        'debug_backtrace' => array(
118
-            0 => array(
119
-                'name'  => 'options',
120
-                '5.2.4' => false,
121
-                '5.2.5' => true,
122
-            ),
123
-            1 => array(
124
-                'name' => 'limit',
125
-                '5.3'  => false,
126
-                '5.4'  => true,
127
-            ),
128
-        ),
129
-        'debug_print_backtrace' => array(
130
-            0 => array(
131
-                'name'  => 'options',
132
-                '5.3.5' => false,
133
-                '5.3.6' => true,
134
-            ),
135
-            1 => array(
136
-                'name' => 'limit',
137
-                '5.3'  => false,
138
-                '5.4'  => true,
139
-            ),
140
-        ),
141
-        'dirname' => array(
142
-            1 => array(
143
-                'name' => 'levels',
144
-                '5.6'  => false,
145
-                '7.0'  => true,
146
-            ),
147
-        ),
148
-        'dns_get_record' => array(
149
-            4 => array(
150
-                'name' => 'raw',
151
-                '5.3'  => false,
152
-                '5.4'  => true,
153
-            ),
154
-        ),
155
-        'fgetcsv' => array(
156
-            4 => array(
157
-                'name' => 'escape',
158
-                '5.2'  => false,
159
-                '5.3'  => true,
160
-            ),
161
-        ),
162
-        'fputcsv' => array(
163
-            4 => array(
164
-                'name'  => 'escape_char',
165
-                '5.5.3' => false,
166
-                '5.5.4' => true,
167
-            ),
168
-        ),
169
-        'file_get_contents' => array(
170
-            3 => array(
171
-                'name' => 'offset',
172
-                '5.0'  => false,
173
-                '5.1'  => true,
174
-            ),
175
-            4 => array(
176
-                'name' => 'maxlen',
177
-                '5.0'  => false,
178
-                '5.1'  => true,
179
-            ),
180
-        ),
181
-        'filter_input_array' => array(
182
-            2 => array(
183
-                'name' => 'add_empty',
184
-                '5.3'  => false,
185
-                '5.4'  => true,
186
-            ),
187
-        ),
188
-        'filter_var_array' => array(
189
-            2 => array(
190
-                'name' => 'add_empty',
191
-                '5.3'  => false,
192
-                '5.4'  => true,
193
-            ),
194
-        ),
195
-        'getenv' => array(
196
-            1 => array(
197
-                'name'   => 'local_only',
198
-                '5.5.37' => false,
199
-                '5.5.38' => true, // Also introduced in PHP 5.6.24 and 7.0.9.
200
-            ),
201
-        ),
202
-        'getopt' => array(
203
-            2 => array(
204
-                'name' => 'optind',
205
-                '7.0'  => false,
206
-                '7.1'  => true,
207
-            ),
208
-        ),
209
-        'gettimeofday' => array(
210
-            0 => array(
211
-                'name' => 'return_float',
212
-                '5.0'  => false,
213
-                '5.1'  => true,
214
-            ),
215
-        ),
216
-        'get_defined_functions' => array(
217
-            0 => array(
218
-                'name'   => 'exclude_disabled',
219
-                '7.0.14' => false,
220
-                '7.0.15' => true,
221
-            ),
222
-        ),
223
-        'get_headers' => array(
224
-            2 => array(
225
-                'name' => 'context',
226
-                '7.0'  => false,
227
-                '7.1'  => true,
228
-            ),
229
-        ),
230
-        'get_html_translation_table' => array(
231
-            2 => array(
232
-                'name'  => 'encoding',
233
-                '5.3.3' => false,
234
-                '5.3.4' => true,
235
-            ),
236
-        ),
237
-        'get_loaded_extensions' => array(
238
-            0 => array(
239
-                'name'  => 'zend_extensions',
240
-                '5.2.3' => false,
241
-                '5.2.4' => true,
242
-            ),
243
-        ),
244
-        'gzcompress' => array(
245
-            2 => array(
246
-                'name' => 'encoding',
247
-                '5.3'  => false,
248
-                '5.4'  => true,
249
-            ),
250
-        ),
251
-        'gzdeflate' => array(
252
-            2 => array(
253
-                'name' => 'encoding',
254
-                '5.3'  => false,
255
-                '5.4'  => true,
256
-            ),
257
-        ),
258
-        'htmlentities' => array(
259
-            3 => array(
260
-                'name'  => 'double_encode',
261
-                '5.2.2' => false,
262
-                '5.2.3' => true,
263
-            ),
264
-        ),
265
-        'htmlspecialchars' => array(
266
-            3 => array(
267
-                'name'  => 'double_encode',
268
-                '5.2.2' => false,
269
-                '5.2.3' => true,
270
-            ),
271
-        ),
272
-        'http_build_query' => array(
273
-            2 => array(
274
-                'name'  => 'arg_separator',
275
-                '5.1.1' => false,
276
-                '5.1.2' => true,
277
-            ),
278
-            3 => array(
279
-                'name' => 'enc_type',
280
-                '5.3'  => false,
281
-                '5.4'  => true,
282
-            ),
283
-        ),
284
-        'idn_to_ascii' => array(
285
-            2 => array(
286
-                'name' => 'variant',
287
-                '5.3'  => false,
288
-                '5.4'  => true,
289
-            ),
290
-            3 => array(
291
-                'name' => 'idna_info',
292
-                '5.3'  => false,
293
-                '5.4'  => true,
294
-            ),
295
-        ),
296
-        'idn_to_utf8' => array(
297
-            2 => array(
298
-                'name' => 'variant',
299
-                '5.3'  => false,
300
-                '5.4'  => true,
301
-            ),
302
-            3 => array(
303
-                'name' => 'idna_info',
304
-                '5.3'  => false,
305
-                '5.4'  => true,
306
-            ),
307
-        ),
308
-        'imagecolorset' => array(
309
-            5 => array(
310
-                'name' => 'alpha',
311
-                '5.3'  => false,
312
-                '5.4'  => true,
313
-            ),
314
-        ),
315
-        'imagepng' => array(
316
-            2 => array(
317
-                'name'  => 'quality',
318
-                '5.1.1' => false,
319
-                '5.1.2' => true,
320
-            ),
321
-            3 => array(
322
-                'name'  => 'filters',
323
-                '5.1.2' => false,
324
-                '5.1.3' => true,
325
-            ),
326
-        ),
327
-        'imagerotate' => array(
328
-            3 => array(
329
-                'name' => 'ignore_transparent',
330
-                '5.0'  => false,
331
-                '5.1'  => true,
332
-            ),
333
-        ),
334
-        'imap_open' => array(
335
-            4 => array(
336
-                'name' => 'n_retries',
337
-                '5.1'  => false,
338
-                '5.2'  => true,
339
-            ),
340
-            5 => array(
341
-                'name'  => 'params',
342
-                '5.3.1' => false,
343
-                '5.3.2' => true,
344
-            ),
345
-        ),
346
-        'imap_reopen' => array(
347
-            3 => array(
348
-                'name' => 'n_retries',
349
-                '5.1'  => false,
350
-                '5.2'  => true,
351
-            ),
352
-        ),
353
-        'ini_get_all' => array(
354
-            1 => array(
355
-                'name' => 'details',
356
-                '5.2'  => false,
357
-                '5.3'  => true,
358
-            ),
359
-        ),
360
-        'is_a' => array(
361
-            2 => array(
362
-                'name'  => 'allow_string',
363
-                '5.3.8' => false,
364
-                '5.3.9' => true,
365
-            ),
366
-        ),
367
-        'is_subclass_of' => array(
368
-            2 => array(
369
-                'name'  => 'allow_string',
370
-                '5.3.8' => false,
371
-                '5.3.9' => true,
372
-            ),
373
-        ),
374
-        'iterator_to_array' => array(
375
-            1 => array(
376
-                'name'  => 'use_keys',
377
-                '5.2.0' => false,
378
-                '5.2.1' => true,
379
-            ),
380
-        ),
381
-        'json_decode' => array(
382
-            2 => array(
383
-                'name' => 'depth',
384
-                '5.2'  => false,
385
-                '5.3'  => true,
386
-            ),
387
-            3 => array(
388
-                'name' => 'options',
389
-                '5.3'  => false,
390
-                '5.4'  => true,
391
-            ),
392
-        ),
393
-        'json_encode' => array(
394
-            1 => array(
395
-                'name' => 'options',
396
-                '5.2'  => false,
397
-                '5.3'  => true,
398
-            ),
399
-            2 => array(
400
-                'name' => 'depth',
401
-                '5.4'  => false,
402
-                '5.5'  => true,
403
-            ),
404
-        ),
405
-        'ldap_add' => array(
406
-            3 => array(
407
-                'name' => 'serverctrls',
408
-                '7.2'  => false,
409
-                '7.3'  => true,
410
-            ),
411
-        ),
412
-        'ldap_compare' => array(
413
-            4 => array(
414
-                'name' => 'serverctrls',
415
-                '7.2'  => false,
416
-                '7.3'  => true,
417
-            ),
418
-        ),
419
-        'ldap_delete' => array(
420
-            2 => array(
421
-                'name' => 'serverctrls',
422
-                '7.2'  => false,
423
-                '7.3'  => true,
424
-            ),
425
-        ),
426
-        'ldap_list' => array(
427
-            8 => array(
428
-                'name' => 'serverctrls',
429
-                '7.2'  => false,
430
-                '7.3'  => true,
431
-            ),
432
-        ),
433
-        'ldap_mod_add' => array(
434
-            3 => array(
435
-                'name' => 'serverctrls',
436
-                '7.2'  => false,
437
-                '7.3'  => true,
438
-            ),
439
-        ),
440
-        'ldap_mod_del' => array(
441
-            3 => array(
442
-                'name' => 'serverctrls',
443
-                '7.2'  => false,
444
-                '7.3'  => true,
445
-            ),
446
-        ),
447
-        'ldap_mod_replace' => array(
448
-            3 => array(
449
-                'name' => 'serverctrls',
450
-                '7.2'  => false,
451
-                '7.3'  => true,
452
-            ),
453
-        ),
454
-        'ldap_modify_batch' => array(
455
-            3 => array(
456
-                'name' => 'serverctrls',
457
-                '7.2'  => false,
458
-                '7.3'  => true,
459
-            ),
460
-        ),
461
-        'ldap_parse_result' => array(
462
-            6 => array(
463
-                'name' => 'serverctrls',
464
-                '7.2'  => false,
465
-                '7.3'  => true,
466
-            ),
467
-        ),
468
-        'ldap_read' => array(
469
-            8 => array(
470
-                'name' => 'serverctrls',
471
-                '7.2'  => false,
472
-                '7.3'  => true,
473
-            ),
474
-        ),
475
-        'ldap_rename' => array(
476
-            5 => array(
477
-                'name' => 'serverctrls',
478
-                '7.2'  => false,
479
-                '7.3'  => true,
480
-            ),
481
-        ),
482
-        'ldap_search' => array(
483
-            8 => array(
484
-                'name' => 'serverctrls',
485
-                '7.2'  => false,
486
-                '7.3'  => true,
487
-            ),
488
-        ),
489
-        'memory_get_peak_usage' => array(
490
-            0 => array(
491
-                'name' => 'real_usage',
492
-                '5.1'  => false,
493
-                '5.2'  => true,
494
-            ),
495
-        ),
496
-        'memory_get_usage' => array(
497
-            0 => array(
498
-                'name' => 'real_usage',
499
-                '5.1'  => false,
500
-                '5.2'  => true,
501
-            ),
502
-        ),
503
-        'mb_encode_numericentity' => array(
504
-            3 => array(
505
-                'name' => 'is_hex',
506
-                '5.3'  => false,
507
-                '5.4'  => true,
508
-            ),
509
-        ),
510
-        'mb_strrpos' => array(
511
-            /*
25
+	/**
26
+	 * A list of new functions, not present in older versions.
27
+	 *
28
+	 * The array lists : version number with false (not present) or true (present).
29
+	 * The index is the location of the parameter in the parameter list, starting at 0 !
30
+	 * If's sufficient to list the first version where the function appears.
31
+	 *
32
+	 * @var array
33
+	 */
34
+	protected $newFunctionParameters = array(
35
+		'array_filter' => array(
36
+			2 => array(
37
+				'name' => 'flag',
38
+				'5.5'  => false,
39
+				'5.6'  => true,
40
+			),
41
+		),
42
+		'array_slice' => array(
43
+			1 => array(
44
+				'name'  => 'preserve_keys',
45
+				'5.0.1' => false,
46
+				'5.0.2' => true,
47
+			),
48
+		),
49
+		'array_unique' => array(
50
+			1 => array(
51
+				'name'  => 'sort_flags',
52
+				'5.2.8' => false,
53
+				'5.2.9' => true,
54
+			),
55
+		),
56
+		'assert' => array(
57
+			1 => array(
58
+				'name'  => 'description',
59
+				'5.4.7' => false,
60
+				'5.4.8' => true,
61
+			),
62
+		),
63
+		'base64_decode' => array(
64
+			1 => array(
65
+				'name' => 'strict',
66
+				'5.1'  => false,
67
+				'5.2'  => true,
68
+			),
69
+		),
70
+		'bcmod' => array(
71
+			2 => array(
72
+				'name' => 'scale',
73
+				'7.1'  => false,
74
+				'7.2'  => true,
75
+			),
76
+		),
77
+		'class_implements' => array(
78
+			1 => array(
79
+				'name' => 'autoload',
80
+				'5.0'  => false,
81
+				'5.1'  => true,
82
+			),
83
+		),
84
+		'class_parents' => array(
85
+			1 => array(
86
+				'name' => 'autoload',
87
+				'5.0'  => false,
88
+				'5.1'  => true,
89
+			),
90
+		),
91
+		'clearstatcache' => array(
92
+			0 => array(
93
+				'name' => 'clear_realpath_cache',
94
+				'5.2'  => false,
95
+				'5.3'  => true,
96
+			),
97
+			1 => array(
98
+				'name' => 'filename',
99
+				'5.2'  => false,
100
+				'5.3'  => true,
101
+			),
102
+		),
103
+		'copy' => array(
104
+			2 => array(
105
+				'name' => 'context',
106
+				'5.2'  => false,
107
+				'5.3'  => true,
108
+			),
109
+		),
110
+		'curl_multi_info_read' => array(
111
+			1 => array(
112
+				'name' => 'msgs_in_queue',
113
+				'5.1'  => false,
114
+				'5.2'  => true,
115
+			),
116
+		),
117
+		'debug_backtrace' => array(
118
+			0 => array(
119
+				'name'  => 'options',
120
+				'5.2.4' => false,
121
+				'5.2.5' => true,
122
+			),
123
+			1 => array(
124
+				'name' => 'limit',
125
+				'5.3'  => false,
126
+				'5.4'  => true,
127
+			),
128
+		),
129
+		'debug_print_backtrace' => array(
130
+			0 => array(
131
+				'name'  => 'options',
132
+				'5.3.5' => false,
133
+				'5.3.6' => true,
134
+			),
135
+			1 => array(
136
+				'name' => 'limit',
137
+				'5.3'  => false,
138
+				'5.4'  => true,
139
+			),
140
+		),
141
+		'dirname' => array(
142
+			1 => array(
143
+				'name' => 'levels',
144
+				'5.6'  => false,
145
+				'7.0'  => true,
146
+			),
147
+		),
148
+		'dns_get_record' => array(
149
+			4 => array(
150
+				'name' => 'raw',
151
+				'5.3'  => false,
152
+				'5.4'  => true,
153
+			),
154
+		),
155
+		'fgetcsv' => array(
156
+			4 => array(
157
+				'name' => 'escape',
158
+				'5.2'  => false,
159
+				'5.3'  => true,
160
+			),
161
+		),
162
+		'fputcsv' => array(
163
+			4 => array(
164
+				'name'  => 'escape_char',
165
+				'5.5.3' => false,
166
+				'5.5.4' => true,
167
+			),
168
+		),
169
+		'file_get_contents' => array(
170
+			3 => array(
171
+				'name' => 'offset',
172
+				'5.0'  => false,
173
+				'5.1'  => true,
174
+			),
175
+			4 => array(
176
+				'name' => 'maxlen',
177
+				'5.0'  => false,
178
+				'5.1'  => true,
179
+			),
180
+		),
181
+		'filter_input_array' => array(
182
+			2 => array(
183
+				'name' => 'add_empty',
184
+				'5.3'  => false,
185
+				'5.4'  => true,
186
+			),
187
+		),
188
+		'filter_var_array' => array(
189
+			2 => array(
190
+				'name' => 'add_empty',
191
+				'5.3'  => false,
192
+				'5.4'  => true,
193
+			),
194
+		),
195
+		'getenv' => array(
196
+			1 => array(
197
+				'name'   => 'local_only',
198
+				'5.5.37' => false,
199
+				'5.5.38' => true, // Also introduced in PHP 5.6.24 and 7.0.9.
200
+			),
201
+		),
202
+		'getopt' => array(
203
+			2 => array(
204
+				'name' => 'optind',
205
+				'7.0'  => false,
206
+				'7.1'  => true,
207
+			),
208
+		),
209
+		'gettimeofday' => array(
210
+			0 => array(
211
+				'name' => 'return_float',
212
+				'5.0'  => false,
213
+				'5.1'  => true,
214
+			),
215
+		),
216
+		'get_defined_functions' => array(
217
+			0 => array(
218
+				'name'   => 'exclude_disabled',
219
+				'7.0.14' => false,
220
+				'7.0.15' => true,
221
+			),
222
+		),
223
+		'get_headers' => array(
224
+			2 => array(
225
+				'name' => 'context',
226
+				'7.0'  => false,
227
+				'7.1'  => true,
228
+			),
229
+		),
230
+		'get_html_translation_table' => array(
231
+			2 => array(
232
+				'name'  => 'encoding',
233
+				'5.3.3' => false,
234
+				'5.3.4' => true,
235
+			),
236
+		),
237
+		'get_loaded_extensions' => array(
238
+			0 => array(
239
+				'name'  => 'zend_extensions',
240
+				'5.2.3' => false,
241
+				'5.2.4' => true,
242
+			),
243
+		),
244
+		'gzcompress' => array(
245
+			2 => array(
246
+				'name' => 'encoding',
247
+				'5.3'  => false,
248
+				'5.4'  => true,
249
+			),
250
+		),
251
+		'gzdeflate' => array(
252
+			2 => array(
253
+				'name' => 'encoding',
254
+				'5.3'  => false,
255
+				'5.4'  => true,
256
+			),
257
+		),
258
+		'htmlentities' => array(
259
+			3 => array(
260
+				'name'  => 'double_encode',
261
+				'5.2.2' => false,
262
+				'5.2.3' => true,
263
+			),
264
+		),
265
+		'htmlspecialchars' => array(
266
+			3 => array(
267
+				'name'  => 'double_encode',
268
+				'5.2.2' => false,
269
+				'5.2.3' => true,
270
+			),
271
+		),
272
+		'http_build_query' => array(
273
+			2 => array(
274
+				'name'  => 'arg_separator',
275
+				'5.1.1' => false,
276
+				'5.1.2' => true,
277
+			),
278
+			3 => array(
279
+				'name' => 'enc_type',
280
+				'5.3'  => false,
281
+				'5.4'  => true,
282
+			),
283
+		),
284
+		'idn_to_ascii' => array(
285
+			2 => array(
286
+				'name' => 'variant',
287
+				'5.3'  => false,
288
+				'5.4'  => true,
289
+			),
290
+			3 => array(
291
+				'name' => 'idna_info',
292
+				'5.3'  => false,
293
+				'5.4'  => true,
294
+			),
295
+		),
296
+		'idn_to_utf8' => array(
297
+			2 => array(
298
+				'name' => 'variant',
299
+				'5.3'  => false,
300
+				'5.4'  => true,
301
+			),
302
+			3 => array(
303
+				'name' => 'idna_info',
304
+				'5.3'  => false,
305
+				'5.4'  => true,
306
+			),
307
+		),
308
+		'imagecolorset' => array(
309
+			5 => array(
310
+				'name' => 'alpha',
311
+				'5.3'  => false,
312
+				'5.4'  => true,
313
+			),
314
+		),
315
+		'imagepng' => array(
316
+			2 => array(
317
+				'name'  => 'quality',
318
+				'5.1.1' => false,
319
+				'5.1.2' => true,
320
+			),
321
+			3 => array(
322
+				'name'  => 'filters',
323
+				'5.1.2' => false,
324
+				'5.1.3' => true,
325
+			),
326
+		),
327
+		'imagerotate' => array(
328
+			3 => array(
329
+				'name' => 'ignore_transparent',
330
+				'5.0'  => false,
331
+				'5.1'  => true,
332
+			),
333
+		),
334
+		'imap_open' => array(
335
+			4 => array(
336
+				'name' => 'n_retries',
337
+				'5.1'  => false,
338
+				'5.2'  => true,
339
+			),
340
+			5 => array(
341
+				'name'  => 'params',
342
+				'5.3.1' => false,
343
+				'5.3.2' => true,
344
+			),
345
+		),
346
+		'imap_reopen' => array(
347
+			3 => array(
348
+				'name' => 'n_retries',
349
+				'5.1'  => false,
350
+				'5.2'  => true,
351
+			),
352
+		),
353
+		'ini_get_all' => array(
354
+			1 => array(
355
+				'name' => 'details',
356
+				'5.2'  => false,
357
+				'5.3'  => true,
358
+			),
359
+		),
360
+		'is_a' => array(
361
+			2 => array(
362
+				'name'  => 'allow_string',
363
+				'5.3.8' => false,
364
+				'5.3.9' => true,
365
+			),
366
+		),
367
+		'is_subclass_of' => array(
368
+			2 => array(
369
+				'name'  => 'allow_string',
370
+				'5.3.8' => false,
371
+				'5.3.9' => true,
372
+			),
373
+		),
374
+		'iterator_to_array' => array(
375
+			1 => array(
376
+				'name'  => 'use_keys',
377
+				'5.2.0' => false,
378
+				'5.2.1' => true,
379
+			),
380
+		),
381
+		'json_decode' => array(
382
+			2 => array(
383
+				'name' => 'depth',
384
+				'5.2'  => false,
385
+				'5.3'  => true,
386
+			),
387
+			3 => array(
388
+				'name' => 'options',
389
+				'5.3'  => false,
390
+				'5.4'  => true,
391
+			),
392
+		),
393
+		'json_encode' => array(
394
+			1 => array(
395
+				'name' => 'options',
396
+				'5.2'  => false,
397
+				'5.3'  => true,
398
+			),
399
+			2 => array(
400
+				'name' => 'depth',
401
+				'5.4'  => false,
402
+				'5.5'  => true,
403
+			),
404
+		),
405
+		'ldap_add' => array(
406
+			3 => array(
407
+				'name' => 'serverctrls',
408
+				'7.2'  => false,
409
+				'7.3'  => true,
410
+			),
411
+		),
412
+		'ldap_compare' => array(
413
+			4 => array(
414
+				'name' => 'serverctrls',
415
+				'7.2'  => false,
416
+				'7.3'  => true,
417
+			),
418
+		),
419
+		'ldap_delete' => array(
420
+			2 => array(
421
+				'name' => 'serverctrls',
422
+				'7.2'  => false,
423
+				'7.3'  => true,
424
+			),
425
+		),
426
+		'ldap_list' => array(
427
+			8 => array(
428
+				'name' => 'serverctrls',
429
+				'7.2'  => false,
430
+				'7.3'  => true,
431
+			),
432
+		),
433
+		'ldap_mod_add' => array(
434
+			3 => array(
435
+				'name' => 'serverctrls',
436
+				'7.2'  => false,
437
+				'7.3'  => true,
438
+			),
439
+		),
440
+		'ldap_mod_del' => array(
441
+			3 => array(
442
+				'name' => 'serverctrls',
443
+				'7.2'  => false,
444
+				'7.3'  => true,
445
+			),
446
+		),
447
+		'ldap_mod_replace' => array(
448
+			3 => array(
449
+				'name' => 'serverctrls',
450
+				'7.2'  => false,
451
+				'7.3'  => true,
452
+			),
453
+		),
454
+		'ldap_modify_batch' => array(
455
+			3 => array(
456
+				'name' => 'serverctrls',
457
+				'7.2'  => false,
458
+				'7.3'  => true,
459
+			),
460
+		),
461
+		'ldap_parse_result' => array(
462
+			6 => array(
463
+				'name' => 'serverctrls',
464
+				'7.2'  => false,
465
+				'7.3'  => true,
466
+			),
467
+		),
468
+		'ldap_read' => array(
469
+			8 => array(
470
+				'name' => 'serverctrls',
471
+				'7.2'  => false,
472
+				'7.3'  => true,
473
+			),
474
+		),
475
+		'ldap_rename' => array(
476
+			5 => array(
477
+				'name' => 'serverctrls',
478
+				'7.2'  => false,
479
+				'7.3'  => true,
480
+			),
481
+		),
482
+		'ldap_search' => array(
483
+			8 => array(
484
+				'name' => 'serverctrls',
485
+				'7.2'  => false,
486
+				'7.3'  => true,
487
+			),
488
+		),
489
+		'memory_get_peak_usage' => array(
490
+			0 => array(
491
+				'name' => 'real_usage',
492
+				'5.1'  => false,
493
+				'5.2'  => true,
494
+			),
495
+		),
496
+		'memory_get_usage' => array(
497
+			0 => array(
498
+				'name' => 'real_usage',
499
+				'5.1'  => false,
500
+				'5.2'  => true,
501
+			),
502
+		),
503
+		'mb_encode_numericentity' => array(
504
+			3 => array(
505
+				'name' => 'is_hex',
506
+				'5.3'  => false,
507
+				'5.4'  => true,
508
+			),
509
+		),
510
+		'mb_strrpos' => array(
511
+			/*
512 512
              * Note: the actual position is 2, but the original 3rd
513 513
              * parameter 'encoding' was moved to the 4th position.
514 514
              * So the only way to detect if offset is used is when
515 515
              * both offset and encoding are set.
516 516
              */
517
-            3 => array(
518
-                'name' => 'offset',
519
-                '5.1'  => false,
520
-                '5.2'  => true,
521
-            ),
522
-        ),
523
-        'mssql_connect' => array(
524
-            3 => array(
525
-                'name' => 'new_link',
526
-                '5.0'  => false,
527
-                '5.1'  => true,
528
-            ),
529
-        ),
530
-        'mysqli_commit' => array(
531
-            1 => array(
532
-                'name' => 'flags',
533
-                '5.4'  => false,
534
-                '5.5'  => true,
535
-            ),
536
-            2 => array(
537
-                'name' => 'name',
538
-                '5.4'  => false,
539
-                '5.5'  => true,
540
-            ),
541
-        ),
542
-        'mysqli_rollback' => array(
543
-            1 => array(
544
-                'name' => 'flags',
545
-                '5.4'  => false,
546
-                '5.5'  => true,
547
-            ),
548
-            2 => array(
549
-                'name' => 'name',
550
-                '5.4'  => false,
551
-                '5.5'  => true,
552
-            ),
553
-        ),
554
-        'nl2br' => array(
555
-            1 => array(
556
-                'name' => 'is_xhtml',
557
-                '5.2'  => false,
558
-                '5.3'  => true,
559
-            ),
560
-        ),
561
-        'openssl_decrypt' => array(
562
-            4 => array(
563
-                'name'  => 'iv',
564
-                '5.3.2' => false,
565
-                '5.3.3' => true,
566
-            ),
567
-            5 => array(
568
-                'name' => 'tag',
569
-                '7.0'  => false,
570
-                '7.1'  => true,
571
-            ),
572
-            6 => array(
573
-                'name' => 'aad',
574
-                '7.0'  => false,
575
-                '7.1'  => true,
576
-            ),
577
-        ),
578
-        'openssl_encrypt' => array(
579
-            4 => array(
580
-                'name'  => 'iv',
581
-                '5.3.2' => false,
582
-                '5.3.3' => true,
583
-            ),
584
-            5 => array(
585
-                'name' => 'tag',
586
-                '7.0'  => false,
587
-                '7.1'  => true,
588
-            ),
589
-            6 => array(
590
-                'name' => 'aad',
591
-                '7.0'  => false,
592
-                '7.1'  => true,
593
-            ),
594
-            7 => array(
595
-                'name' => 'tag_length',
596
-                '7.0'  => false,
597
-                '7.1'  => true,
598
-            ),
599
-        ),
600
-        'openssl_open' => array(
601
-            4 => array(
602
-                'name' => 'method',
603
-                '5.2'  => false,
604
-                '5.3'  => true,
605
-            ),
606
-            5 => array(
607
-                'name' => 'iv',
608
-                '5.6'  => false,
609
-                '7.0'  => true,
610
-            ),
611
-        ),
612
-        'openssl_pkcs7_verify' => array(
613
-            5 => array(
614
-                'name' => 'content',
615
-                '5.0'  => false,
616
-                '5.1'  => true,
617
-            ),
618
-            6 => array(
619
-                'name' => 'p7bfilename',
620
-                '7.1'  => false,
621
-                '7.2'  => true,
622
-            ),
623
-        ),
624
-        'openssl_seal' => array(
625
-            4 => array(
626
-                'name' => 'method',
627
-                '5.2'  => false,
628
-                '5.3'  => true,
629
-            ),
630
-            5 => array(
631
-                'name' => 'iv',
632
-                '5.6'  => false,
633
-                '7.0'  => true,
634
-            ),
635
-        ),
636
-        'openssl_verify' => array(
637
-            3 => array(
638
-                'name' => 'signature_alg',
639
-                '5.1'  => false,
640
-                '5.2'  => true,
641
-            ),
642
-        ),
643
-        'parse_ini_file' => array(
644
-            2 => array(
645
-                'name' => 'scanner_mode',
646
-                '5.2'  => false,
647
-                '5.3'  => true,
648
-            ),
649
-        ),
650
-        'parse_url' => array(
651
-            1 => array(
652
-                'name'  => 'component',
653
-                '5.1.1' => false,
654
-                '5.1.2' => true,
655
-            ),
656
-        ),
657
-        'pg_fetch_all' => array(
658
-            1 => array(
659
-                'name' => 'result_type',
660
-                '7.0'  => false,
661
-                '7.1'  => true,
662
-            ),
663
-        ),
664
-        'pg_last_notice' => array(
665
-            1 => array(
666
-                'name' => 'option',
667
-                '7.0'  => false,
668
-                '7.1'  => true,
669
-            ),
670
-        ),
671
-        'pg_lo_create' => array(
672
-            1 => array(
673
-                'name' => 'object_id',
674
-                '5.2'  => false,
675
-                '5.3'  => true,
676
-            ),
677
-        ),
678
-        'pg_lo_import' => array(
679
-            2 => array(
680
-                'name' => 'object_id',
681
-                '5.2'  => false,
682
-                '5.3'  => true,
683
-            ),
684
-        ),
685
-        'pg_select' => array(
686
-            4 => array(
687
-                'name' => 'result_type',
688
-                '7.0'  => false,
689
-                '7.1'  => true,
690
-            ),
691
-        ),
692
-        'php_uname' => array(
693
-            0 => array(
694
-                'name' => 'mode',
695
-                '4.2'  => false,
696
-                '4.3'  => true,
697
-            ),
698
-        ),
699
-        'preg_replace' => array(
700
-            4 => array(
701
-                'name' => 'count',
702
-                '5.0'  => false,
703
-                '5.1'  => true,
704
-            ),
705
-        ),
706
-        'preg_replace_callback' => array(
707
-            4 => array(
708
-                'name' => 'count',
709
-                '5.0'  => false,
710
-                '5.1'  => true,
711
-            ),
712
-            5 => array(
713
-                'name' => 'flags',
714
-                '7.3'  => false,
715
-                '7.4'  => true,
716
-            ),
717
-        ),
718
-        'preg_replace_callback_array' => array(
719
-            4 => array(
720
-                'name' => 'flags',
721
-                '7.3'  => false,
722
-                '7.4'  => true,
723
-            ),
724
-        ),
725
-        'round' => array(
726
-            2 => array(
727
-                'name' => 'mode',
728
-                '5.2'  => false,
729
-                '5.3'  => true,
730
-            ),
731
-        ),
732
-        'sem_acquire' => array(
733
-            1 => array(
734
-                'name'  => 'nowait',
735
-                '5.6'   => false,
736
-                '5.6.1' => true,
737
-            ),
738
-        ),
739
-        'session_regenerate_id' => array(
740
-            0 => array(
741
-                'name' => 'delete_old_session',
742
-                '5.0'  => false,
743
-                '5.1'  => true,
744
-            ),
745
-        ),
746
-        'session_set_cookie_params' => array(
747
-            4 => array(
748
-                'name' => 'httponly',
749
-                '5.1'  => false,
750
-                '5.2'  => true,
751
-            ),
752
-        ),
753
-        'session_set_save_handler' => array(
754
-            6 => array(
755
-                'name'  => 'create_sid',
756
-                '5.5.0' => false,
757
-                '5.5.1' => true,
758
-            ),
759
-            7 => array(
760
-                'name' => 'validate_sid',
761
-                '5.6'  => false,
762
-                '7.0'  => true,
763
-            ),
764
-            8 => array(
765
-                'name' => 'update_timestamp',
766
-                '5.6'  => false,
767
-                '7.0'  => true,
768
-            ),
769
-        ),
770
-        'session_start' => array(
771
-            0 => array(
772
-                'name' => 'options',
773
-                '5.6'  => false,
774
-                '7.0'  => true,
775
-            ),
776
-        ),
777
-        'setcookie' => array(
778
-            6 => array(
779
-                'name' => 'httponly',
780
-                '5.1'  => false,
781
-                '5.2'  => true,
782
-            ),
783
-        ),
784
-        'setrawcookie' => array(
785
-            6 => array(
786
-                'name' => 'httponly',
787
-                '5.1'  => false,
788
-                '5.2'  => true,
789
-            ),
790
-        ),
791
-        'simplexml_load_file' => array(
792
-            4 => array(
793
-                'name' => 'is_prefix',
794
-                '5.1'  => false,
795
-                '5.2'  => true,
796
-            ),
797
-        ),
798
-        'simplexml_load_string' => array(
799
-            4 => array(
800
-                'name' => 'is_prefix',
801
-                '5.1'  => false,
802
-                '5.2'  => true,
803
-            ),
804
-        ),
805
-        'spl_autoload_register' => array(
806
-            2 => array(
807
-                'name' => 'prepend',
808
-                '5.2'  => false,
809
-                '5.3'  => true,
810
-            ),
811
-        ),
812
-        'stream_context_create' => array(
813
-            1 => array(
814
-                'name' => 'params',
815
-                '5.2'  => false,
816
-                '5.3'  => true,
817
-            ),
818
-        ),
819
-        'stream_copy_to_stream' => array(
820
-            3 => array(
821
-                'name' => 'offset',
822
-                '5.0'  => false,
823
-                '5.1'  => true,
824
-            ),
825
-        ),
826
-        'stream_get_contents' => array(
827
-            2 => array(
828
-                'name' => 'offset',
829
-                '5.0'  => false,
830
-                '5.1'  => true,
831
-            ),
832
-        ),
833
-        'stream_wrapper_register' => array(
834
-            2 => array(
835
-                'name'  => 'flags',
836
-                '5.2.3' => false,
837
-                '5.2.4' => true,
838
-            ),
839
-        ),
840
-        'stristr' => array(
841
-            2 => array(
842
-                'name' => 'before_needle',
843
-                '5.2'  => false,
844
-                '5.3'  => true,
845
-            ),
846
-        ),
847
-        'strstr' => array(
848
-            2 => array(
849
-                'name' => 'before_needle',
850
-                '5.2'  => false,
851
-                '5.3'  => true,
852
-            ),
853
-        ),
854
-        'str_word_count' => array(
855
-            2 => array(
856
-                'name' => 'charlist',
857
-                '5.0'  => false,
858
-                '5.1'  => true,
859
-            ),
860
-        ),
861
-        'substr_count' => array(
862
-            2 => array(
863
-                'name' => 'offset',
864
-                '5.0'  => false,
865
-                '5.1'  => true,
866
-            ),
867
-            3 => array(
868
-                'name' => 'length',
869
-                '5.0'  => false,
870
-                '5.1'  => true,
871
-            ),
872
-        ),
873
-        'sybase_connect' => array(
874
-            5 => array(
875
-                'name' => 'new',
876
-                '5.2'  => false,
877
-                '5.3'  => true,
878
-            ),
879
-        ),
880
-        'timezone_transitions_get' => array(
881
-            1 => array(
882
-                'name' => 'timestamp_begin',
883
-                '5.2'  => false,
884
-                '5.3'  => true,
885
-            ),
886
-            2 => array(
887
-                'name' => 'timestamp_end',
888
-                '5.2'  => false,
889
-                '5.3'  => true,
890
-            ),
891
-        ),
892
-        'timezone_identifiers_list' => array(
893
-            0 => array(
894
-                'name' => 'what',
895
-                '5.2'  => false,
896
-                '5.3'  => true,
897
-            ),
898
-            1 => array(
899
-                'name' => 'country',
900
-                '5.2'  => false,
901
-                '5.3'  => true,
902
-            ),
903
-        ),
904
-        'token_get_all' => array(
905
-            1 => array(
906
-                'name' => 'flags',
907
-                '5.6'  => false,
908
-                '7.0'  => true,
909
-            ),
910
-        ),
911
-        'ucwords' => array(
912
-            1 => array(
913
-                'name'   => 'delimiters',
914
-                '5.4.31' => false,
915
-                '5.5.15' => false,
916
-                '5.4.32' => true,
917
-                '5.5.16' => true,
918
-            ),
919
-        ),
920
-        'unpack' => array(
921
-            2 => array(
922
-                'name' => 'offset',
923
-                '7.0'  => false,
924
-                '7.1'  => true,
925
-            ),
926
-        ),
927
-        'unserialize' => array(
928
-            1 => array(
929
-                'name' => 'options',
930
-                '5.6'  => false,
931
-                '7.0'  => true,
932
-            ),
933
-        ),
934
-    );
517
+			3 => array(
518
+				'name' => 'offset',
519
+				'5.1'  => false,
520
+				'5.2'  => true,
521
+			),
522
+		),
523
+		'mssql_connect' => array(
524
+			3 => array(
525
+				'name' => 'new_link',
526
+				'5.0'  => false,
527
+				'5.1'  => true,
528
+			),
529
+		),
530
+		'mysqli_commit' => array(
531
+			1 => array(
532
+				'name' => 'flags',
533
+				'5.4'  => false,
534
+				'5.5'  => true,
535
+			),
536
+			2 => array(
537
+				'name' => 'name',
538
+				'5.4'  => false,
539
+				'5.5'  => true,
540
+			),
541
+		),
542
+		'mysqli_rollback' => array(
543
+			1 => array(
544
+				'name' => 'flags',
545
+				'5.4'  => false,
546
+				'5.5'  => true,
547
+			),
548
+			2 => array(
549
+				'name' => 'name',
550
+				'5.4'  => false,
551
+				'5.5'  => true,
552
+			),
553
+		),
554
+		'nl2br' => array(
555
+			1 => array(
556
+				'name' => 'is_xhtml',
557
+				'5.2'  => false,
558
+				'5.3'  => true,
559
+			),
560
+		),
561
+		'openssl_decrypt' => array(
562
+			4 => array(
563
+				'name'  => 'iv',
564
+				'5.3.2' => false,
565
+				'5.3.3' => true,
566
+			),
567
+			5 => array(
568
+				'name' => 'tag',
569
+				'7.0'  => false,
570
+				'7.1'  => true,
571
+			),
572
+			6 => array(
573
+				'name' => 'aad',
574
+				'7.0'  => false,
575
+				'7.1'  => true,
576
+			),
577
+		),
578
+		'openssl_encrypt' => array(
579
+			4 => array(
580
+				'name'  => 'iv',
581
+				'5.3.2' => false,
582
+				'5.3.3' => true,
583
+			),
584
+			5 => array(
585
+				'name' => 'tag',
586
+				'7.0'  => false,
587
+				'7.1'  => true,
588
+			),
589
+			6 => array(
590
+				'name' => 'aad',
591
+				'7.0'  => false,
592
+				'7.1'  => true,
593
+			),
594
+			7 => array(
595
+				'name' => 'tag_length',
596
+				'7.0'  => false,
597
+				'7.1'  => true,
598
+			),
599
+		),
600
+		'openssl_open' => array(
601
+			4 => array(
602
+				'name' => 'method',
603
+				'5.2'  => false,
604
+				'5.3'  => true,
605
+			),
606
+			5 => array(
607
+				'name' => 'iv',
608
+				'5.6'  => false,
609
+				'7.0'  => true,
610
+			),
611
+		),
612
+		'openssl_pkcs7_verify' => array(
613
+			5 => array(
614
+				'name' => 'content',
615
+				'5.0'  => false,
616
+				'5.1'  => true,
617
+			),
618
+			6 => array(
619
+				'name' => 'p7bfilename',
620
+				'7.1'  => false,
621
+				'7.2'  => true,
622
+			),
623
+		),
624
+		'openssl_seal' => array(
625
+			4 => array(
626
+				'name' => 'method',
627
+				'5.2'  => false,
628
+				'5.3'  => true,
629
+			),
630
+			5 => array(
631
+				'name' => 'iv',
632
+				'5.6'  => false,
633
+				'7.0'  => true,
634
+			),
635
+		),
636
+		'openssl_verify' => array(
637
+			3 => array(
638
+				'name' => 'signature_alg',
639
+				'5.1'  => false,
640
+				'5.2'  => true,
641
+			),
642
+		),
643
+		'parse_ini_file' => array(
644
+			2 => array(
645
+				'name' => 'scanner_mode',
646
+				'5.2'  => false,
647
+				'5.3'  => true,
648
+			),
649
+		),
650
+		'parse_url' => array(
651
+			1 => array(
652
+				'name'  => 'component',
653
+				'5.1.1' => false,
654
+				'5.1.2' => true,
655
+			),
656
+		),
657
+		'pg_fetch_all' => array(
658
+			1 => array(
659
+				'name' => 'result_type',
660
+				'7.0'  => false,
661
+				'7.1'  => true,
662
+			),
663
+		),
664
+		'pg_last_notice' => array(
665
+			1 => array(
666
+				'name' => 'option',
667
+				'7.0'  => false,
668
+				'7.1'  => true,
669
+			),
670
+		),
671
+		'pg_lo_create' => array(
672
+			1 => array(
673
+				'name' => 'object_id',
674
+				'5.2'  => false,
675
+				'5.3'  => true,
676
+			),
677
+		),
678
+		'pg_lo_import' => array(
679
+			2 => array(
680
+				'name' => 'object_id',
681
+				'5.2'  => false,
682
+				'5.3'  => true,
683
+			),
684
+		),
685
+		'pg_select' => array(
686
+			4 => array(
687
+				'name' => 'result_type',
688
+				'7.0'  => false,
689
+				'7.1'  => true,
690
+			),
691
+		),
692
+		'php_uname' => array(
693
+			0 => array(
694
+				'name' => 'mode',
695
+				'4.2'  => false,
696
+				'4.3'  => true,
697
+			),
698
+		),
699
+		'preg_replace' => array(
700
+			4 => array(
701
+				'name' => 'count',
702
+				'5.0'  => false,
703
+				'5.1'  => true,
704
+			),
705
+		),
706
+		'preg_replace_callback' => array(
707
+			4 => array(
708
+				'name' => 'count',
709
+				'5.0'  => false,
710
+				'5.1'  => true,
711
+			),
712
+			5 => array(
713
+				'name' => 'flags',
714
+				'7.3'  => false,
715
+				'7.4'  => true,
716
+			),
717
+		),
718
+		'preg_replace_callback_array' => array(
719
+			4 => array(
720
+				'name' => 'flags',
721
+				'7.3'  => false,
722
+				'7.4'  => true,
723
+			),
724
+		),
725
+		'round' => array(
726
+			2 => array(
727
+				'name' => 'mode',
728
+				'5.2'  => false,
729
+				'5.3'  => true,
730
+			),
731
+		),
732
+		'sem_acquire' => array(
733
+			1 => array(
734
+				'name'  => 'nowait',
735
+				'5.6'   => false,
736
+				'5.6.1' => true,
737
+			),
738
+		),
739
+		'session_regenerate_id' => array(
740
+			0 => array(
741
+				'name' => 'delete_old_session',
742
+				'5.0'  => false,
743
+				'5.1'  => true,
744
+			),
745
+		),
746
+		'session_set_cookie_params' => array(
747
+			4 => array(
748
+				'name' => 'httponly',
749
+				'5.1'  => false,
750
+				'5.2'  => true,
751
+			),
752
+		),
753
+		'session_set_save_handler' => array(
754
+			6 => array(
755
+				'name'  => 'create_sid',
756
+				'5.5.0' => false,
757
+				'5.5.1' => true,
758
+			),
759
+			7 => array(
760
+				'name' => 'validate_sid',
761
+				'5.6'  => false,
762
+				'7.0'  => true,
763
+			),
764
+			8 => array(
765
+				'name' => 'update_timestamp',
766
+				'5.6'  => false,
767
+				'7.0'  => true,
768
+			),
769
+		),
770
+		'session_start' => array(
771
+			0 => array(
772
+				'name' => 'options',
773
+				'5.6'  => false,
774
+				'7.0'  => true,
775
+			),
776
+		),
777
+		'setcookie' => array(
778
+			6 => array(
779
+				'name' => 'httponly',
780
+				'5.1'  => false,
781
+				'5.2'  => true,
782
+			),
783
+		),
784
+		'setrawcookie' => array(
785
+			6 => array(
786
+				'name' => 'httponly',
787
+				'5.1'  => false,
788
+				'5.2'  => true,
789
+			),
790
+		),
791
+		'simplexml_load_file' => array(
792
+			4 => array(
793
+				'name' => 'is_prefix',
794
+				'5.1'  => false,
795
+				'5.2'  => true,
796
+			),
797
+		),
798
+		'simplexml_load_string' => array(
799
+			4 => array(
800
+				'name' => 'is_prefix',
801
+				'5.1'  => false,
802
+				'5.2'  => true,
803
+			),
804
+		),
805
+		'spl_autoload_register' => array(
806
+			2 => array(
807
+				'name' => 'prepend',
808
+				'5.2'  => false,
809
+				'5.3'  => true,
810
+			),
811
+		),
812
+		'stream_context_create' => array(
813
+			1 => array(
814
+				'name' => 'params',
815
+				'5.2'  => false,
816
+				'5.3'  => true,
817
+			),
818
+		),
819
+		'stream_copy_to_stream' => array(
820
+			3 => array(
821
+				'name' => 'offset',
822
+				'5.0'  => false,
823
+				'5.1'  => true,
824
+			),
825
+		),
826
+		'stream_get_contents' => array(
827
+			2 => array(
828
+				'name' => 'offset',
829
+				'5.0'  => false,
830
+				'5.1'  => true,
831
+			),
832
+		),
833
+		'stream_wrapper_register' => array(
834
+			2 => array(
835
+				'name'  => 'flags',
836
+				'5.2.3' => false,
837
+				'5.2.4' => true,
838
+			),
839
+		),
840
+		'stristr' => array(
841
+			2 => array(
842
+				'name' => 'before_needle',
843
+				'5.2'  => false,
844
+				'5.3'  => true,
845
+			),
846
+		),
847
+		'strstr' => array(
848
+			2 => array(
849
+				'name' => 'before_needle',
850
+				'5.2'  => false,
851
+				'5.3'  => true,
852
+			),
853
+		),
854
+		'str_word_count' => array(
855
+			2 => array(
856
+				'name' => 'charlist',
857
+				'5.0'  => false,
858
+				'5.1'  => true,
859
+			),
860
+		),
861
+		'substr_count' => array(
862
+			2 => array(
863
+				'name' => 'offset',
864
+				'5.0'  => false,
865
+				'5.1'  => true,
866
+			),
867
+			3 => array(
868
+				'name' => 'length',
869
+				'5.0'  => false,
870
+				'5.1'  => true,
871
+			),
872
+		),
873
+		'sybase_connect' => array(
874
+			5 => array(
875
+				'name' => 'new',
876
+				'5.2'  => false,
877
+				'5.3'  => true,
878
+			),
879
+		),
880
+		'timezone_transitions_get' => array(
881
+			1 => array(
882
+				'name' => 'timestamp_begin',
883
+				'5.2'  => false,
884
+				'5.3'  => true,
885
+			),
886
+			2 => array(
887
+				'name' => 'timestamp_end',
888
+				'5.2'  => false,
889
+				'5.3'  => true,
890
+			),
891
+		),
892
+		'timezone_identifiers_list' => array(
893
+			0 => array(
894
+				'name' => 'what',
895
+				'5.2'  => false,
896
+				'5.3'  => true,
897
+			),
898
+			1 => array(
899
+				'name' => 'country',
900
+				'5.2'  => false,
901
+				'5.3'  => true,
902
+			),
903
+		),
904
+		'token_get_all' => array(
905
+			1 => array(
906
+				'name' => 'flags',
907
+				'5.6'  => false,
908
+				'7.0'  => true,
909
+			),
910
+		),
911
+		'ucwords' => array(
912
+			1 => array(
913
+				'name'   => 'delimiters',
914
+				'5.4.31' => false,
915
+				'5.5.15' => false,
916
+				'5.4.32' => true,
917
+				'5.5.16' => true,
918
+			),
919
+		),
920
+		'unpack' => array(
921
+			2 => array(
922
+				'name' => 'offset',
923
+				'7.0'  => false,
924
+				'7.1'  => true,
925
+			),
926
+		),
927
+		'unserialize' => array(
928
+			1 => array(
929
+				'name' => 'options',
930
+				'5.6'  => false,
931
+				'7.0'  => true,
932
+			),
933
+		),
934
+	);
935 935
 
936 936
 
937
-    /**
938
-     * Returns an array of tokens this test wants to listen for.
939
-     *
940
-     * @return array
941
-     */
942
-    public function register()
943
-    {
944
-        // Handle case-insensitivity of function names.
945
-        $this->newFunctionParameters = $this->arrayKeysToLowercase($this->newFunctionParameters);
937
+	/**
938
+	 * Returns an array of tokens this test wants to listen for.
939
+	 *
940
+	 * @return array
941
+	 */
942
+	public function register()
943
+	{
944
+		// Handle case-insensitivity of function names.
945
+		$this->newFunctionParameters = $this->arrayKeysToLowercase($this->newFunctionParameters);
946 946
 
947
-        return array(\T_STRING);
948
-    }
947
+		return array(\T_STRING);
948
+	}
949 949
 
950
-    /**
951
-     * Processes this test, when one of its tokens is encountered.
952
-     *
953
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
954
-     * @param int                   $stackPtr  The position of the current token in
955
-     *                                         the stack passed in $tokens.
956
-     *
957
-     * @return void
958
-     */
959
-    public function process(File $phpcsFile, $stackPtr)
960
-    {
961
-        $tokens = $phpcsFile->getTokens();
950
+	/**
951
+	 * Processes this test, when one of its tokens is encountered.
952
+	 *
953
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
954
+	 * @param int                   $stackPtr  The position of the current token in
955
+	 *                                         the stack passed in $tokens.
956
+	 *
957
+	 * @return void
958
+	 */
959
+	public function process(File $phpcsFile, $stackPtr)
960
+	{
961
+		$tokens = $phpcsFile->getTokens();
962 962
 
963
-        $ignore = array(
964
-            \T_DOUBLE_COLON    => true,
965
-            \T_OBJECT_OPERATOR => true,
966
-            \T_FUNCTION        => true,
967
-            \T_CONST           => true,
968
-        );
963
+		$ignore = array(
964
+			\T_DOUBLE_COLON    => true,
965
+			\T_OBJECT_OPERATOR => true,
966
+			\T_FUNCTION        => true,
967
+			\T_CONST           => true,
968
+		);
969 969
 
970
-        $prevToken = $phpcsFile->findPrevious(\T_WHITESPACE, ($stackPtr - 1), null, true);
971
-        if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
972
-            // Not a call to a PHP function.
973
-            return;
974
-        }
970
+		$prevToken = $phpcsFile->findPrevious(\T_WHITESPACE, ($stackPtr - 1), null, true);
971
+		if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
972
+			// Not a call to a PHP function.
973
+			return;
974
+		}
975 975
 
976
-        $function   = $tokens[$stackPtr]['content'];
977
-        $functionLc = strtolower($function);
976
+		$function   = $tokens[$stackPtr]['content'];
977
+		$functionLc = strtolower($function);
978 978
 
979
-        if (isset($this->newFunctionParameters[$functionLc]) === false) {
980
-            return;
981
-        }
979
+		if (isset($this->newFunctionParameters[$functionLc]) === false) {
980
+			return;
981
+		}
982 982
 
983
-        $parameterCount = $this->getFunctionCallParameterCount($phpcsFile, $stackPtr);
984
-        if ($parameterCount === 0) {
985
-            return;
986
-        }
983
+		$parameterCount = $this->getFunctionCallParameterCount($phpcsFile, $stackPtr);
984
+		if ($parameterCount === 0) {
985
+			return;
986
+		}
987 987
 
988
-        // If the parameter count returned > 0, we know there will be valid open parenthesis.
989
-        $openParenthesis      = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
990
-        $parameterOffsetFound = $parameterCount - 1;
988
+		// If the parameter count returned > 0, we know there will be valid open parenthesis.
989
+		$openParenthesis      = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
990
+		$parameterOffsetFound = $parameterCount - 1;
991 991
 
992
-        foreach ($this->newFunctionParameters[$functionLc] as $offset => $parameterDetails) {
993
-            if ($offset <= $parameterOffsetFound) {
994
-                $itemInfo = array(
995
-                    'name'   => $function,
996
-                    'nameLc' => $functionLc,
997
-                    'offset' => $offset,
998
-                );
999
-                $this->handleFeature($phpcsFile, $openParenthesis, $itemInfo);
1000
-            }
1001
-        }
1002
-    }
992
+		foreach ($this->newFunctionParameters[$functionLc] as $offset => $parameterDetails) {
993
+			if ($offset <= $parameterOffsetFound) {
994
+				$itemInfo = array(
995
+					'name'   => $function,
996
+					'nameLc' => $functionLc,
997
+					'offset' => $offset,
998
+				);
999
+				$this->handleFeature($phpcsFile, $openParenthesis, $itemInfo);
1000
+			}
1001
+		}
1002
+	}
1003 1003
 
1004 1004
 
1005
-    /**
1006
-     * Get the relevant sub-array for a specific item from a multi-dimensional array.
1007
-     *
1008
-     * @param array $itemInfo Base information about the item.
1009
-     *
1010
-     * @return array Version and other information about the item.
1011
-     */
1012
-    public function getItemArray(array $itemInfo)
1013
-    {
1014
-        return $this->newFunctionParameters[$itemInfo['nameLc']][$itemInfo['offset']];
1015
-    }
1005
+	/**
1006
+	 * Get the relevant sub-array for a specific item from a multi-dimensional array.
1007
+	 *
1008
+	 * @param array $itemInfo Base information about the item.
1009
+	 *
1010
+	 * @return array Version and other information about the item.
1011
+	 */
1012
+	public function getItemArray(array $itemInfo)
1013
+	{
1014
+		return $this->newFunctionParameters[$itemInfo['nameLc']][$itemInfo['offset']];
1015
+	}
1016 1016
 
1017 1017
 
1018
-    /**
1019
-     * Get an array of the non-PHP-version array keys used in a sub-array.
1020
-     *
1021
-     * @return array
1022
-     */
1023
-    protected function getNonVersionArrayKeys()
1024
-    {
1025
-        return array('name');
1026
-    }
1018
+	/**
1019
+	 * Get an array of the non-PHP-version array keys used in a sub-array.
1020
+	 *
1021
+	 * @return array
1022
+	 */
1023
+	protected function getNonVersionArrayKeys()
1024
+	{
1025
+		return array('name');
1026
+	}
1027 1027
 
1028 1028
 
1029
-    /**
1030
-     * Retrieve the relevant detail (version) information for use in an error message.
1031
-     *
1032
-     * @param array $itemArray Version and other information about the item.
1033
-     * @param array $itemInfo  Base information about the item.
1034
-     *
1035
-     * @return array
1036
-     */
1037
-    public function getErrorInfo(array $itemArray, array $itemInfo)
1038
-    {
1039
-        $errorInfo              = parent::getErrorInfo($itemArray, $itemInfo);
1040
-        $errorInfo['paramName'] = $itemArray['name'];
1029
+	/**
1030
+	 * Retrieve the relevant detail (version) information for use in an error message.
1031
+	 *
1032
+	 * @param array $itemArray Version and other information about the item.
1033
+	 * @param array $itemInfo  Base information about the item.
1034
+	 *
1035
+	 * @return array
1036
+	 */
1037
+	public function getErrorInfo(array $itemArray, array $itemInfo)
1038
+	{
1039
+		$errorInfo              = parent::getErrorInfo($itemArray, $itemInfo);
1040
+		$errorInfo['paramName'] = $itemArray['name'];
1041 1041
 
1042
-        return $errorInfo;
1043
-    }
1042
+		return $errorInfo;
1043
+	}
1044 1044
 
1045 1045
 
1046
-    /**
1047
-     * Get the item name to be used for the creation of the error code.
1048
-     *
1049
-     * @param array $itemInfo  Base information about the item.
1050
-     * @param array $errorInfo Detail information about an item.
1051
-     *
1052
-     * @return string
1053
-     */
1054
-    protected function getItemName(array $itemInfo, array $errorInfo)
1055
-    {
1056
-        return $itemInfo['name'] . '_' . $errorInfo['paramName'];
1057
-    }
1046
+	/**
1047
+	 * Get the item name to be used for the creation of the error code.
1048
+	 *
1049
+	 * @param array $itemInfo  Base information about the item.
1050
+	 * @param array $errorInfo Detail information about an item.
1051
+	 *
1052
+	 * @return string
1053
+	 */
1054
+	protected function getItemName(array $itemInfo, array $errorInfo)
1055
+	{
1056
+		return $itemInfo['name'] . '_' . $errorInfo['paramName'];
1057
+	}
1058 1058
 
1059 1059
 
1060
-    /**
1061
-     * Get the error message template for this sniff.
1062
-     *
1063
-     * @return string
1064
-     */
1065
-    protected function getErrorMsgTemplate()
1066
-    {
1067
-        return 'The function %s() does not have a parameter "%s" in PHP version %s or earlier';
1068
-    }
1060
+	/**
1061
+	 * Get the error message template for this sniff.
1062
+	 *
1063
+	 * @return string
1064
+	 */
1065
+	protected function getErrorMsgTemplate()
1066
+	{
1067
+		return 'The function %s() does not have a parameter "%s" in PHP version %s or earlier';
1068
+	}
1069 1069
 
1070 1070
 
1071
-    /**
1072
-     * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
1073
-     *
1074
-     * @param array $data      The error data array which was created.
1075
-     * @param array $itemInfo  Base information about the item this error message applies to.
1076
-     * @param array $errorInfo Detail information about an item this error message applies to.
1077
-     *
1078
-     * @return array
1079
-     */
1080
-    protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
1081
-    {
1082
-        array_shift($data);
1083
-        array_unshift($data, $itemInfo['name'], $errorInfo['paramName']);
1084
-        return $data;
1085
-    }
1071
+	/**
1072
+	 * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
1073
+	 *
1074
+	 * @param array $data      The error data array which was created.
1075
+	 * @param array $itemInfo  Base information about the item this error message applies to.
1076
+	 * @param array $errorInfo Detail information about an item this error message applies to.
1077
+	 *
1078
+	 * @return array
1079
+	 */
1080
+	protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
1081
+	{
1082
+		array_shift($data);
1083
+		array_unshift($data, $itemInfo['name'], $errorInfo['paramName']);
1084
+		return $data;
1085
+	}
1086 1086
 }
Please login to merge, or discard this patch.
php-compatibility/PHPCompatibility/Sniffs/Keywords/NewKeywordsSniff.php 1 patch
Indentation   +323 added lines, -323 removed lines patch added patch discarded remove patch
@@ -25,196 +25,196 @@  discard block
 block discarded – undo
25 25
 class NewKeywordsSniff extends AbstractNewFeatureSniff
26 26
 {
27 27
 
28
-    /**
29
-     * A list of new keywords, not present in older versions.
30
-     *
31
-     * The array lists : version number with false (not present) or true (present).
32
-     * If's sufficient to list the last version which did not contain the keyword.
33
-     *
34
-     * Description will be used as part of the error message.
35
-     * Condition is the name of a callback method within this class or the parent class
36
-     * which checks whether the token complies with a certain condition.
37
-     * The callback function will be passed the $phpcsFile and the $stackPtr.
38
-     * The callback function should return `true` if the condition is met and the
39
-     * error should *not* be thrown.
40
-     *
41
-     * @var array(string => array(string => int|string|null))
42
-     */
43
-    protected $newKeywords = array(
44
-        'T_HALT_COMPILER' => array(
45
-            '5.0'         => false,
46
-            '5.1'         => true,
47
-            'description' => '"__halt_compiler" keyword',
48
-        ),
49
-        'T_CONST' => array(
50
-            '5.2'         => false,
51
-            '5.3'         => true,
52
-            'description' => '"const" keyword',
53
-            'condition'   => 'isClassConstant', // Keyword is only new when not in class context.
54
-        ),
55
-        'T_CALLABLE' => array(
56
-            '5.3'         => false,
57
-            '5.4'         => true,
58
-            'description' => '"callable" keyword',
59
-            'content'     => 'callable',
60
-        ),
61
-        'T_DIR' => array(
62
-            '5.2'         => false,
63
-            '5.3'         => true,
64
-            'description' => '__DIR__ magic constant',
65
-            'content'     => '__DIR__',
66
-        ),
67
-        'T_GOTO' => array(
68
-            '5.2'         => false,
69
-            '5.3'         => true,
70
-            'description' => '"goto" keyword',
71
-            'content'     => 'goto',
72
-        ),
73
-        'T_INSTEADOF' => array(
74
-            '5.3'         => false,
75
-            '5.4'         => true,
76
-            'description' => '"insteadof" keyword (for traits)',
77
-            'content'     => 'insteadof',
78
-        ),
79
-        'T_NAMESPACE' => array(
80
-            '5.2'         => false,
81
-            '5.3'         => true,
82
-            'description' => '"namespace" keyword',
83
-            'content'     => 'namespace',
84
-        ),
85
-        'T_NS_C' => array(
86
-            '5.2'         => false,
87
-            '5.3'         => true,
88
-            'description' => '__NAMESPACE__ magic constant',
89
-            'content'     => '__NAMESPACE__',
90
-        ),
91
-        'T_USE' => array(
92
-            '5.2'         => false,
93
-            '5.3'         => true,
94
-            'description' => '"use" keyword (for traits/namespaces/anonymous functions)',
95
-        ),
96
-        'T_START_NOWDOC' => array(
97
-            '5.2'         => false,
98
-            '5.3'         => true,
99
-            'description' => 'nowdoc functionality',
100
-        ),
101
-        'T_END_NOWDOC' => array(
102
-            '5.2'         => false,
103
-            '5.3'         => true,
104
-            'description' => 'nowdoc functionality',
105
-        ),
106
-        'T_START_HEREDOC' => array(
107
-            '5.2'         => false,
108
-            '5.3'         => true,
109
-            'description' => '(Double) quoted Heredoc identifier',
110
-            'condition'   => 'isNotQuoted', // Heredoc is only new with quoted identifier.
111
-        ),
112
-        'T_TRAIT' => array(
113
-            '5.3'         => false,
114
-            '5.4'         => true,
115
-            'description' => '"trait" keyword',
116
-            'content'     => 'trait',
117
-        ),
118
-        'T_TRAIT_C' => array(
119
-            '5.3'         => false,
120
-            '5.4'         => true,
121
-            'description' => '__TRAIT__ magic constant',
122
-            'content'     => '__TRAIT__',
123
-        ),
124
-        // The specifics for distinguishing between 'yield' and 'yield from' are dealt
125
-        // with in the translation logic.
126
-        // This token has to be placed above the `T_YIELD` token in this array to allow for this.
127
-        'T_YIELD_FROM' => array(
128
-            '5.6'         => false,
129
-            '7.0'         => true,
130
-            'description' => '"yield from" keyword (for generators)',
131
-            'content'     => 'yield',
132
-        ),
133
-        'T_YIELD' => array(
134
-            '5.4'         => false,
135
-            '5.5'         => true,
136
-            'description' => '"yield" keyword (for generators)',
137
-            'content'     => 'yield',
138
-        ),
139
-        'T_FINALLY' => array(
140
-            '5.4'         => false,
141
-            '5.5'         => true,
142
-            'description' => '"finally" keyword (in exception handling)',
143
-            'content'     => 'finally',
144
-        ),
145
-    );
146
-
147
-    /**
148
-     * Translation table for T_STRING tokens.
149
-     *
150
-     * Will be set up from the register() method.
151
-     *
152
-     * @var array(string => string)
153
-     */
154
-    protected $translateContentToToken = array();
155
-
156
-
157
-    /**
158
-     * Returns an array of tokens this test wants to listen for.
159
-     *
160
-     * @return array
161
-     */
162
-    public function register()
163
-    {
164
-        $tokens    = array();
165
-        $translate = array();
166
-        foreach ($this->newKeywords as $token => $versions) {
167
-            if (\defined($token)) {
168
-                $tokens[] = constant($token);
169
-            }
170
-            if (isset($versions['content'])) {
171
-                $translate[strtolower($versions['content'])] = $token;
172
-            }
173
-        }
174
-
175
-        /*
28
+	/**
29
+	 * A list of new keywords, not present in older versions.
30
+	 *
31
+	 * The array lists : version number with false (not present) or true (present).
32
+	 * If's sufficient to list the last version which did not contain the keyword.
33
+	 *
34
+	 * Description will be used as part of the error message.
35
+	 * Condition is the name of a callback method within this class or the parent class
36
+	 * which checks whether the token complies with a certain condition.
37
+	 * The callback function will be passed the $phpcsFile and the $stackPtr.
38
+	 * The callback function should return `true` if the condition is met and the
39
+	 * error should *not* be thrown.
40
+	 *
41
+	 * @var array(string => array(string => int|string|null))
42
+	 */
43
+	protected $newKeywords = array(
44
+		'T_HALT_COMPILER' => array(
45
+			'5.0'         => false,
46
+			'5.1'         => true,
47
+			'description' => '"__halt_compiler" keyword',
48
+		),
49
+		'T_CONST' => array(
50
+			'5.2'         => false,
51
+			'5.3'         => true,
52
+			'description' => '"const" keyword',
53
+			'condition'   => 'isClassConstant', // Keyword is only new when not in class context.
54
+		),
55
+		'T_CALLABLE' => array(
56
+			'5.3'         => false,
57
+			'5.4'         => true,
58
+			'description' => '"callable" keyword',
59
+			'content'     => 'callable',
60
+		),
61
+		'T_DIR' => array(
62
+			'5.2'         => false,
63
+			'5.3'         => true,
64
+			'description' => '__DIR__ magic constant',
65
+			'content'     => '__DIR__',
66
+		),
67
+		'T_GOTO' => array(
68
+			'5.2'         => false,
69
+			'5.3'         => true,
70
+			'description' => '"goto" keyword',
71
+			'content'     => 'goto',
72
+		),
73
+		'T_INSTEADOF' => array(
74
+			'5.3'         => false,
75
+			'5.4'         => true,
76
+			'description' => '"insteadof" keyword (for traits)',
77
+			'content'     => 'insteadof',
78
+		),
79
+		'T_NAMESPACE' => array(
80
+			'5.2'         => false,
81
+			'5.3'         => true,
82
+			'description' => '"namespace" keyword',
83
+			'content'     => 'namespace',
84
+		),
85
+		'T_NS_C' => array(
86
+			'5.2'         => false,
87
+			'5.3'         => true,
88
+			'description' => '__NAMESPACE__ magic constant',
89
+			'content'     => '__NAMESPACE__',
90
+		),
91
+		'T_USE' => array(
92
+			'5.2'         => false,
93
+			'5.3'         => true,
94
+			'description' => '"use" keyword (for traits/namespaces/anonymous functions)',
95
+		),
96
+		'T_START_NOWDOC' => array(
97
+			'5.2'         => false,
98
+			'5.3'         => true,
99
+			'description' => 'nowdoc functionality',
100
+		),
101
+		'T_END_NOWDOC' => array(
102
+			'5.2'         => false,
103
+			'5.3'         => true,
104
+			'description' => 'nowdoc functionality',
105
+		),
106
+		'T_START_HEREDOC' => array(
107
+			'5.2'         => false,
108
+			'5.3'         => true,
109
+			'description' => '(Double) quoted Heredoc identifier',
110
+			'condition'   => 'isNotQuoted', // Heredoc is only new with quoted identifier.
111
+		),
112
+		'T_TRAIT' => array(
113
+			'5.3'         => false,
114
+			'5.4'         => true,
115
+			'description' => '"trait" keyword',
116
+			'content'     => 'trait',
117
+		),
118
+		'T_TRAIT_C' => array(
119
+			'5.3'         => false,
120
+			'5.4'         => true,
121
+			'description' => '__TRAIT__ magic constant',
122
+			'content'     => '__TRAIT__',
123
+		),
124
+		// The specifics for distinguishing between 'yield' and 'yield from' are dealt
125
+		// with in the translation logic.
126
+		// This token has to be placed above the `T_YIELD` token in this array to allow for this.
127
+		'T_YIELD_FROM' => array(
128
+			'5.6'         => false,
129
+			'7.0'         => true,
130
+			'description' => '"yield from" keyword (for generators)',
131
+			'content'     => 'yield',
132
+		),
133
+		'T_YIELD' => array(
134
+			'5.4'         => false,
135
+			'5.5'         => true,
136
+			'description' => '"yield" keyword (for generators)',
137
+			'content'     => 'yield',
138
+		),
139
+		'T_FINALLY' => array(
140
+			'5.4'         => false,
141
+			'5.5'         => true,
142
+			'description' => '"finally" keyword (in exception handling)',
143
+			'content'     => 'finally',
144
+		),
145
+	);
146
+
147
+	/**
148
+	 * Translation table for T_STRING tokens.
149
+	 *
150
+	 * Will be set up from the register() method.
151
+	 *
152
+	 * @var array(string => string)
153
+	 */
154
+	protected $translateContentToToken = array();
155
+
156
+
157
+	/**
158
+	 * Returns an array of tokens this test wants to listen for.
159
+	 *
160
+	 * @return array
161
+	 */
162
+	public function register()
163
+	{
164
+		$tokens    = array();
165
+		$translate = array();
166
+		foreach ($this->newKeywords as $token => $versions) {
167
+			if (\defined($token)) {
168
+				$tokens[] = constant($token);
169
+			}
170
+			if (isset($versions['content'])) {
171
+				$translate[strtolower($versions['content'])] = $token;
172
+			}
173
+		}
174
+
175
+		/*
176 176
          * Deal with tokens not recognized by the PHP version the sniffer is run
177 177
          * under and (not correctly) compensated for by PHPCS.
178 178
          */
179
-        if (empty($translate) === false) {
180
-            $this->translateContentToToken = $translate;
181
-            $tokens[]                      = \T_STRING;
182
-        }
183
-
184
-        return $tokens;
185
-    }
186
-
187
-
188
-    /**
189
-     * Processes this test, when one of its tokens is encountered.
190
-     *
191
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
192
-     * @param int                   $stackPtr  The position of the current token in
193
-     *                                         the stack passed in $tokens.
194
-     *
195
-     * @return void
196
-     */
197
-    public function process(File $phpcsFile, $stackPtr)
198
-    {
199
-        $tokens    = $phpcsFile->getTokens();
200
-        $tokenType = $tokens[$stackPtr]['type'];
201
-
202
-        // Allow for dealing with multi-token keywords, like "yield from".
203
-        $end = $stackPtr;
204
-
205
-        // Translate T_STRING token if necessary.
206
-        if ($tokens[$stackPtr]['type'] === 'T_STRING') {
207
-            $content = strtolower($tokens[$stackPtr]['content']);
208
-
209
-            if (isset($this->translateContentToToken[$content]) === false) {
210
-                // Not one of the tokens we're looking for.
211
-                return;
212
-            }
213
-
214
-            $tokenType = $this->translateContentToToken[$content];
215
-        }
216
-
217
-        /*
179
+		if (empty($translate) === false) {
180
+			$this->translateContentToToken = $translate;
181
+			$tokens[]                      = \T_STRING;
182
+		}
183
+
184
+		return $tokens;
185
+	}
186
+
187
+
188
+	/**
189
+	 * Processes this test, when one of its tokens is encountered.
190
+	 *
191
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
192
+	 * @param int                   $stackPtr  The position of the current token in
193
+	 *                                         the stack passed in $tokens.
194
+	 *
195
+	 * @return void
196
+	 */
197
+	public function process(File $phpcsFile, $stackPtr)
198
+	{
199
+		$tokens    = $phpcsFile->getTokens();
200
+		$tokenType = $tokens[$stackPtr]['type'];
201
+
202
+		// Allow for dealing with multi-token keywords, like "yield from".
203
+		$end = $stackPtr;
204
+
205
+		// Translate T_STRING token if necessary.
206
+		if ($tokens[$stackPtr]['type'] === 'T_STRING') {
207
+			$content = strtolower($tokens[$stackPtr]['content']);
208
+
209
+			if (isset($this->translateContentToToken[$content]) === false) {
210
+				// Not one of the tokens we're looking for.
211
+				return;
212
+			}
213
+
214
+			$tokenType = $this->translateContentToToken[$content];
215
+		}
216
+
217
+		/*
218 218
          * Special case: distinguish between `yield` and `yield from`.
219 219
          *
220 220
          * PHPCS currently (at least up to v 3.0.1) does not backfill for the
@@ -227,140 +227,140 @@  discard block
 block discarded – undo
227 227
          * In PHP 7.0+ both are tokenized as their respective token, however,
228 228
          * a multi-line "yield from" is tokenized as two tokens.
229 229
          */
230
-        if ($tokenType === 'T_YIELD') {
231
-            $nextToken = $phpcsFile->findNext(\T_WHITESPACE, ($end + 1), null, true);
232
-            if ($tokens[$nextToken]['code'] === \T_STRING
233
-                && $tokens[$nextToken]['content'] === 'from'
234
-            ) {
235
-                $tokenType = 'T_YIELD_FROM';
236
-                $end       = $nextToken;
237
-            }
238
-            unset($nextToken);
239
-        }
240
-
241
-        if ($tokenType === 'T_YIELD_FROM' && $tokens[($stackPtr - 1)]['type'] === 'T_YIELD_FROM') {
242
-            // Multi-line "yield from", no need to report it twice.
243
-            return;
244
-        }
245
-
246
-        if (isset($this->newKeywords[$tokenType]) === false) {
247
-            return;
248
-        }
249
-
250
-        $nextToken = $phpcsFile->findNext(Tokens::$emptyTokens, ($end + 1), null, true);
251
-        $prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
252
-
253
-        if ($prevToken !== false
254
-            && ($tokens[$prevToken]['code'] === \T_DOUBLE_COLON
255
-            || $tokens[$prevToken]['code'] === \T_OBJECT_OPERATOR)
256
-        ) {
257
-            // Class property of the same name as one of the keywords. Ignore.
258
-            return;
259
-        }
260
-
261
-        // Skip attempts to use keywords as functions or class names - the former
262
-        // will be reported by ForbiddenNamesAsInvokedFunctionsSniff, whilst the
263
-        // latter will be (partially) reported by the ForbiddenNames sniff.
264
-        // Either type will result in false-positives when targetting lower versions
265
-        // of PHP where the name was not reserved, unless we explicitly check for
266
-        // them.
267
-        if (($nextToken === false
268
-                || $tokens[$nextToken]['type'] !== 'T_OPEN_PARENTHESIS')
269
-            && ($prevToken === false
270
-                || $tokens[$prevToken]['type'] !== 'T_CLASS'
271
-                || $tokens[$prevToken]['type'] !== 'T_INTERFACE')
272
-        ) {
273
-            // Skip based on token scope condition.
274
-            if (isset($this->newKeywords[$tokenType]['condition'])
275
-                && \call_user_func(array($this, $this->newKeywords[$tokenType]['condition']), $phpcsFile, $stackPtr) === true
276
-            ) {
277
-                return;
278
-            }
279
-
280
-            $itemInfo = array(
281
-                'name'   => $tokenType,
282
-            );
283
-            $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
284
-        }
285
-    }
286
-
287
-
288
-    /**
289
-     * Get the relevant sub-array for a specific item from a multi-dimensional array.
290
-     *
291
-     * @param array $itemInfo Base information about the item.
292
-     *
293
-     * @return array Version and other information about the item.
294
-     */
295
-    public function getItemArray(array $itemInfo)
296
-    {
297
-        return $this->newKeywords[$itemInfo['name']];
298
-    }
299
-
300
-
301
-    /**
302
-     * Get an array of the non-PHP-version array keys used in a sub-array.
303
-     *
304
-     * @return array
305
-     */
306
-    protected function getNonVersionArrayKeys()
307
-    {
308
-        return array(
309
-            'description',
310
-            'condition',
311
-            'content',
312
-        );
313
-    }
314
-
315
-
316
-    /**
317
-     * Retrieve the relevant detail (version) information for use in an error message.
318
-     *
319
-     * @param array $itemArray Version and other information about the item.
320
-     * @param array $itemInfo  Base information about the item.
321
-     *
322
-     * @return array
323
-     */
324
-    public function getErrorInfo(array $itemArray, array $itemInfo)
325
-    {
326
-        $errorInfo                = parent::getErrorInfo($itemArray, $itemInfo);
327
-        $errorInfo['description'] = $itemArray['description'];
328
-
329
-        return $errorInfo;
330
-    }
331
-
332
-
333
-    /**
334
-     * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
335
-     *
336
-     * @param array $data      The error data array which was created.
337
-     * @param array $itemInfo  Base information about the item this error message applies to.
338
-     * @param array $errorInfo Detail information about an item this error message applies to.
339
-     *
340
-     * @return array
341
-     */
342
-    protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
343
-    {
344
-        $data[0] = $errorInfo['description'];
345
-        return $data;
346
-    }
347
-
348
-
349
-    /**
350
-     * Callback for the quoted heredoc identifier condition.
351
-     *
352
-     * A double quoted identifier will have the opening quote on position 3
353
-     * in the string: `<<<"ID"`.
354
-     *
355
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
356
-     * @param int                   $stackPtr  The position of the current token in
357
-     *                                         the stack passed in $tokens.
358
-     *
359
-     * @return bool
360
-     */
361
-    public function isNotQuoted(File $phpcsFile, $stackPtr)
362
-    {
363
-        $tokens = $phpcsFile->getTokens();
364
-        return ($tokens[$stackPtr]['content'][3] !== '"');
365
-    }
230
+		if ($tokenType === 'T_YIELD') {
231
+			$nextToken = $phpcsFile->findNext(\T_WHITESPACE, ($end + 1), null, true);
232
+			if ($tokens[$nextToken]['code'] === \T_STRING
233
+				&& $tokens[$nextToken]['content'] === 'from'
234
+			) {
235
+				$tokenType = 'T_YIELD_FROM';
236
+				$end       = $nextToken;
237
+			}
238
+			unset($nextToken);
239
+		}
240
+
241
+		if ($tokenType === 'T_YIELD_FROM' && $tokens[($stackPtr - 1)]['type'] === 'T_YIELD_FROM') {
242
+			// Multi-line "yield from", no need to report it twice.
243
+			return;
244
+		}
245
+
246
+		if (isset($this->newKeywords[$tokenType]) === false) {
247
+			return;
248
+		}
249
+
250
+		$nextToken = $phpcsFile->findNext(Tokens::$emptyTokens, ($end + 1), null, true);
251
+		$prevToken = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
252
+
253
+		if ($prevToken !== false
254
+			&& ($tokens[$prevToken]['code'] === \T_DOUBLE_COLON
255
+			|| $tokens[$prevToken]['code'] === \T_OBJECT_OPERATOR)
256
+		) {
257
+			// Class property of the same name as one of the keywords. Ignore.
258
+			return;
259
+		}
260
+
261
+		// Skip attempts to use keywords as functions or class names - the former
262
+		// will be reported by ForbiddenNamesAsInvokedFunctionsSniff, whilst the
263
+		// latter will be (partially) reported by the ForbiddenNames sniff.
264
+		// Either type will result in false-positives when targetting lower versions
265
+		// of PHP where the name was not reserved, unless we explicitly check for
266
+		// them.
267
+		if (($nextToken === false
268
+				|| $tokens[$nextToken]['type'] !== 'T_OPEN_PARENTHESIS')
269
+			&& ($prevToken === false
270
+				|| $tokens[$prevToken]['type'] !== 'T_CLASS'
271
+				|| $tokens[$prevToken]['type'] !== 'T_INTERFACE')
272
+		) {
273
+			// Skip based on token scope condition.
274
+			if (isset($this->newKeywords[$tokenType]['condition'])
275
+				&& \call_user_func(array($this, $this->newKeywords[$tokenType]['condition']), $phpcsFile, $stackPtr) === true
276
+			) {
277
+				return;
278
+			}
279
+
280
+			$itemInfo = array(
281
+				'name'   => $tokenType,
282
+			);
283
+			$this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
284
+		}
285
+	}
286
+
287
+
288
+	/**
289
+	 * Get the relevant sub-array for a specific item from a multi-dimensional array.
290
+	 *
291
+	 * @param array $itemInfo Base information about the item.
292
+	 *
293
+	 * @return array Version and other information about the item.
294
+	 */
295
+	public function getItemArray(array $itemInfo)
296
+	{
297
+		return $this->newKeywords[$itemInfo['name']];
298
+	}
299
+
300
+
301
+	/**
302
+	 * Get an array of the non-PHP-version array keys used in a sub-array.
303
+	 *
304
+	 * @return array
305
+	 */
306
+	protected function getNonVersionArrayKeys()
307
+	{
308
+		return array(
309
+			'description',
310
+			'condition',
311
+			'content',
312
+		);
313
+	}
314
+
315
+
316
+	/**
317
+	 * Retrieve the relevant detail (version) information for use in an error message.
318
+	 *
319
+	 * @param array $itemArray Version and other information about the item.
320
+	 * @param array $itemInfo  Base information about the item.
321
+	 *
322
+	 * @return array
323
+	 */
324
+	public function getErrorInfo(array $itemArray, array $itemInfo)
325
+	{
326
+		$errorInfo                = parent::getErrorInfo($itemArray, $itemInfo);
327
+		$errorInfo['description'] = $itemArray['description'];
328
+
329
+		return $errorInfo;
330
+	}
331
+
332
+
333
+	/**
334
+	 * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
335
+	 *
336
+	 * @param array $data      The error data array which was created.
337
+	 * @param array $itemInfo  Base information about the item this error message applies to.
338
+	 * @param array $errorInfo Detail information about an item this error message applies to.
339
+	 *
340
+	 * @return array
341
+	 */
342
+	protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
343
+	{
344
+		$data[0] = $errorInfo['description'];
345
+		return $data;
346
+	}
347
+
348
+
349
+	/**
350
+	 * Callback for the quoted heredoc identifier condition.
351
+	 *
352
+	 * A double quoted identifier will have the opening quote on position 3
353
+	 * in the string: `<<<"ID"`.
354
+	 *
355
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
356
+	 * @param int                   $stackPtr  The position of the current token in
357
+	 *                                         the stack passed in $tokens.
358
+	 *
359
+	 * @return bool
360
+	 */
361
+	public function isNotQuoted(File $phpcsFile, $stackPtr)
362
+	{
363
+		$tokens = $phpcsFile->getTokens();
364
+		return ($tokens[$stackPtr]['content'][3] !== '"');
365
+	}
366 366
 }
Please login to merge, or discard this patch.
PHPCompatibility/Sniffs/Keywords/ForbiddenNamesAsInvokedFunctionsSniff.php 1 patch
Indentation   +140 added lines, -140 removed lines patch added patch discarded remove patch
@@ -27,155 +27,155 @@
 block discarded – undo
27 27
 class ForbiddenNamesAsInvokedFunctionsSniff extends Sniff
28 28
 {
29 29
 
30
-    /**
31
-     * List of tokens to register.
32
-     *
33
-     * @var array
34
-     */
35
-    protected $targetedTokens = array(
36
-        \T_ABSTRACT   => '5.0',
37
-        \T_CALLABLE   => '5.4',
38
-        \T_CATCH      => '5.0',
39
-        \T_FINAL      => '5.0',
40
-        \T_FINALLY    => '5.5',
41
-        \T_GOTO       => '5.3',
42
-        \T_IMPLEMENTS => '5.0',
43
-        \T_INTERFACE  => '5.0',
44
-        \T_INSTANCEOF => '5.0',
45
-        \T_INSTEADOF  => '5.4',
46
-        \T_NAMESPACE  => '5.3',
47
-        \T_PRIVATE    => '5.0',
48
-        \T_PROTECTED  => '5.0',
49
-        \T_PUBLIC     => '5.0',
50
-        \T_TRAIT      => '5.4',
51
-        \T_TRY        => '5.0',
52
-
53
-    );
54
-
55
-    /**
56
-     * T_STRING keywords to recognize as targetted tokens.
57
-     *
58
-     * Compatibility for PHP versions where the keyword is not yet recognized
59
-     * as its own token and for PHPCS versions which change the token to
60
-     * T_STRING when used in a method call.
61
-     *
62
-     * @var array
63
-     */
64
-    protected $targetedStringTokens = array(
65
-        'abstract'   => '5.0',
66
-        'callable'   => '5.4',
67
-        'catch'      => '5.0',
68
-        'final'      => '5.0',
69
-        'finally'    => '5.5',
70
-        'goto'       => '5.3',
71
-        'implements' => '5.0',
72
-        'interface'  => '5.0',
73
-        'instanceof' => '5.0',
74
-        'insteadof'  => '5.4',
75
-        'namespace'  => '5.3',
76
-        'private'    => '5.0',
77
-        'protected'  => '5.0',
78
-        'public'     => '5.0',
79
-        'trait'      => '5.4',
80
-        'try'        => '5.0',
81
-    );
82
-
83
-    /**
84
-     * Returns an array of tokens this test wants to listen for.
85
-     *
86
-     * @return array
87
-     */
88
-    public function register()
89
-    {
90
-        $tokens   = array_keys($this->targetedTokens);
91
-        $tokens[] = \T_STRING;
92
-
93
-        return $tokens;
94
-    }
95
-
96
-    /**
97
-     * Processes this test, when one of its tokens is encountered.
98
-     *
99
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
100
-     * @param int                   $stackPtr  The position of the current token in the
101
-     *                                         stack passed in $tokens.
102
-     *
103
-     * @return void
104
-     */
105
-    public function process(File $phpcsFile, $stackPtr)
106
-    {
107
-        $tokens         = $phpcsFile->getTokens();
108
-        $tokenCode      = $tokens[$stackPtr]['code'];
109
-        $tokenContentLc = strtolower($tokens[$stackPtr]['content']);
110
-        $isString       = false;
111
-
112
-        /*
30
+	/**
31
+	 * List of tokens to register.
32
+	 *
33
+	 * @var array
34
+	 */
35
+	protected $targetedTokens = array(
36
+		\T_ABSTRACT   => '5.0',
37
+		\T_CALLABLE   => '5.4',
38
+		\T_CATCH      => '5.0',
39
+		\T_FINAL      => '5.0',
40
+		\T_FINALLY    => '5.5',
41
+		\T_GOTO       => '5.3',
42
+		\T_IMPLEMENTS => '5.0',
43
+		\T_INTERFACE  => '5.0',
44
+		\T_INSTANCEOF => '5.0',
45
+		\T_INSTEADOF  => '5.4',
46
+		\T_NAMESPACE  => '5.3',
47
+		\T_PRIVATE    => '5.0',
48
+		\T_PROTECTED  => '5.0',
49
+		\T_PUBLIC     => '5.0',
50
+		\T_TRAIT      => '5.4',
51
+		\T_TRY        => '5.0',
52
+
53
+	);
54
+
55
+	/**
56
+	 * T_STRING keywords to recognize as targetted tokens.
57
+	 *
58
+	 * Compatibility for PHP versions where the keyword is not yet recognized
59
+	 * as its own token and for PHPCS versions which change the token to
60
+	 * T_STRING when used in a method call.
61
+	 *
62
+	 * @var array
63
+	 */
64
+	protected $targetedStringTokens = array(
65
+		'abstract'   => '5.0',
66
+		'callable'   => '5.4',
67
+		'catch'      => '5.0',
68
+		'final'      => '5.0',
69
+		'finally'    => '5.5',
70
+		'goto'       => '5.3',
71
+		'implements' => '5.0',
72
+		'interface'  => '5.0',
73
+		'instanceof' => '5.0',
74
+		'insteadof'  => '5.4',
75
+		'namespace'  => '5.3',
76
+		'private'    => '5.0',
77
+		'protected'  => '5.0',
78
+		'public'     => '5.0',
79
+		'trait'      => '5.4',
80
+		'try'        => '5.0',
81
+	);
82
+
83
+	/**
84
+	 * Returns an array of tokens this test wants to listen for.
85
+	 *
86
+	 * @return array
87
+	 */
88
+	public function register()
89
+	{
90
+		$tokens   = array_keys($this->targetedTokens);
91
+		$tokens[] = \T_STRING;
92
+
93
+		return $tokens;
94
+	}
95
+
96
+	/**
97
+	 * Processes this test, when one of its tokens is encountered.
98
+	 *
99
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
100
+	 * @param int                   $stackPtr  The position of the current token in the
101
+	 *                                         stack passed in $tokens.
102
+	 *
103
+	 * @return void
104
+	 */
105
+	public function process(File $phpcsFile, $stackPtr)
106
+	{
107
+		$tokens         = $phpcsFile->getTokens();
108
+		$tokenCode      = $tokens[$stackPtr]['code'];
109
+		$tokenContentLc = strtolower($tokens[$stackPtr]['content']);
110
+		$isString       = false;
111
+
112
+		/*
113 113
          * For string tokens we only care if the string is a reserved word used
114 114
          * as a function. This only happens in older versions of PHP where the
115 115
          * token doesn't exist yet for that keyword or in later versions when the
116 116
          * token is used in a method invocation.
117 117
          */
118
-        if ($tokenCode === \T_STRING
119
-            && (isset($this->targetedStringTokens[$tokenContentLc]) === false)
120
-        ) {
121
-            return;
122
-        }
123
-
124
-        if ($tokenCode === \T_STRING) {
125
-            $isString = true;
126
-        }
127
-
128
-        // Make sure this is a function call.
129
-        $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
130
-        if ($next === false || $tokens[$next]['code'] !== \T_OPEN_PARENTHESIS) {
131
-            // Not a function call.
132
-            return;
133
-        }
134
-
135
-        // This sniff isn't concerned about function declarations.
136
-        $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
137
-        if ($prev !== false && $tokens[$prev]['code'] === \T_FUNCTION) {
138
-            return;
139
-        }
140
-
141
-        /*
118
+		if ($tokenCode === \T_STRING
119
+			&& (isset($this->targetedStringTokens[$tokenContentLc]) === false)
120
+		) {
121
+			return;
122
+		}
123
+
124
+		if ($tokenCode === \T_STRING) {
125
+			$isString = true;
126
+		}
127
+
128
+		// Make sure this is a function call.
129
+		$next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
130
+		if ($next === false || $tokens[$next]['code'] !== \T_OPEN_PARENTHESIS) {
131
+			// Not a function call.
132
+			return;
133
+		}
134
+
135
+		// This sniff isn't concerned about function declarations.
136
+		$prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
137
+		if ($prev !== false && $tokens[$prev]['code'] === \T_FUNCTION) {
138
+			return;
139
+		}
140
+
141
+		/*
142 142
          * Deal with PHP 7 relaxing the rules.
143 143
          * "As of PHP 7.0.0 these keywords are allowed as property, constant, and method names
144 144
          * of classes, interfaces and traits...", i.e. they can be invoked as a method call.
145 145
          *
146 146
          * Only needed for those keywords which we sniff out via T_STRING.
147 147
          */
148
-        if (($tokens[$prev]['code'] === \T_OBJECT_OPERATOR || $tokens[$prev]['code'] === \T_DOUBLE_COLON)
149
-            && $this->supportsBelow('5.6') === false
150
-        ) {
151
-            return;
152
-        }
153
-
154
-        // For the word catch, it is valid to have an open parenthesis
155
-        // after it, but only if it is preceded by a right curly brace.
156
-        if ($tokenCode === \T_CATCH) {
157
-            if ($prev !== false && $tokens[$prev]['code'] === \T_CLOSE_CURLY_BRACKET) {
158
-                // Ok, it's fine.
159
-                return;
160
-            }
161
-        }
162
-
163
-        if ($isString === true) {
164
-            $version = $this->targetedStringTokens[$tokenContentLc];
165
-        } else {
166
-            $version = $this->targetedTokens[$tokenCode];
167
-        }
168
-
169
-        if ($this->supportsAbove($version)) {
170
-            $error     = "'%s' is a reserved keyword introduced in PHP version %s and cannot be invoked as a function (%s)";
171
-            $errorCode = $this->stringToErrorCode($tokenContentLc) . 'Found';
172
-            $data      = array(
173
-                $tokenContentLc,
174
-                $version,
175
-                $tokens[$stackPtr]['type'],
176
-            );
177
-
178
-            $phpcsFile->addError($error, $stackPtr, $errorCode, $data);
179
-        }
180
-    }
148
+		if (($tokens[$prev]['code'] === \T_OBJECT_OPERATOR || $tokens[$prev]['code'] === \T_DOUBLE_COLON)
149
+			&& $this->supportsBelow('5.6') === false
150
+		) {
151
+			return;
152
+		}
153
+
154
+		// For the word catch, it is valid to have an open parenthesis
155
+		// after it, but only if it is preceded by a right curly brace.
156
+		if ($tokenCode === \T_CATCH) {
157
+			if ($prev !== false && $tokens[$prev]['code'] === \T_CLOSE_CURLY_BRACKET) {
158
+				// Ok, it's fine.
159
+				return;
160
+			}
161
+		}
162
+
163
+		if ($isString === true) {
164
+			$version = $this->targetedStringTokens[$tokenContentLc];
165
+		} else {
166
+			$version = $this->targetedTokens[$tokenCode];
167
+		}
168
+
169
+		if ($this->supportsAbove($version)) {
170
+			$error     = "'%s' is a reserved keyword introduced in PHP version %s and cannot be invoked as a function (%s)";
171
+			$errorCode = $this->stringToErrorCode($tokenContentLc) . 'Found';
172
+			$data      = array(
173
+				$tokenContentLc,
174
+				$version,
175
+				$tokens[$stackPtr]['type'],
176
+			);
177
+
178
+			$phpcsFile->addError($error, $stackPtr, $errorCode, $data);
179
+		}
180
+	}
181 181
 }
Please login to merge, or discard this patch.
PHPCompatibility/Sniffs/Keywords/ForbiddenNamesAsDeclaredSniff.php 1 patch
Indentation   +213 added lines, -213 removed lines patch added patch discarded remove patch
@@ -32,217 +32,217 @@
 block discarded – undo
32 32
 class ForbiddenNamesAsDeclaredSniff extends Sniff
33 33
 {
34 34
 
35
-    /**
36
-     * List of tokens which can not be used as class, interface, trait names or as part of a namespace.
37
-     *
38
-     * @var array
39
-     */
40
-    protected $forbiddenTokens = array(
41
-        \T_NULL  => '7.0',
42
-        \T_TRUE  => '7.0',
43
-        \T_FALSE => '7.0',
44
-    );
45
-
46
-    /**
47
-     * T_STRING keywords to recognize as forbidden names.
48
-     *
49
-     * @var array
50
-     */
51
-    protected $forbiddenNames = array(
52
-        'null'     => '7.0',
53
-        'true'     => '7.0',
54
-        'false'    => '7.0',
55
-        'bool'     => '7.0',
56
-        'int'      => '7.0',
57
-        'float'    => '7.0',
58
-        'string'   => '7.0',
59
-        'iterable' => '7.1',
60
-        'void'     => '7.1',
61
-        'object'   => '7.2',
62
-    );
63
-
64
-    /**
65
-     * T_STRING keywords to recognize as soft reserved names.
66
-     *
67
-     * Using any of these keywords to name a class, interface, trait or namespace
68
-     * is highly discouraged since they may be used in future versions of PHP.
69
-     *
70
-     * @var array
71
-     */
72
-    protected $softReservedNames = array(
73
-        'resource' => '7.0',
74
-        'object'   => '7.0',
75
-        'mixed'    => '7.0',
76
-        'numeric'  => '7.0',
77
-    );
78
-
79
-    /**
80
-     * Combined list of the two lists above.
81
-     *
82
-     * Used for quick check whether or not something is a reserved
83
-     * word.
84
-     * Set from the `register()` method.
85
-     *
86
-     * @var array
87
-     */
88
-    private $allForbiddenNames = array();
89
-
90
-
91
-    /**
92
-     * Returns an array of tokens this test wants to listen for.
93
-     *
94
-     * @return array
95
-     */
96
-    public function register()
97
-    {
98
-        // Do the list merge only once.
99
-        $this->allForbiddenNames = array_merge($this->forbiddenNames, $this->softReservedNames);
100
-
101
-        $targets = array(
102
-            \T_CLASS,
103
-            \T_INTERFACE,
104
-            \T_TRAIT,
105
-            \T_NAMESPACE,
106
-            \T_STRING, // Compat for PHPCS < 2.4.0 and PHP < 5.3.
107
-        );
108
-
109
-        return $targets;
110
-    }
111
-
112
-
113
-    /**
114
-     * Processes this test, when one of its tokens is encountered.
115
-     *
116
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
117
-     * @param int                   $stackPtr  The position of the current token in the
118
-     *                                         stack passed in $tokens.
119
-     *
120
-     * @return void
121
-     */
122
-    public function process(File $phpcsFile, $stackPtr)
123
-    {
124
-        if ($this->supportsAbove('7.0') === false) {
125
-            return;
126
-        }
127
-
128
-        $tokens         = $phpcsFile->getTokens();
129
-        $tokenCode      = $tokens[$stackPtr]['code'];
130
-        $tokenType      = $tokens[$stackPtr]['type'];
131
-        $tokenContentLc = strtolower($tokens[$stackPtr]['content']);
132
-
133
-        // For string tokens we only care about 'trait' as that is the only one
134
-        // which may not be correctly recognized as it's own token.
135
-        // This only happens in older versions of PHP where the token doesn't exist yet as a keyword.
136
-        if ($tokenCode === \T_STRING && $tokenContentLc !== 'trait') {
137
-            return;
138
-        }
139
-
140
-        if (\in_array($tokenType, array('T_CLASS', 'T_INTERFACE', 'T_TRAIT'), true)) {
141
-            // Check for the declared name being a name which is not tokenized as T_STRING.
142
-            $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
143
-            if ($nextNonEmpty !== false && isset($this->forbiddenTokens[$tokens[$nextNonEmpty]['code']]) === true) {
144
-                $name = $tokens[$nextNonEmpty]['content'];
145
-            } else {
146
-                // Get the declared name if it's a T_STRING.
147
-                $name = $phpcsFile->getDeclarationName($stackPtr);
148
-            }
149
-            unset($nextNonEmpty);
150
-
151
-            if (isset($name) === false || \is_string($name) === false || $name === '') {
152
-                return;
153
-            }
154
-
155
-            $nameLc = strtolower($name);
156
-            if (isset($this->allForbiddenNames[$nameLc]) === false) {
157
-                return;
158
-            }
159
-
160
-        } elseif ($tokenCode === \T_NAMESPACE) {
161
-            $namespaceName = $this->getDeclaredNamespaceName($phpcsFile, $stackPtr);
162
-
163
-            if ($namespaceName === false || $namespaceName === '') {
164
-                return;
165
-            }
166
-
167
-            $namespaceParts = explode('\\', $namespaceName);
168
-            foreach ($namespaceParts as $namespacePart) {
169
-                $partLc = strtolower($namespacePart);
170
-                if (isset($this->allForbiddenNames[$partLc]) === true) {
171
-                    $name   = $namespacePart;
172
-                    $nameLc = $partLc;
173
-                    break;
174
-                }
175
-            }
176
-        } elseif ($tokenCode === \T_STRING) {
177
-            // Traits which are not yet tokenized as T_TRAIT.
178
-            $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
179
-            if ($nextNonEmpty === false) {
180
-                return;
181
-            }
182
-
183
-            $nextNonEmptyCode = $tokens[$nextNonEmpty]['code'];
184
-
185
-            if ($nextNonEmptyCode !== \T_STRING && isset($this->forbiddenTokens[$nextNonEmptyCode]) === true) {
186
-                $name   = $tokens[$nextNonEmpty]['content'];
187
-                $nameLc = strtolower($tokens[$nextNonEmpty]['content']);
188
-            } elseif ($nextNonEmptyCode === \T_STRING) {
189
-                $endOfStatement = $phpcsFile->findNext(array(\T_SEMICOLON, \T_OPEN_CURLY_BRACKET), ($stackPtr + 1));
190
-                if ($endOfStatement === false) {
191
-                    return;
192
-                }
193
-
194
-                do {
195
-                    $nextNonEmptyLc = strtolower($tokens[$nextNonEmpty]['content']);
196
-
197
-                    if (isset($this->allForbiddenNames[$nextNonEmptyLc]) === true) {
198
-                        $name   = $tokens[$nextNonEmpty]['content'];
199
-                        $nameLc = $nextNonEmptyLc;
200
-                        break;
201
-                    }
202
-
203
-                    $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), $endOfStatement, true);
204
-                } while ($nextNonEmpty !== false);
205
-            }
206
-            unset($nextNonEmptyCode, $nextNonEmptyLc, $endOfStatement);
207
-        }
208
-
209
-        if (isset($name, $nameLc) === false) {
210
-            return;
211
-        }
212
-
213
-        // Still here, so this is one of the reserved words.
214
-        // Build up the error message.
215
-        $error     = "'%s' is a";
216
-        $isError   = null;
217
-        $errorCode = $this->stringToErrorCode($nameLc) . 'Found';
218
-        $data      = array(
219
-            $nameLc,
220
-        );
221
-
222
-        if (isset($this->softReservedNames[$nameLc]) === true
223
-            && $this->supportsAbove($this->softReservedNames[$nameLc]) === true
224
-        ) {
225
-            $error  .= ' soft reserved keyword as of PHP version %s';
226
-            $isError = false;
227
-            $data[]  = $this->softReservedNames[$nameLc];
228
-        }
229
-
230
-        if (isset($this->forbiddenNames[$nameLc]) === true
231
-            && $this->supportsAbove($this->forbiddenNames[$nameLc]) === true
232
-        ) {
233
-            if (isset($isError) === true) {
234
-                $error .= ' and a';
235
-            }
236
-            $error  .= ' reserved keyword as of PHP version %s';
237
-            $isError = true;
238
-            $data[]  = $this->forbiddenNames[$nameLc];
239
-        }
240
-
241
-        if (isset($isError) === true) {
242
-            $error .= ' and should not be used to name a class, interface or trait or as part of a namespace (%s)';
243
-            $data[] = $tokens[$stackPtr]['type'];
244
-
245
-            $this->addMessage($phpcsFile, $error, $stackPtr, $isError, $errorCode, $data);
246
-        }
247
-    }
35
+	/**
36
+	 * List of tokens which can not be used as class, interface, trait names or as part of a namespace.
37
+	 *
38
+	 * @var array
39
+	 */
40
+	protected $forbiddenTokens = array(
41
+		\T_NULL  => '7.0',
42
+		\T_TRUE  => '7.0',
43
+		\T_FALSE => '7.0',
44
+	);
45
+
46
+	/**
47
+	 * T_STRING keywords to recognize as forbidden names.
48
+	 *
49
+	 * @var array
50
+	 */
51
+	protected $forbiddenNames = array(
52
+		'null'     => '7.0',
53
+		'true'     => '7.0',
54
+		'false'    => '7.0',
55
+		'bool'     => '7.0',
56
+		'int'      => '7.0',
57
+		'float'    => '7.0',
58
+		'string'   => '7.0',
59
+		'iterable' => '7.1',
60
+		'void'     => '7.1',
61
+		'object'   => '7.2',
62
+	);
63
+
64
+	/**
65
+	 * T_STRING keywords to recognize as soft reserved names.
66
+	 *
67
+	 * Using any of these keywords to name a class, interface, trait or namespace
68
+	 * is highly discouraged since they may be used in future versions of PHP.
69
+	 *
70
+	 * @var array
71
+	 */
72
+	protected $softReservedNames = array(
73
+		'resource' => '7.0',
74
+		'object'   => '7.0',
75
+		'mixed'    => '7.0',
76
+		'numeric'  => '7.0',
77
+	);
78
+
79
+	/**
80
+	 * Combined list of the two lists above.
81
+	 *
82
+	 * Used for quick check whether or not something is a reserved
83
+	 * word.
84
+	 * Set from the `register()` method.
85
+	 *
86
+	 * @var array
87
+	 */
88
+	private $allForbiddenNames = array();
89
+
90
+
91
+	/**
92
+	 * Returns an array of tokens this test wants to listen for.
93
+	 *
94
+	 * @return array
95
+	 */
96
+	public function register()
97
+	{
98
+		// Do the list merge only once.
99
+		$this->allForbiddenNames = array_merge($this->forbiddenNames, $this->softReservedNames);
100
+
101
+		$targets = array(
102
+			\T_CLASS,
103
+			\T_INTERFACE,
104
+			\T_TRAIT,
105
+			\T_NAMESPACE,
106
+			\T_STRING, // Compat for PHPCS < 2.4.0 and PHP < 5.3.
107
+		);
108
+
109
+		return $targets;
110
+	}
111
+
112
+
113
+	/**
114
+	 * Processes this test, when one of its tokens is encountered.
115
+	 *
116
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
117
+	 * @param int                   $stackPtr  The position of the current token in the
118
+	 *                                         stack passed in $tokens.
119
+	 *
120
+	 * @return void
121
+	 */
122
+	public function process(File $phpcsFile, $stackPtr)
123
+	{
124
+		if ($this->supportsAbove('7.0') === false) {
125
+			return;
126
+		}
127
+
128
+		$tokens         = $phpcsFile->getTokens();
129
+		$tokenCode      = $tokens[$stackPtr]['code'];
130
+		$tokenType      = $tokens[$stackPtr]['type'];
131
+		$tokenContentLc = strtolower($tokens[$stackPtr]['content']);
132
+
133
+		// For string tokens we only care about 'trait' as that is the only one
134
+		// which may not be correctly recognized as it's own token.
135
+		// This only happens in older versions of PHP where the token doesn't exist yet as a keyword.
136
+		if ($tokenCode === \T_STRING && $tokenContentLc !== 'trait') {
137
+			return;
138
+		}
139
+
140
+		if (\in_array($tokenType, array('T_CLASS', 'T_INTERFACE', 'T_TRAIT'), true)) {
141
+			// Check for the declared name being a name which is not tokenized as T_STRING.
142
+			$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
143
+			if ($nextNonEmpty !== false && isset($this->forbiddenTokens[$tokens[$nextNonEmpty]['code']]) === true) {
144
+				$name = $tokens[$nextNonEmpty]['content'];
145
+			} else {
146
+				// Get the declared name if it's a T_STRING.
147
+				$name = $phpcsFile->getDeclarationName($stackPtr);
148
+			}
149
+			unset($nextNonEmpty);
150
+
151
+			if (isset($name) === false || \is_string($name) === false || $name === '') {
152
+				return;
153
+			}
154
+
155
+			$nameLc = strtolower($name);
156
+			if (isset($this->allForbiddenNames[$nameLc]) === false) {
157
+				return;
158
+			}
159
+
160
+		} elseif ($tokenCode === \T_NAMESPACE) {
161
+			$namespaceName = $this->getDeclaredNamespaceName($phpcsFile, $stackPtr);
162
+
163
+			if ($namespaceName === false || $namespaceName === '') {
164
+				return;
165
+			}
166
+
167
+			$namespaceParts = explode('\\', $namespaceName);
168
+			foreach ($namespaceParts as $namespacePart) {
169
+				$partLc = strtolower($namespacePart);
170
+				if (isset($this->allForbiddenNames[$partLc]) === true) {
171
+					$name   = $namespacePart;
172
+					$nameLc = $partLc;
173
+					break;
174
+				}
175
+			}
176
+		} elseif ($tokenCode === \T_STRING) {
177
+			// Traits which are not yet tokenized as T_TRAIT.
178
+			$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
179
+			if ($nextNonEmpty === false) {
180
+				return;
181
+			}
182
+
183
+			$nextNonEmptyCode = $tokens[$nextNonEmpty]['code'];
184
+
185
+			if ($nextNonEmptyCode !== \T_STRING && isset($this->forbiddenTokens[$nextNonEmptyCode]) === true) {
186
+				$name   = $tokens[$nextNonEmpty]['content'];
187
+				$nameLc = strtolower($tokens[$nextNonEmpty]['content']);
188
+			} elseif ($nextNonEmptyCode === \T_STRING) {
189
+				$endOfStatement = $phpcsFile->findNext(array(\T_SEMICOLON, \T_OPEN_CURLY_BRACKET), ($stackPtr + 1));
190
+				if ($endOfStatement === false) {
191
+					return;
192
+				}
193
+
194
+				do {
195
+					$nextNonEmptyLc = strtolower($tokens[$nextNonEmpty]['content']);
196
+
197
+					if (isset($this->allForbiddenNames[$nextNonEmptyLc]) === true) {
198
+						$name   = $tokens[$nextNonEmpty]['content'];
199
+						$nameLc = $nextNonEmptyLc;
200
+						break;
201
+					}
202
+
203
+					$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), $endOfStatement, true);
204
+				} while ($nextNonEmpty !== false);
205
+			}
206
+			unset($nextNonEmptyCode, $nextNonEmptyLc, $endOfStatement);
207
+		}
208
+
209
+		if (isset($name, $nameLc) === false) {
210
+			return;
211
+		}
212
+
213
+		// Still here, so this is one of the reserved words.
214
+		// Build up the error message.
215
+		$error     = "'%s' is a";
216
+		$isError   = null;
217
+		$errorCode = $this->stringToErrorCode($nameLc) . 'Found';
218
+		$data      = array(
219
+			$nameLc,
220
+		);
221
+
222
+		if (isset($this->softReservedNames[$nameLc]) === true
223
+			&& $this->supportsAbove($this->softReservedNames[$nameLc]) === true
224
+		) {
225
+			$error  .= ' soft reserved keyword as of PHP version %s';
226
+			$isError = false;
227
+			$data[]  = $this->softReservedNames[$nameLc];
228
+		}
229
+
230
+		if (isset($this->forbiddenNames[$nameLc]) === true
231
+			&& $this->supportsAbove($this->forbiddenNames[$nameLc]) === true
232
+		) {
233
+			if (isset($isError) === true) {
234
+				$error .= ' and a';
235
+			}
236
+			$error  .= ' reserved keyword as of PHP version %s';
237
+			$isError = true;
238
+			$data[]  = $this->forbiddenNames[$nameLc];
239
+		}
240
+
241
+		if (isset($isError) === true) {
242
+			$error .= ' and should not be used to name a class, interface or trait or as part of a namespace (%s)';
243
+			$data[] = $tokens[$stackPtr]['type'];
244
+
245
+			$this->addMessage($phpcsFile, $error, $stackPtr, $isError, $errorCode, $data);
246
+		}
247
+	}
248 248
 }
Please login to merge, or discard this patch.
PHPCompatibility/Sniffs/Keywords/CaseSensitiveKeywordsSniff.php 1 patch
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -29,45 +29,45 @@
 block discarded – undo
29 29
 class CaseSensitiveKeywordsSniff extends Sniff
30 30
 {
31 31
 
32
-    /**
33
-     * Returns an array of tokens this test wants to listen for.
34
-     *
35
-     * @return array
36
-     */
37
-    public function register()
38
-    {
39
-        return array(
40
-            \T_SELF,
41
-            \T_STATIC,
42
-            \T_PARENT,
43
-        );
44
-    }
32
+	/**
33
+	 * Returns an array of tokens this test wants to listen for.
34
+	 *
35
+	 * @return array
36
+	 */
37
+	public function register()
38
+	{
39
+		return array(
40
+			\T_SELF,
41
+			\T_STATIC,
42
+			\T_PARENT,
43
+		);
44
+	}
45 45
 
46
-    /**
47
-     * Processes this test, when one of its tokens is encountered.
48
-     *
49
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
50
-     * @param int                   $stackPtr  The position of the current token in the
51
-     *                                         stack passed in $tokens.
52
-     *
53
-     * @return void
54
-     */
55
-    public function process(File $phpcsFile, $stackPtr)
56
-    {
57
-        if ($this->supportsBelow('5.4') === false) {
58
-            return;
59
-        }
46
+	/**
47
+	 * Processes this test, when one of its tokens is encountered.
48
+	 *
49
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
50
+	 * @param int                   $stackPtr  The position of the current token in the
51
+	 *                                         stack passed in $tokens.
52
+	 *
53
+	 * @return void
54
+	 */
55
+	public function process(File $phpcsFile, $stackPtr)
56
+	{
57
+		if ($this->supportsBelow('5.4') === false) {
58
+			return;
59
+		}
60 60
 
61
-        $tokens         = $phpcsFile->getTokens();
62
-        $tokenContentLC = strtolower($tokens[$stackPtr]['content']);
61
+		$tokens         = $phpcsFile->getTokens();
62
+		$tokenContentLC = strtolower($tokens[$stackPtr]['content']);
63 63
 
64
-        if ($tokenContentLC !== $tokens[$stackPtr]['content']) {
65
-            $phpcsFile->addError(
66
-                'The keyword \'%s\' was treated in a case-sensitive fashion in certain cases in PHP 5.4 or earlier. Use the lowercase version for consistent support.',
67
-                $stackPtr,
68
-                'NonLowercaseFound',
69
-                array($tokenContentLC)
70
-            );
71
-        }
72
-    }
64
+		if ($tokenContentLC !== $tokens[$stackPtr]['content']) {
65
+			$phpcsFile->addError(
66
+				'The keyword \'%s\' was treated in a case-sensitive fashion in certain cases in PHP 5.4 or earlier. Use the lowercase version for consistent support.',
67
+				$stackPtr,
68
+				'NonLowercaseFound',
69
+				array($tokenContentLC)
70
+			);
71
+		}
72
+	}
73 73
 }
Please login to merge, or discard this patch.
php-compatibility/PHPCompatibility/Sniffs/Keywords/ForbiddenNamesSniff.php 1 patch
Indentation   +335 added lines, -335 removed lines patch added patch discarded remove patch
@@ -27,365 +27,365 @@
 block discarded – undo
27 27
 class ForbiddenNamesSniff extends Sniff
28 28
 {
29 29
 
30
-    /**
31
-     * A list of keywords that can not be used as function, class and namespace name or constant name.
32
-     * Mentions since which version it's not allowed.
33
-     *
34
-     * @var array(string => string)
35
-     */
36
-    protected $invalidNames = array(
37
-        'abstract'      => '5.0',
38
-        'and'           => 'all',
39
-        'array'         => 'all',
40
-        'as'            => 'all',
41
-        'break'         => 'all',
42
-        'callable'      => '5.4',
43
-        'case'          => 'all',
44
-        'catch'         => '5.0',
45
-        'class'         => 'all',
46
-        'clone'         => '5.0',
47
-        'const'         => 'all',
48
-        'continue'      => 'all',
49
-        'declare'       => 'all',
50
-        'default'       => 'all',
51
-        'do'            => 'all',
52
-        'else'          => 'all',
53
-        'elseif'        => 'all',
54
-        'enddeclare'    => 'all',
55
-        'endfor'        => 'all',
56
-        'endforeach'    => 'all',
57
-        'endif'         => 'all',
58
-        'endswitch'     => 'all',
59
-        'endwhile'      => 'all',
60
-        'extends'       => 'all',
61
-        'final'         => '5.0',
62
-        'finally'       => '5.5',
63
-        'for'           => 'all',
64
-        'foreach'       => 'all',
65
-        'function'      => 'all',
66
-        'global'        => 'all',
67
-        'goto'          => '5.3',
68
-        'if'            => 'all',
69
-        'implements'    => '5.0',
70
-        'interface'     => '5.0',
71
-        'instanceof'    => '5.0',
72
-        'insteadof'     => '5.4',
73
-        'namespace'     => '5.3',
74
-        'new'           => 'all',
75
-        'or'            => 'all',
76
-        'private'       => '5.0',
77
-        'protected'     => '5.0',
78
-        'public'        => '5.0',
79
-        'static'        => 'all',
80
-        'switch'        => 'all',
81
-        'throw'         => '5.0',
82
-        'trait'         => '5.4',
83
-        'try'           => '5.0',
84
-        'use'           => 'all',
85
-        'var'           => 'all',
86
-        'while'         => 'all',
87
-        'xor'           => 'all',
88
-        '__class__'     => 'all',
89
-        '__dir__'       => '5.3',
90
-        '__file__'      => 'all',
91
-        '__function__'  => 'all',
92
-        '__method__'    => 'all',
93
-        '__namespace__' => '5.3',
94
-    );
95
-
96
-    /**
97
-     * A list of keywords that can follow use statements.
98
-     *
99
-     * @var array(string => string)
100
-     */
101
-    protected $validUseNames = array(
102
-        'const'    => true,
103
-        'function' => true,
104
-    );
105
-
106
-    /**
107
-     * Scope modifiers and other keywords allowed in trait use statements.
108
-     *
109
-     * @var array
110
-     */
111
-    private $allowedModifiers = array();
112
-
113
-    /**
114
-     * Targeted tokens.
115
-     *
116
-     * @var array
117
-     */
118
-    protected $targetedTokens = array(
119
-        \T_CLASS,
120
-        \T_FUNCTION,
121
-        \T_NAMESPACE,
122
-        \T_STRING,
123
-        \T_CONST,
124
-        \T_USE,
125
-        \T_AS,
126
-        \T_EXTENDS,
127
-        \T_INTERFACE,
128
-        \T_TRAIT,
129
-    );
130
-
131
-    /**
132
-     * Returns an array of tokens this test wants to listen for.
133
-     *
134
-     * @return array
135
-     */
136
-    public function register()
137
-    {
138
-        $this->allowedModifiers           = Tokens::$scopeModifiers;
139
-        $this->allowedModifiers[\T_FINAL] = \T_FINAL;
140
-
141
-        $tokens = $this->targetedTokens;
142
-
143
-        if (\defined('T_ANON_CLASS')) {
144
-            $tokens[] = \T_ANON_CLASS;
145
-        }
146
-
147
-        return $tokens;
148
-    }
149
-
150
-    /**
151
-     * Processes this test, when one of its tokens is encountered.
152
-     *
153
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
154
-     * @param int                   $stackPtr  The position of the current token in the
155
-     *                                         stack passed in $tokens.
156
-     *
157
-     * @return void
158
-     */
159
-    public function process(File $phpcsFile, $stackPtr)
160
-    {
161
-        $tokens = $phpcsFile->getTokens();
162
-
163
-        /*
30
+	/**
31
+	 * A list of keywords that can not be used as function, class and namespace name or constant name.
32
+	 * Mentions since which version it's not allowed.
33
+	 *
34
+	 * @var array(string => string)
35
+	 */
36
+	protected $invalidNames = array(
37
+		'abstract'      => '5.0',
38
+		'and'           => 'all',
39
+		'array'         => 'all',
40
+		'as'            => 'all',
41
+		'break'         => 'all',
42
+		'callable'      => '5.4',
43
+		'case'          => 'all',
44
+		'catch'         => '5.0',
45
+		'class'         => 'all',
46
+		'clone'         => '5.0',
47
+		'const'         => 'all',
48
+		'continue'      => 'all',
49
+		'declare'       => 'all',
50
+		'default'       => 'all',
51
+		'do'            => 'all',
52
+		'else'          => 'all',
53
+		'elseif'        => 'all',
54
+		'enddeclare'    => 'all',
55
+		'endfor'        => 'all',
56
+		'endforeach'    => 'all',
57
+		'endif'         => 'all',
58
+		'endswitch'     => 'all',
59
+		'endwhile'      => 'all',
60
+		'extends'       => 'all',
61
+		'final'         => '5.0',
62
+		'finally'       => '5.5',
63
+		'for'           => 'all',
64
+		'foreach'       => 'all',
65
+		'function'      => 'all',
66
+		'global'        => 'all',
67
+		'goto'          => '5.3',
68
+		'if'            => 'all',
69
+		'implements'    => '5.0',
70
+		'interface'     => '5.0',
71
+		'instanceof'    => '5.0',
72
+		'insteadof'     => '5.4',
73
+		'namespace'     => '5.3',
74
+		'new'           => 'all',
75
+		'or'            => 'all',
76
+		'private'       => '5.0',
77
+		'protected'     => '5.0',
78
+		'public'        => '5.0',
79
+		'static'        => 'all',
80
+		'switch'        => 'all',
81
+		'throw'         => '5.0',
82
+		'trait'         => '5.4',
83
+		'try'           => '5.0',
84
+		'use'           => 'all',
85
+		'var'           => 'all',
86
+		'while'         => 'all',
87
+		'xor'           => 'all',
88
+		'__class__'     => 'all',
89
+		'__dir__'       => '5.3',
90
+		'__file__'      => 'all',
91
+		'__function__'  => 'all',
92
+		'__method__'    => 'all',
93
+		'__namespace__' => '5.3',
94
+	);
95
+
96
+	/**
97
+	 * A list of keywords that can follow use statements.
98
+	 *
99
+	 * @var array(string => string)
100
+	 */
101
+	protected $validUseNames = array(
102
+		'const'    => true,
103
+		'function' => true,
104
+	);
105
+
106
+	/**
107
+	 * Scope modifiers and other keywords allowed in trait use statements.
108
+	 *
109
+	 * @var array
110
+	 */
111
+	private $allowedModifiers = array();
112
+
113
+	/**
114
+	 * Targeted tokens.
115
+	 *
116
+	 * @var array
117
+	 */
118
+	protected $targetedTokens = array(
119
+		\T_CLASS,
120
+		\T_FUNCTION,
121
+		\T_NAMESPACE,
122
+		\T_STRING,
123
+		\T_CONST,
124
+		\T_USE,
125
+		\T_AS,
126
+		\T_EXTENDS,
127
+		\T_INTERFACE,
128
+		\T_TRAIT,
129
+	);
130
+
131
+	/**
132
+	 * Returns an array of tokens this test wants to listen for.
133
+	 *
134
+	 * @return array
135
+	 */
136
+	public function register()
137
+	{
138
+		$this->allowedModifiers           = Tokens::$scopeModifiers;
139
+		$this->allowedModifiers[\T_FINAL] = \T_FINAL;
140
+
141
+		$tokens = $this->targetedTokens;
142
+
143
+		if (\defined('T_ANON_CLASS')) {
144
+			$tokens[] = \T_ANON_CLASS;
145
+		}
146
+
147
+		return $tokens;
148
+	}
149
+
150
+	/**
151
+	 * Processes this test, when one of its tokens is encountered.
152
+	 *
153
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
154
+	 * @param int                   $stackPtr  The position of the current token in the
155
+	 *                                         stack passed in $tokens.
156
+	 *
157
+	 * @return void
158
+	 */
159
+	public function process(File $phpcsFile, $stackPtr)
160
+	{
161
+		$tokens = $phpcsFile->getTokens();
162
+
163
+		/*
164 164
          * We distinguish between the class, function and namespace names vs the define statements.
165 165
          */
166
-        if ($tokens[$stackPtr]['type'] === 'T_STRING') {
167
-            $this->processString($phpcsFile, $stackPtr, $tokens);
168
-        } else {
169
-            $this->processNonString($phpcsFile, $stackPtr, $tokens);
170
-        }
171
-    }
172
-
173
-    /**
174
-     * Processes this test, when one of its tokens is encountered.
175
-     *
176
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
177
-     * @param int                   $stackPtr  The position of the current token in the
178
-     *                                         stack passed in $tokens.
179
-     * @param array                 $tokens    The stack of tokens that make up
180
-     *                                         the file.
181
-     *
182
-     * @return void
183
-     */
184
-    public function processNonString(File $phpcsFile, $stackPtr, $tokens)
185
-    {
186
-        $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
187
-        if ($nextNonEmpty === false) {
188
-            return;
189
-        }
190
-
191
-        /*
166
+		if ($tokens[$stackPtr]['type'] === 'T_STRING') {
167
+			$this->processString($phpcsFile, $stackPtr, $tokens);
168
+		} else {
169
+			$this->processNonString($phpcsFile, $stackPtr, $tokens);
170
+		}
171
+	}
172
+
173
+	/**
174
+	 * Processes this test, when one of its tokens is encountered.
175
+	 *
176
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
177
+	 * @param int                   $stackPtr  The position of the current token in the
178
+	 *                                         stack passed in $tokens.
179
+	 * @param array                 $tokens    The stack of tokens that make up
180
+	 *                                         the file.
181
+	 *
182
+	 * @return void
183
+	 */
184
+	public function processNonString(File $phpcsFile, $stackPtr, $tokens)
185
+	{
186
+		$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
187
+		if ($nextNonEmpty === false) {
188
+			return;
189
+		}
190
+
191
+		/*
192 192
          * Deal with anonymous classes - `class` before a reserved keyword is sometimes
193 193
          * misidentified as `T_ANON_CLASS`.
194 194
          * In PHPCS < 2.3.4 these were tokenized as T_CLASS no matter what.
195 195
          */
196
-        if ($tokens[$stackPtr]['type'] === 'T_ANON_CLASS' || $tokens[$stackPtr]['type'] === 'T_CLASS') {
197
-            $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
198
-            if ($prevNonEmpty !== false && $tokens[$prevNonEmpty]['type'] === 'T_NEW') {
199
-                return;
200
-            }
201
-        }
202
-
203
-        /*
196
+		if ($tokens[$stackPtr]['type'] === 'T_ANON_CLASS' || $tokens[$stackPtr]['type'] === 'T_CLASS') {
197
+			$prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
198
+			if ($prevNonEmpty !== false && $tokens[$prevNonEmpty]['type'] === 'T_NEW') {
199
+				return;
200
+			}
201
+		}
202
+
203
+		/*
204 204
          * PHP 5.6 allows for use const and use function, but only if followed by the function/constant name.
205 205
          * - `use function HelloWorld` => move to the next token (HelloWorld) to verify.
206 206
          * - `use const HelloWorld` => move to the next token (HelloWorld) to verify.
207 207
          */
208
-        elseif ($tokens[$stackPtr]['type'] === 'T_USE'
209
-            && isset($this->validUseNames[strtolower($tokens[$nextNonEmpty]['content'])]) === true
210
-        ) {
211
-            $maybeUseNext = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), null, true, null, true);
212
-            if ($maybeUseNext !== false && $this->isEndOfUseStatement($tokens[$maybeUseNext]) === false) {
213
-                $nextNonEmpty = $maybeUseNext;
214
-            }
215
-        }
216
-
217
-        /*
208
+		elseif ($tokens[$stackPtr]['type'] === 'T_USE'
209
+			&& isset($this->validUseNames[strtolower($tokens[$nextNonEmpty]['content'])]) === true
210
+		) {
211
+			$maybeUseNext = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), null, true, null, true);
212
+			if ($maybeUseNext !== false && $this->isEndOfUseStatement($tokens[$maybeUseNext]) === false) {
213
+				$nextNonEmpty = $maybeUseNext;
214
+			}
215
+		}
216
+
217
+		/*
218 218
          * Deal with visibility modifiers.
219 219
          * - `use HelloWorld { sayHello as protected; }` => valid, bow out.
220 220
          * - `use HelloWorld { sayHello as private myPrivateHello; }` => move to the next token to verify.
221 221
          */
222
-        elseif ($tokens[$stackPtr]['type'] === 'T_AS'
223
-            && isset($this->allowedModifiers[$tokens[$nextNonEmpty]['code']]) === true
224
-            && $phpcsFile->hasCondition($stackPtr, \T_USE) === true
225
-        ) {
226
-            $maybeUseNext = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), null, true, null, true);
227
-            if ($maybeUseNext === false || $this->isEndOfUseStatement($tokens[$maybeUseNext]) === true) {
228
-                return;
229
-            }
230
-
231
-            $nextNonEmpty = $maybeUseNext;
232
-        }
233
-
234
-        /*
222
+		elseif ($tokens[$stackPtr]['type'] === 'T_AS'
223
+			&& isset($this->allowedModifiers[$tokens[$nextNonEmpty]['code']]) === true
224
+			&& $phpcsFile->hasCondition($stackPtr, \T_USE) === true
225
+		) {
226
+			$maybeUseNext = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), null, true, null, true);
227
+			if ($maybeUseNext === false || $this->isEndOfUseStatement($tokens[$maybeUseNext]) === true) {
228
+				return;
229
+			}
230
+
231
+			$nextNonEmpty = $maybeUseNext;
232
+		}
233
+
234
+		/*
235 235
          * Deal with functions declared to return by reference.
236 236
          */
237
-        elseif ($tokens[$stackPtr]['type'] === 'T_FUNCTION'
238
-            && $tokens[$nextNonEmpty]['type'] === 'T_BITWISE_AND'
239
-        ) {
240
-            $maybeUseNext = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), null, true, null, true);
241
-            if ($maybeUseNext === false) {
242
-                // Live coding.
243
-                return;
244
-            }
245
-
246
-            $nextNonEmpty = $maybeUseNext;
247
-        }
248
-
249
-        /*
237
+		elseif ($tokens[$stackPtr]['type'] === 'T_FUNCTION'
238
+			&& $tokens[$nextNonEmpty]['type'] === 'T_BITWISE_AND'
239
+		) {
240
+			$maybeUseNext = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), null, true, null, true);
241
+			if ($maybeUseNext === false) {
242
+				// Live coding.
243
+				return;
244
+			}
245
+
246
+			$nextNonEmpty = $maybeUseNext;
247
+		}
248
+
249
+		/*
250 250
          * Deal with nested namespaces.
251 251
          */
252
-        elseif ($tokens[$stackPtr]['type'] === 'T_NAMESPACE') {
253
-            if ($tokens[$stackPtr + 1]['code'] === \T_NS_SEPARATOR) {
254
-                // Not a namespace declaration, but use of, i.e. namespace\someFunction();
255
-                return;
256
-            }
257
-
258
-            $endToken      = $phpcsFile->findNext(array(\T_SEMICOLON, \T_OPEN_CURLY_BRACKET), ($stackPtr + 1), null, false, null, true);
259
-            $namespaceName = trim($phpcsFile->getTokensAsString(($stackPtr + 1), ($endToken - $stackPtr - 1)));
260
-            if (empty($namespaceName) === true) {
261
-                return;
262
-            }
263
-
264
-            $namespaceParts = explode('\\', $namespaceName);
265
-            foreach ($namespaceParts as $namespacePart) {
266
-                $partLc = strtolower($namespacePart);
267
-                if (isset($this->invalidNames[$partLc]) === false) {
268
-                    continue;
269
-                }
270
-
271
-                // Find the token position of the part which matched.
272
-                for ($i = ($stackPtr + 1); $i < $endToken; $i++) {
273
-                    if ($tokens[$i]['content'] === $namespacePart) {
274
-                        $nextNonEmpty = $i;
275
-                        break;
276
-                    }
277
-                }
278
-            }
279
-            unset($i, $namespacePart, $partLc);
280
-        }
281
-
282
-        $nextContentLc = strtolower($tokens[$nextNonEmpty]['content']);
283
-        if (isset($this->invalidNames[$nextContentLc]) === false) {
284
-            return;
285
-        }
286
-
287
-        /*
252
+		elseif ($tokens[$stackPtr]['type'] === 'T_NAMESPACE') {
253
+			if ($tokens[$stackPtr + 1]['code'] === \T_NS_SEPARATOR) {
254
+				// Not a namespace declaration, but use of, i.e. namespace\someFunction();
255
+				return;
256
+			}
257
+
258
+			$endToken      = $phpcsFile->findNext(array(\T_SEMICOLON, \T_OPEN_CURLY_BRACKET), ($stackPtr + 1), null, false, null, true);
259
+			$namespaceName = trim($phpcsFile->getTokensAsString(($stackPtr + 1), ($endToken - $stackPtr - 1)));
260
+			if (empty($namespaceName) === true) {
261
+				return;
262
+			}
263
+
264
+			$namespaceParts = explode('\\', $namespaceName);
265
+			foreach ($namespaceParts as $namespacePart) {
266
+				$partLc = strtolower($namespacePart);
267
+				if (isset($this->invalidNames[$partLc]) === false) {
268
+					continue;
269
+				}
270
+
271
+				// Find the token position of the part which matched.
272
+				for ($i = ($stackPtr + 1); $i < $endToken; $i++) {
273
+					if ($tokens[$i]['content'] === $namespacePart) {
274
+						$nextNonEmpty = $i;
275
+						break;
276
+					}
277
+				}
278
+			}
279
+			unset($i, $namespacePart, $partLc);
280
+		}
281
+
282
+		$nextContentLc = strtolower($tokens[$nextNonEmpty]['content']);
283
+		if (isset($this->invalidNames[$nextContentLc]) === false) {
284
+			return;
285
+		}
286
+
287
+		/*
288 288
          * Deal with PHP 7 relaxing the rules.
289 289
          * "As of PHP 7.0.0 these keywords are allowed as property, constant, and method names
290 290
          * of classes, interfaces and traits, except that class may not be used as constant name."
291 291
          */
292
-        if ((($tokens[$stackPtr]['type'] === 'T_FUNCTION'
293
-                && $this->inClassScope($phpcsFile, $stackPtr, false) === true)
294
-            || ($tokens[$stackPtr]['type'] === 'T_CONST'
295
-                && $this->isClassConstant($phpcsFile, $stackPtr) === true
296
-                && $nextContentLc !== 'class'))
297
-            && $this->supportsBelow('5.6') === false
298
-        ) {
299
-            return;
300
-        }
301
-
302
-        if ($this->supportsAbove($this->invalidNames[$nextContentLc])) {
303
-            $data = array(
304
-                $tokens[$nextNonEmpty]['content'],
305
-                $this->invalidNames[$nextContentLc],
306
-            );
307
-            $this->addError($phpcsFile, $stackPtr, $tokens[$nextNonEmpty]['content'], $data);
308
-        }
309
-    }
310
-
311
-    /**
312
-     * Processes this test, when one of its tokens is encountered.
313
-     *
314
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
315
-     * @param int                   $stackPtr  The position of the current token in the
316
-     *                                         stack passed in $tokens.
317
-     * @param array                 $tokens    The stack of tokens that make up
318
-     *                                         the file.
319
-     *
320
-     * @return void
321
-     */
322
-    public function processString(File $phpcsFile, $stackPtr, $tokens)
323
-    {
324
-        $tokenContentLc = strtolower($tokens[$stackPtr]['content']);
325
-
326
-        /*
292
+		if ((($tokens[$stackPtr]['type'] === 'T_FUNCTION'
293
+				&& $this->inClassScope($phpcsFile, $stackPtr, false) === true)
294
+			|| ($tokens[$stackPtr]['type'] === 'T_CONST'
295
+				&& $this->isClassConstant($phpcsFile, $stackPtr) === true
296
+				&& $nextContentLc !== 'class'))
297
+			&& $this->supportsBelow('5.6') === false
298
+		) {
299
+			return;
300
+		}
301
+
302
+		if ($this->supportsAbove($this->invalidNames[$nextContentLc])) {
303
+			$data = array(
304
+				$tokens[$nextNonEmpty]['content'],
305
+				$this->invalidNames[$nextContentLc],
306
+			);
307
+			$this->addError($phpcsFile, $stackPtr, $tokens[$nextNonEmpty]['content'], $data);
308
+		}
309
+	}
310
+
311
+	/**
312
+	 * Processes this test, when one of its tokens is encountered.
313
+	 *
314
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
315
+	 * @param int                   $stackPtr  The position of the current token in the
316
+	 *                                         stack passed in $tokens.
317
+	 * @param array                 $tokens    The stack of tokens that make up
318
+	 *                                         the file.
319
+	 *
320
+	 * @return void
321
+	 */
322
+	public function processString(File $phpcsFile, $stackPtr, $tokens)
323
+	{
324
+		$tokenContentLc = strtolower($tokens[$stackPtr]['content']);
325
+
326
+		/*
327 327
          * Special case for PHP versions where the target is not yet identified as
328 328
          * its own token, but presents as T_STRING.
329 329
          * - trait keyword in PHP < 5.4
330 330
          */
331
-        if (version_compare(\PHP_VERSION_ID, '50400', '<') && $tokenContentLc === 'trait') {
332
-            $this->processNonString($phpcsFile, $stackPtr, $tokens);
333
-            return;
334
-        }
335
-
336
-        // Look for any define/defined tokens (both T_STRING ones, blame Tokenizer).
337
-        if ($tokenContentLc !== 'define' && $tokenContentLc !== 'defined') {
338
-            return;
339
-        }
340
-
341
-        // Retrieve the define(d) constant name.
342
-        $firstParam = $this->getFunctionCallParameter($phpcsFile, $stackPtr, 1);
343
-        if ($firstParam === false) {
344
-            return;
345
-        }
346
-
347
-        $defineName   = $this->stripQuotes($firstParam['raw']);
348
-        $defineNameLc = strtolower($defineName);
349
-
350
-        if (isset($this->invalidNames[$defineNameLc]) && $this->supportsAbove($this->invalidNames[$defineNameLc])) {
351
-            $data = array(
352
-                $defineName,
353
-                $this->invalidNames[$defineNameLc],
354
-            );
355
-            $this->addError($phpcsFile, $stackPtr, $defineNameLc, $data);
356
-        }
357
-    }
358
-
359
-
360
-    /**
361
-     * Add the error message.
362
-     *
363
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
364
-     * @param int                   $stackPtr  The position of the current token in the
365
-     *                                         stack passed in $tokens.
366
-     * @param string                $content   The token content found.
367
-     * @param array                 $data      The data to pass into the error message.
368
-     *
369
-     * @return void
370
-     */
371
-    protected function addError(File $phpcsFile, $stackPtr, $content, $data)
372
-    {
373
-        $error     = "Function name, class name, namespace name or constant name can not be reserved keyword '%s' (since version %s)";
374
-        $errorCode = $this->stringToErrorCode($content) . 'Found';
375
-        $phpcsFile->addError($error, $stackPtr, $errorCode, $data);
376
-    }
377
-
378
-
379
-    /**
380
-     * Check if the current token code is for a token which can be considered
381
-     * the end of a (partial) use statement.
382
-     *
383
-     * @param int $token The current token information.
384
-     *
385
-     * @return bool
386
-     */
387
-    protected function isEndOfUseStatement($token)
388
-    {
389
-        return \in_array($token['code'], array(\T_CLOSE_CURLY_BRACKET, \T_SEMICOLON, \T_COMMA), true);
390
-    }
331
+		if (version_compare(\PHP_VERSION_ID, '50400', '<') && $tokenContentLc === 'trait') {
332
+			$this->processNonString($phpcsFile, $stackPtr, $tokens);
333
+			return;
334
+		}
335
+
336
+		// Look for any define/defined tokens (both T_STRING ones, blame Tokenizer).
337
+		if ($tokenContentLc !== 'define' && $tokenContentLc !== 'defined') {
338
+			return;
339
+		}
340
+
341
+		// Retrieve the define(d) constant name.
342
+		$firstParam = $this->getFunctionCallParameter($phpcsFile, $stackPtr, 1);
343
+		if ($firstParam === false) {
344
+			return;
345
+		}
346
+
347
+		$defineName   = $this->stripQuotes($firstParam['raw']);
348
+		$defineNameLc = strtolower($defineName);
349
+
350
+		if (isset($this->invalidNames[$defineNameLc]) && $this->supportsAbove($this->invalidNames[$defineNameLc])) {
351
+			$data = array(
352
+				$defineName,
353
+				$this->invalidNames[$defineNameLc],
354
+			);
355
+			$this->addError($phpcsFile, $stackPtr, $defineNameLc, $data);
356
+		}
357
+	}
358
+
359
+
360
+	/**
361
+	 * Add the error message.
362
+	 *
363
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
364
+	 * @param int                   $stackPtr  The position of the current token in the
365
+	 *                                         stack passed in $tokens.
366
+	 * @param string                $content   The token content found.
367
+	 * @param array                 $data      The data to pass into the error message.
368
+	 *
369
+	 * @return void
370
+	 */
371
+	protected function addError(File $phpcsFile, $stackPtr, $content, $data)
372
+	{
373
+		$error     = "Function name, class name, namespace name or constant name can not be reserved keyword '%s' (since version %s)";
374
+		$errorCode = $this->stringToErrorCode($content) . 'Found';
375
+		$phpcsFile->addError($error, $stackPtr, $errorCode, $data);
376
+	}
377
+
378
+
379
+	/**
380
+	 * Check if the current token code is for a token which can be considered
381
+	 * the end of a (partial) use statement.
382
+	 *
383
+	 * @param int $token The current token information.
384
+	 *
385
+	 * @return bool
386
+	 */
387
+	protected function isEndOfUseStatement($token)
388
+	{
389
+		return \in_array($token['code'], array(\T_CLOSE_CURLY_BRACKET, \T_SEMICOLON, \T_COMMA), true);
390
+	}
391 391
 }
Please login to merge, or discard this patch.
Sniffs/ControlStructures/DiscouragedSwitchContinueSniff.php 1 patch
Indentation   +191 added lines, -191 removed lines patch added patch discarded remove patch
@@ -29,195 +29,195 @@
 block discarded – undo
29 29
 class DiscouragedSwitchContinueSniff extends Sniff
30 30
 {
31 31
 
32
-    /**
33
-     * Token codes of control structures which can be targeted using continue.
34
-     *
35
-     * @var array
36
-     */
37
-    protected $loopStructures = array(
38
-        \T_FOR     => \T_FOR,
39
-        \T_FOREACH => \T_FOREACH,
40
-        \T_WHILE   => \T_WHILE,
41
-        \T_DO      => \T_DO,
42
-        \T_SWITCH  => \T_SWITCH,
43
-    );
44
-
45
-    /**
46
-     * Tokens which start a new case within a switch.
47
-     *
48
-     * @var array
49
-     */
50
-    protected $caseTokens = array(
51
-        \T_CASE    => \T_CASE,
52
-        \T_DEFAULT => \T_DEFAULT,
53
-    );
54
-
55
-    /**
56
-     * Token codes which are accepted to determine the level for the continue.
57
-     *
58
-     * This array is enriched with the arithmetic operators in the register() method.
59
-     *
60
-     * @var array
61
-     */
62
-    protected $acceptedLevelTokens = array(
63
-        \T_LNUMBER           => \T_LNUMBER,
64
-        \T_OPEN_PARENTHESIS  => \T_OPEN_PARENTHESIS,
65
-        \T_CLOSE_PARENTHESIS => \T_CLOSE_PARENTHESIS,
66
-    );
67
-
68
-
69
-    /**
70
-     * Returns an array of tokens this test wants to listen for.
71
-     *
72
-     * @return array
73
-     */
74
-    public function register()
75
-    {
76
-        $this->acceptedLevelTokens += Tokens::$arithmeticTokens;
77
-        $this->acceptedLevelTokens += Tokens::$emptyTokens;
78
-
79
-        return array(\T_SWITCH);
80
-    }
81
-
82
-    /**
83
-     * Processes this test, when one of its tokens is encountered.
84
-     *
85
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
86
-     * @param int                   $stackPtr  The position of the current token in the
87
-     *                                         stack passed in $tokens.
88
-     *
89
-     * @return void
90
-     */
91
-    public function process(File $phpcsFile, $stackPtr)
92
-    {
93
-        if ($this->supportsAbove('7.3') === false) {
94
-            return;
95
-        }
96
-
97
-        $tokens = $phpcsFile->getTokens();
98
-
99
-        if (isset($tokens[$stackPtr]['scope_opener'], $tokens[$stackPtr]['scope_closer']) === false) {
100
-            return;
101
-        }
102
-
103
-        $switchOpener = $tokens[$stackPtr]['scope_opener'];
104
-        $switchCloser = $tokens[$stackPtr]['scope_closer'];
105
-
106
-        // Quick check whether we need to bother with the more complex logic.
107
-        $hasContinue = $phpcsFile->findNext(\T_CONTINUE, ($switchOpener + 1), $switchCloser);
108
-        if ($hasContinue === false) {
109
-            return;
110
-        }
111
-
112
-        $caseDefault = $switchOpener;
113
-
114
-        do {
115
-            $caseDefault = $phpcsFile->findNext($this->caseTokens, ($caseDefault + 1), $switchCloser);
116
-            if ($caseDefault === false) {
117
-                break;
118
-            }
119
-
120
-            if (isset($tokens[$caseDefault]['scope_opener']) === false) {
121
-                // Unknown start of the case, skip.
122
-                continue;
123
-            }
124
-
125
-            $caseOpener      = $tokens[$caseDefault]['scope_opener'];
126
-            $nextCaseDefault = $phpcsFile->findNext($this->caseTokens, ($caseDefault + 1), $switchCloser);
127
-            if ($nextCaseDefault === false) {
128
-                $caseCloser = $switchCloser;
129
-            } else {
130
-                $caseCloser = $nextCaseDefault;
131
-            }
132
-
133
-            // Check for unscoped control structures within the case.
134
-            $controlStructure = $caseOpener;
135
-            $doCount          = 0;
136
-            while (($controlStructure = $phpcsFile->findNext($this->loopStructures, ($controlStructure + 1), $caseCloser)) !== false) {
137
-                if ($tokens[$controlStructure]['code'] === \T_DO) {
138
-                    $doCount++;
139
-                }
140
-
141
-                if (isset($tokens[$controlStructure]['scope_opener'], $tokens[$controlStructure]['scope_closer']) === false) {
142
-                    if ($tokens[$controlStructure]['code'] === \T_WHILE && $doCount > 0) {
143
-                        // While in a do-while construct.
144
-                        $doCount--;
145
-                        continue;
146
-                    }
147
-
148
-                    // Control structure without braces found within the case, ignore this case.
149
-                    continue 2;
150
-                }
151
-            }
152
-
153
-            // Examine the contents of the case.
154
-            $continue = $caseOpener;
155
-
156
-            do {
157
-                $continue = $phpcsFile->findNext(\T_CONTINUE, ($continue + 1), $caseCloser);
158
-                if ($continue === false) {
159
-                    break;
160
-                }
161
-
162
-                $nextSemicolon = $phpcsFile->findNext(array(\T_SEMICOLON, \T_CLOSE_TAG), ($continue + 1), $caseCloser);
163
-                $codeString    = '';
164
-                for ($i = ($continue + 1); $i < $nextSemicolon; $i++) {
165
-                    if (isset($this->acceptedLevelTokens[$tokens[$i]['code']]) === false) {
166
-                        // Function call/variable or other token which make numeric level impossible to determine.
167
-                        continue 2;
168
-                    }
169
-
170
-                    if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === true) {
171
-                        continue;
172
-                    }
173
-
174
-                    $codeString .= $tokens[$i]['content'];
175
-                }
176
-
177
-                $level = null;
178
-                if ($codeString !== '') {
179
-                    if (is_numeric($codeString)) {
180
-                        $level = (int) $codeString;
181
-                    } else {
182
-                        // With the above logic, the string can only contain digits and operators, eval!
183
-                        $level = eval("return ( $codeString );");
184
-                    }
185
-                }
186
-
187
-                if (isset($level) === false || $level === 0) {
188
-                    $level = 1;
189
-                }
190
-
191
-                // Examine which control structure is being targeted by the continue statement.
192
-                if (isset($tokens[$continue]['conditions']) === false) {
193
-                    continue;
194
-                }
195
-
196
-                $conditions = array_reverse($tokens[$continue]['conditions'], true);
197
-                // PHPCS adds more structures to the conditions array than we want to take into
198
-                // consideration, so clean up the array.
199
-                foreach ($conditions as $tokenPtr => $tokenCode) {
200
-                    if (isset($this->loopStructures[$tokenCode]) === false) {
201
-                        unset($conditions[$tokenPtr]);
202
-                    }
203
-                }
204
-
205
-                $targetCondition = \array_slice($conditions, ($level - 1), 1, true);
206
-                if (empty($targetCondition)) {
207
-                    continue;
208
-                }
209
-
210
-                $conditionToken = key($targetCondition);
211
-                if ($conditionToken === $stackPtr) {
212
-                    $phpcsFile->addWarning(
213
-                        "Targeting a 'switch' control structure with a 'continue' statement is strongly discouraged and will throw a warning as of PHP 7.3.",
214
-                        $continue,
215
-                        'Found'
216
-                    );
217
-                }
218
-
219
-            } while ($continue < $caseCloser);
220
-
221
-        } while ($caseDefault < $switchCloser);
222
-    }
32
+	/**
33
+	 * Token codes of control structures which can be targeted using continue.
34
+	 *
35
+	 * @var array
36
+	 */
37
+	protected $loopStructures = array(
38
+		\T_FOR     => \T_FOR,
39
+		\T_FOREACH => \T_FOREACH,
40
+		\T_WHILE   => \T_WHILE,
41
+		\T_DO      => \T_DO,
42
+		\T_SWITCH  => \T_SWITCH,
43
+	);
44
+
45
+	/**
46
+	 * Tokens which start a new case within a switch.
47
+	 *
48
+	 * @var array
49
+	 */
50
+	protected $caseTokens = array(
51
+		\T_CASE    => \T_CASE,
52
+		\T_DEFAULT => \T_DEFAULT,
53
+	);
54
+
55
+	/**
56
+	 * Token codes which are accepted to determine the level for the continue.
57
+	 *
58
+	 * This array is enriched with the arithmetic operators in the register() method.
59
+	 *
60
+	 * @var array
61
+	 */
62
+	protected $acceptedLevelTokens = array(
63
+		\T_LNUMBER           => \T_LNUMBER,
64
+		\T_OPEN_PARENTHESIS  => \T_OPEN_PARENTHESIS,
65
+		\T_CLOSE_PARENTHESIS => \T_CLOSE_PARENTHESIS,
66
+	);
67
+
68
+
69
+	/**
70
+	 * Returns an array of tokens this test wants to listen for.
71
+	 *
72
+	 * @return array
73
+	 */
74
+	public function register()
75
+	{
76
+		$this->acceptedLevelTokens += Tokens::$arithmeticTokens;
77
+		$this->acceptedLevelTokens += Tokens::$emptyTokens;
78
+
79
+		return array(\T_SWITCH);
80
+	}
81
+
82
+	/**
83
+	 * Processes this test, when one of its tokens is encountered.
84
+	 *
85
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
86
+	 * @param int                   $stackPtr  The position of the current token in the
87
+	 *                                         stack passed in $tokens.
88
+	 *
89
+	 * @return void
90
+	 */
91
+	public function process(File $phpcsFile, $stackPtr)
92
+	{
93
+		if ($this->supportsAbove('7.3') === false) {
94
+			return;
95
+		}
96
+
97
+		$tokens = $phpcsFile->getTokens();
98
+
99
+		if (isset($tokens[$stackPtr]['scope_opener'], $tokens[$stackPtr]['scope_closer']) === false) {
100
+			return;
101
+		}
102
+
103
+		$switchOpener = $tokens[$stackPtr]['scope_opener'];
104
+		$switchCloser = $tokens[$stackPtr]['scope_closer'];
105
+
106
+		// Quick check whether we need to bother with the more complex logic.
107
+		$hasContinue = $phpcsFile->findNext(\T_CONTINUE, ($switchOpener + 1), $switchCloser);
108
+		if ($hasContinue === false) {
109
+			return;
110
+		}
111
+
112
+		$caseDefault = $switchOpener;
113
+
114
+		do {
115
+			$caseDefault = $phpcsFile->findNext($this->caseTokens, ($caseDefault + 1), $switchCloser);
116
+			if ($caseDefault === false) {
117
+				break;
118
+			}
119
+
120
+			if (isset($tokens[$caseDefault]['scope_opener']) === false) {
121
+				// Unknown start of the case, skip.
122
+				continue;
123
+			}
124
+
125
+			$caseOpener      = $tokens[$caseDefault]['scope_opener'];
126
+			$nextCaseDefault = $phpcsFile->findNext($this->caseTokens, ($caseDefault + 1), $switchCloser);
127
+			if ($nextCaseDefault === false) {
128
+				$caseCloser = $switchCloser;
129
+			} else {
130
+				$caseCloser = $nextCaseDefault;
131
+			}
132
+
133
+			// Check for unscoped control structures within the case.
134
+			$controlStructure = $caseOpener;
135
+			$doCount          = 0;
136
+			while (($controlStructure = $phpcsFile->findNext($this->loopStructures, ($controlStructure + 1), $caseCloser)) !== false) {
137
+				if ($tokens[$controlStructure]['code'] === \T_DO) {
138
+					$doCount++;
139
+				}
140
+
141
+				if (isset($tokens[$controlStructure]['scope_opener'], $tokens[$controlStructure]['scope_closer']) === false) {
142
+					if ($tokens[$controlStructure]['code'] === \T_WHILE && $doCount > 0) {
143
+						// While in a do-while construct.
144
+						$doCount--;
145
+						continue;
146
+					}
147
+
148
+					// Control structure without braces found within the case, ignore this case.
149
+					continue 2;
150
+				}
151
+			}
152
+
153
+			// Examine the contents of the case.
154
+			$continue = $caseOpener;
155
+
156
+			do {
157
+				$continue = $phpcsFile->findNext(\T_CONTINUE, ($continue + 1), $caseCloser);
158
+				if ($continue === false) {
159
+					break;
160
+				}
161
+
162
+				$nextSemicolon = $phpcsFile->findNext(array(\T_SEMICOLON, \T_CLOSE_TAG), ($continue + 1), $caseCloser);
163
+				$codeString    = '';
164
+				for ($i = ($continue + 1); $i < $nextSemicolon; $i++) {
165
+					if (isset($this->acceptedLevelTokens[$tokens[$i]['code']]) === false) {
166
+						// Function call/variable or other token which make numeric level impossible to determine.
167
+						continue 2;
168
+					}
169
+
170
+					if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === true) {
171
+						continue;
172
+					}
173
+
174
+					$codeString .= $tokens[$i]['content'];
175
+				}
176
+
177
+				$level = null;
178
+				if ($codeString !== '') {
179
+					if (is_numeric($codeString)) {
180
+						$level = (int) $codeString;
181
+					} else {
182
+						// With the above logic, the string can only contain digits and operators, eval!
183
+						$level = eval("return ( $codeString );");
184
+					}
185
+				}
186
+
187
+				if (isset($level) === false || $level === 0) {
188
+					$level = 1;
189
+				}
190
+
191
+				// Examine which control structure is being targeted by the continue statement.
192
+				if (isset($tokens[$continue]['conditions']) === false) {
193
+					continue;
194
+				}
195
+
196
+				$conditions = array_reverse($tokens[$continue]['conditions'], true);
197
+				// PHPCS adds more structures to the conditions array than we want to take into
198
+				// consideration, so clean up the array.
199
+				foreach ($conditions as $tokenPtr => $tokenCode) {
200
+					if (isset($this->loopStructures[$tokenCode]) === false) {
201
+						unset($conditions[$tokenPtr]);
202
+					}
203
+				}
204
+
205
+				$targetCondition = \array_slice($conditions, ($level - 1), 1, true);
206
+				if (empty($targetCondition)) {
207
+					continue;
208
+				}
209
+
210
+				$conditionToken = key($targetCondition);
211
+				if ($conditionToken === $stackPtr) {
212
+					$phpcsFile->addWarning(
213
+						"Targeting a 'switch' control structure with a 'continue' statement is strongly discouraged and will throw a warning as of PHP 7.3.",
214
+						$continue,
215
+						'Found'
216
+					);
217
+				}
218
+
219
+			} while ($continue < $caseCloser);
220
+
221
+		} while ($caseDefault < $switchCloser);
222
+	}
223 223
 }
Please login to merge, or discard this patch.
Sniffs/ControlStructures/ForbiddenBreakContinueVariableArgumentsSniff.php 1 patch
Indentation   +61 added lines, -61 removed lines patch added patch discarded remove patch
@@ -30,72 +30,72 @@
 block discarded – undo
30 30
  */
31 31
 class ForbiddenBreakContinueVariableArgumentsSniff extends Sniff
32 32
 {
33
-    /**
34
-     * Error types this sniff handles for forbidden break/continue arguments.
35
-     *
36
-     * Array key is the error code. Array value will be used as part of the error message.
37
-     *
38
-     * @var array
39
-     */
40
-    private $errorTypes = array(
41
-        'variableArgument' => 'a variable argument',
42
-        'zeroArgument'     => '0 as an argument',
43
-    );
33
+	/**
34
+	 * Error types this sniff handles for forbidden break/continue arguments.
35
+	 *
36
+	 * Array key is the error code. Array value will be used as part of the error message.
37
+	 *
38
+	 * @var array
39
+	 */
40
+	private $errorTypes = array(
41
+		'variableArgument' => 'a variable argument',
42
+		'zeroArgument'     => '0 as an argument',
43
+	);
44 44
 
45
-    /**
46
-     * Returns an array of tokens this test wants to listen for.
47
-     *
48
-     * @return array
49
-     */
50
-    public function register()
51
-    {
52
-        return array(\T_BREAK, \T_CONTINUE);
53
-    }
45
+	/**
46
+	 * Returns an array of tokens this test wants to listen for.
47
+	 *
48
+	 * @return array
49
+	 */
50
+	public function register()
51
+	{
52
+		return array(\T_BREAK, \T_CONTINUE);
53
+	}
54 54
 
55
-    /**
56
-     * Processes this test, when one of its tokens is encountered.
57
-     *
58
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
59
-     * @param int                   $stackPtr  The position of the current token in the
60
-     *                                         stack passed in $tokens.
61
-     *
62
-     * @return void
63
-     */
64
-    public function process(File $phpcsFile, $stackPtr)
65
-    {
66
-        if ($this->supportsAbove('5.4') === false) {
67
-            return;
68
-        }
55
+	/**
56
+	 * Processes this test, when one of its tokens is encountered.
57
+	 *
58
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
59
+	 * @param int                   $stackPtr  The position of the current token in the
60
+	 *                                         stack passed in $tokens.
61
+	 *
62
+	 * @return void
63
+	 */
64
+	public function process(File $phpcsFile, $stackPtr)
65
+	{
66
+		if ($this->supportsAbove('5.4') === false) {
67
+			return;
68
+		}
69 69
 
70
-        $tokens             = $phpcsFile->getTokens();
71
-        $nextSemicolonToken = $phpcsFile->findNext(array(\T_SEMICOLON, \T_CLOSE_TAG), ($stackPtr), null, false);
72
-        $errorType          = '';
73
-        for ($curToken = $stackPtr + 1; $curToken < $nextSemicolonToken; $curToken++) {
74
-            if ($tokens[$curToken]['type'] === 'T_STRING') {
75
-                // If the next non-whitespace token after the string
76
-                // is an opening parenthesis then it's a function call.
77
-                $openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, $curToken + 1, null, true);
78
-                if ($tokens[$openBracket]['code'] === \T_OPEN_PARENTHESIS) {
79
-                    $errorType = 'variableArgument';
80
-                    break;
81
-                }
70
+		$tokens             = $phpcsFile->getTokens();
71
+		$nextSemicolonToken = $phpcsFile->findNext(array(\T_SEMICOLON, \T_CLOSE_TAG), ($stackPtr), null, false);
72
+		$errorType          = '';
73
+		for ($curToken = $stackPtr + 1; $curToken < $nextSemicolonToken; $curToken++) {
74
+			if ($tokens[$curToken]['type'] === 'T_STRING') {
75
+				// If the next non-whitespace token after the string
76
+				// is an opening parenthesis then it's a function call.
77
+				$openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, $curToken + 1, null, true);
78
+				if ($tokens[$openBracket]['code'] === \T_OPEN_PARENTHESIS) {
79
+					$errorType = 'variableArgument';
80
+					break;
81
+				}
82 82
 
83
-            } elseif (\in_array($tokens[$curToken]['type'], array('T_VARIABLE', 'T_FUNCTION', 'T_CLOSURE'), true)) {
84
-                $errorType = 'variableArgument';
85
-                break;
83
+			} elseif (\in_array($tokens[$curToken]['type'], array('T_VARIABLE', 'T_FUNCTION', 'T_CLOSURE'), true)) {
84
+				$errorType = 'variableArgument';
85
+				break;
86 86
 
87
-            } elseif ($tokens[$curToken]['type'] === 'T_LNUMBER' && $tokens[$curToken]['content'] === '0') {
88
-                $errorType = 'zeroArgument';
89
-                break;
90
-            }
91
-        }
87
+			} elseif ($tokens[$curToken]['type'] === 'T_LNUMBER' && $tokens[$curToken]['content'] === '0') {
88
+				$errorType = 'zeroArgument';
89
+				break;
90
+			}
91
+		}
92 92
 
93
-        if ($errorType !== '') {
94
-            $error     = 'Using %s on break or continue is forbidden since PHP 5.4';
95
-            $errorCode = $errorType . 'Found';
96
-            $data      = array($this->errorTypes[$errorType]);
93
+		if ($errorType !== '') {
94
+			$error     = 'Using %s on break or continue is forbidden since PHP 5.4';
95
+			$errorCode = $errorType . 'Found';
96
+			$data      = array($this->errorTypes[$errorType]);
97 97
 
98
-            $phpcsFile->addError($error, $stackPtr, $errorCode, $data);
99
-        }
100
-    }
98
+			$phpcsFile->addError($error, $stackPtr, $errorCode, $data);
99
+		}
100
+	}
101 101
 }
Please login to merge, or discard this patch.
Sniffs/ControlStructures/ForbiddenSwitchWithMultipleDefaultBlocksSniff.php 1 patch
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -28,52 +28,52 @@
 block discarded – undo
28 28
 class ForbiddenSwitchWithMultipleDefaultBlocksSniff extends Sniff
29 29
 {
30 30
 
31
-    /**
32
-     * Returns an array of tokens this test wants to listen for.
33
-     *
34
-     * @return array
35
-     */
36
-    public function register()
37
-    {
38
-        return array(\T_SWITCH);
39
-    }
31
+	/**
32
+	 * Returns an array of tokens this test wants to listen for.
33
+	 *
34
+	 * @return array
35
+	 */
36
+	public function register()
37
+	{
38
+		return array(\T_SWITCH);
39
+	}
40 40
 
41
-    /**
42
-     * Processes this test, when one of its tokens is encountered.
43
-     *
44
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
45
-     * @param int                   $stackPtr  The position of the current token
46
-     *                                         in the stack passed in $tokens.
47
-     *
48
-     * @return void
49
-     */
50
-    public function process(File $phpcsFile, $stackPtr)
51
-    {
52
-        if ($this->supportsAbove('7.0') === false) {
53
-            return;
54
-        }
41
+	/**
42
+	 * Processes this test, when one of its tokens is encountered.
43
+	 *
44
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
45
+	 * @param int                   $stackPtr  The position of the current token
46
+	 *                                         in the stack passed in $tokens.
47
+	 *
48
+	 * @return void
49
+	 */
50
+	public function process(File $phpcsFile, $stackPtr)
51
+	{
52
+		if ($this->supportsAbove('7.0') === false) {
53
+			return;
54
+		}
55 55
 
56
-        $tokens = $phpcsFile->getTokens();
57
-        if (isset($tokens[$stackPtr]['scope_closer']) === false) {
58
-            return;
59
-        }
56
+		$tokens = $phpcsFile->getTokens();
57
+		if (isset($tokens[$stackPtr]['scope_closer']) === false) {
58
+			return;
59
+		}
60 60
 
61
-        $defaultToken = $stackPtr;
62
-        $defaultCount = 0;
63
-        $targetLevel  = $tokens[$stackPtr]['level'] + 1;
64
-        while ($defaultCount < 2 && ($defaultToken = $phpcsFile->findNext(array(\T_DEFAULT), $defaultToken + 1, $tokens[$stackPtr]['scope_closer'])) !== false) {
65
-            // Same level or one below (= two default cases after each other).
66
-            if ($tokens[$defaultToken]['level'] === $targetLevel || $tokens[$defaultToken]['level'] === ($targetLevel + 1)) {
67
-                $defaultCount++;
68
-            }
69
-        }
61
+		$defaultToken = $stackPtr;
62
+		$defaultCount = 0;
63
+		$targetLevel  = $tokens[$stackPtr]['level'] + 1;
64
+		while ($defaultCount < 2 && ($defaultToken = $phpcsFile->findNext(array(\T_DEFAULT), $defaultToken + 1, $tokens[$stackPtr]['scope_closer'])) !== false) {
65
+			// Same level or one below (= two default cases after each other).
66
+			if ($tokens[$defaultToken]['level'] === $targetLevel || $tokens[$defaultToken]['level'] === ($targetLevel + 1)) {
67
+				$defaultCount++;
68
+			}
69
+		}
70 70
 
71
-        if ($defaultCount > 1) {
72
-            $phpcsFile->addError(
73
-                'Switch statements can not have multiple default blocks since PHP 7.0',
74
-                $stackPtr,
75
-                'Found'
76
-            );
77
-        }
78
-    }
71
+		if ($defaultCount > 1) {
72
+			$phpcsFile->addError(
73
+				'Switch statements can not have multiple default blocks since PHP 7.0',
74
+				$stackPtr,
75
+				'Found'
76
+			);
77
+		}
78
+	}
79 79
 }
Please login to merge, or discard this patch.