Completed
Pull Request — develop (#1492)
by Zack
28:58 queued 09:00
created
includes/class-gravityview-powered-by.php 1 patch
Indentation   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@
 block discarded – undo
69 69
 
70 70
 		$url = add_query_arg( array(
71 71
 			'utm_source' => 'powered_by',
72
-            'utm_term' => get_bloginfo('name' ),
72
+			'utm_term' => get_bloginfo('name' ),
73 73
 		), $url );
74 74
 
75 75
 		/**
Please login to merge, or discard this patch.
includes/fields/class-gravityview-field-textarea.php 1 patch
Indentation   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -39,13 +39,13 @@
 block discarded – undo
39 39
 			'tooltip' => __( 'Enter the number of words to be shown. If specified it truncates the text. Leave it blank if you want to show the full text.', 'gravityview' ),
40 40
 		);
41 41
 
42
-        $field_options['make_clickable'] = array(
43
-            'type' => 'checkbox',
44
-            'merge_tags' => false,
45
-            'value' => 0,
46
-            'label' => __( 'Convert text URLs to HTML links', 'gravityview' ),
47
-            'tooltip' => __( 'Converts URI, www, FTP, and email addresses in HTML links', 'gravityview' ),
48
-        );
42
+		$field_options['make_clickable'] = array(
43
+			'type' => 'checkbox',
44
+			'merge_tags' => false,
45
+			'value' => 0,
46
+			'label' => __( 'Convert text URLs to HTML links', 'gravityview' ),
47
+			'tooltip' => __( 'Converts URI, www, FTP, and email addresses in HTML links', 'gravityview' ),
48
+		);
49 49
 
50 50
 		$field_options['allow_html'] = array(
51 51
 			'type' => 'checkbox',
Please login to merge, or discard this patch.
vendor/phpcompatibility/php-compatibility/PHPCompatibility/Sniff.php 1 patch
Indentation   +2036 added lines, -2036 removed lines patch added patch discarded remove patch
@@ -27,959 +27,959 @@  discard block
 block discarded – undo
27 27
 abstract class Sniff implements PHPCS_Sniff
28 28
 {
29 29
 
30
-    const REGEX_COMPLEX_VARS = '`(?:(\{)?(?<!\\\\)\$)?(\{)?(?<!\\\\)\$(\{)?(?P<varname>[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(?:->\$?(?P>varname)|\[[^\]]+\]|::\$?(?P>varname)|\([^\)]*\))*(?(3)\}|)(?(2)\}|)(?(1)\}|)`';
31
-
32
-    /**
33
-     * List of superglobals as an array of strings.
34
-     *
35
-     * Used by the ParameterShadowSuperGlobals and ForbiddenClosureUseVariableNames sniffs.
36
-     *
37
-     * @var array
38
-     */
39
-    protected $superglobals = array(
40
-        '$GLOBALS'  => true,
41
-        '$_SERVER'  => true,
42
-        '$_GET'     => true,
43
-        '$_POST'    => true,
44
-        '$_FILES'   => true,
45
-        '$_COOKIE'  => true,
46
-        '$_SESSION' => true,
47
-        '$_REQUEST' => true,
48
-        '$_ENV'     => true,
49
-    );
50
-
51
-    /**
52
-     * List of functions using hash algorithm as parameter (always the first parameter).
53
-     *
54
-     * Used by the new/removed hash algorithm sniffs.
55
-     * Key is the function name, value is the 1-based parameter position in the function call.
56
-     *
57
-     * @var array
58
-     */
59
-    protected $hashAlgoFunctions = array(
60
-        'hash_file'      => 1,
61
-        'hash_hmac_file' => 1,
62
-        'hash_hmac'      => 1,
63
-        'hash_init'      => 1,
64
-        'hash_pbkdf2'    => 1,
65
-        'hash'           => 1,
66
-    );
67
-
68
-
69
-    /**
70
-     * List of functions which take an ini directive as parameter (always the first parameter).
71
-     *
72
-     * Used by the new/removed ini directives sniffs.
73
-     * Key is the function name, value is the 1-based parameter position in the function call.
74
-     *
75
-     * @var array
76
-     */
77
-    protected $iniFunctions = array(
78
-        'ini_get' => 1,
79
-        'ini_set' => 1,
80
-    );
81
-
82
-
83
-    /**
84
-     * Get the testVersion configuration variable.
85
-     *
86
-     * The testVersion configuration variable may be in any of the following formats:
87
-     * 1) Omitted/empty, in which case no version is specified. This effectively
88
-     *    disables all the checks for new PHP features provided by this standard.
89
-     * 2) A single PHP version number, e.g. "5.4" in which case the standard checks that
90
-     *    the code will run on that version of PHP (no deprecated features or newer
91
-     *    features being used).
92
-     * 3) A range, e.g. "5.0-5.5", in which case the standard checks the code will run
93
-     *    on all PHP versions in that range, and that it doesn't use any features that
94
-     *    were deprecated by the final version in the list, or which were not available
95
-     *    for the first version in the list.
96
-     *    We accept ranges where one of the components is missing, e.g. "-5.6" means
97
-     *    all versions up to PHP 5.6, and "7.0-" means all versions above PHP 7.0.
98
-     * PHP version numbers should always be in Major.Minor format.  Both "5", "5.3.2"
99
-     * would be treated as invalid, and ignored.
100
-     *
101
-     * @return array $arrTestVersions will hold an array containing min/max version
102
-     *               of PHP that we are checking against (see above).  If only a
103
-     *               single version number is specified, then this is used as
104
-     *               both the min and max.
105
-     *
106
-     * @throws \PHP_CodeSniffer_Exception If testVersion is invalid.
107
-     */
108
-    private function getTestVersion()
109
-    {
110
-        static $arrTestVersions = array();
111
-
112
-        $default     = array(null, null);
113
-        $testVersion = trim(PHPCSHelper::getConfigData('testVersion'));
114
-
115
-        if (empty($testVersion) === false && isset($arrTestVersions[$testVersion]) === false) {
116
-
117
-            $arrTestVersions[$testVersion] = $default;
118
-
119
-            if (preg_match('`^\d+\.\d+$`', $testVersion)) {
120
-                $arrTestVersions[$testVersion] = array($testVersion, $testVersion);
121
-                return $arrTestVersions[$testVersion];
122
-            }
123
-
124
-            if (preg_match('`^(\d+\.\d+)?\s*-\s*(\d+\.\d+)?$`', $testVersion, $matches)) {
125
-                if (empty($matches[1]) === false || empty($matches[2]) === false) {
126
-                    // If no lower-limit is set, we set the min version to 4.0.
127
-                    // Whilst development focuses on PHP 5 and above, we also accept
128
-                    // sniffs for PHP 4, so we include that as the minimum.
129
-                    // (It makes no sense to support PHP 3 as this was effectively a
130
-                    // different language).
131
-                    $min = empty($matches[1]) ? '4.0' : $matches[1];
132
-
133
-                    // If no upper-limit is set, we set the max version to 99.9.
134
-                    $max = empty($matches[2]) ? '99.9' : $matches[2];
135
-
136
-                    if (version_compare($min, $max, '>')) {
137
-                        trigger_error(
138
-                            "Invalid range in testVersion setting: '" . $testVersion . "'",
139
-                            \E_USER_WARNING
140
-                        );
141
-                        return $default;
142
-                    } else {
143
-                        $arrTestVersions[$testVersion] = array($min, $max);
144
-                        return $arrTestVersions[$testVersion];
145
-                    }
146
-                }
147
-            }
148
-
149
-            trigger_error(
150
-                "Invalid testVersion setting: '" . $testVersion . "'",
151
-                \E_USER_WARNING
152
-            );
153
-            return $default;
154
-        }
155
-
156
-        if (isset($arrTestVersions[$testVersion])) {
157
-            return $arrTestVersions[$testVersion];
158
-        }
159
-
160
-        return $default;
161
-    }
162
-
163
-
164
-    /**
165
-     * Check whether a specific PHP version is equal to or higher than the maximum
166
-     * supported PHP version as provided by the user in `testVersion`.
167
-     *
168
-     * Should be used when sniffing for *old* PHP features (deprecated/removed).
169
-     *
170
-     * @param string $phpVersion A PHP version number in 'major.minor' format.
171
-     *
172
-     * @return bool True if testVersion has not been provided or if the PHP version
173
-     *              is equal to or higher than the highest supported PHP version
174
-     *              in testVersion. False otherwise.
175
-     */
176
-    public function supportsAbove($phpVersion)
177
-    {
178
-        $testVersion = $this->getTestVersion();
179
-        $testVersion = $testVersion[1];
180
-
181
-        if (\is_null($testVersion)
182
-            || version_compare($testVersion, $phpVersion) >= 0
183
-        ) {
184
-            return true;
185
-        } else {
186
-            return false;
187
-        }
188
-    }
189
-
190
-
191
-    /**
192
-     * Check whether a specific PHP version is equal to or lower than the minimum
193
-     * supported PHP version as provided by the user in `testVersion`.
194
-     *
195
-     * Should be used when sniffing for *new* PHP features.
196
-     *
197
-     * @param string $phpVersion A PHP version number in 'major.minor' format.
198
-     *
199
-     * @return bool True if the PHP version is equal to or lower than the lowest
200
-     *              supported PHP version in testVersion.
201
-     *              False otherwise or if no testVersion is provided.
202
-     */
203
-    public function supportsBelow($phpVersion)
204
-    {
205
-        $testVersion = $this->getTestVersion();
206
-        $testVersion = $testVersion[0];
207
-
208
-        if (\is_null($testVersion) === false
209
-            && version_compare($testVersion, $phpVersion) <= 0
210
-        ) {
211
-            return true;
212
-        } else {
213
-            return false;
214
-        }
215
-    }
216
-
217
-
218
-    /**
219
-     * Add a PHPCS message to the output stack as either a warning or an error.
220
-     *
221
-     * @param \PHP_CodeSniffer_File $phpcsFile The file the message applies to.
222
-     * @param string                $message   The message.
223
-     * @param int                   $stackPtr  The position of the token
224
-     *                                         the message relates to.
225
-     * @param bool                  $isError   Whether to report the message as an
226
-     *                                         'error' or 'warning'.
227
-     *                                         Defaults to true (error).
228
-     * @param string                $code      The error code for the message.
229
-     *                                         Defaults to 'Found'.
230
-     * @param array                 $data      Optional input for the data replacements.
231
-     *
232
-     * @return void
233
-     */
234
-    public function addMessage(File $phpcsFile, $message, $stackPtr, $isError, $code = 'Found', $data = array())
235
-    {
236
-        if ($isError === true) {
237
-            $phpcsFile->addError($message, $stackPtr, $code, $data);
238
-        } else {
239
-            $phpcsFile->addWarning($message, $stackPtr, $code, $data);
240
-        }
241
-    }
242
-
243
-
244
-    /**
245
-     * Convert an arbitrary string to an alphanumeric string with underscores.
246
-     *
247
-     * Pre-empt issues with arbitrary strings being used as error codes in XML and PHP.
248
-     *
249
-     * @param string $baseString Arbitrary string.
250
-     *
251
-     * @return string
252
-     */
253
-    public function stringToErrorCode($baseString)
254
-    {
255
-        return preg_replace('`[^a-z0-9_]`i', '_', strtolower($baseString));
256
-    }
257
-
258
-
259
-    /**
260
-     * Strip quotes surrounding an arbitrary string.
261
-     *
262
-     * Intended for use with the contents of a T_CONSTANT_ENCAPSED_STRING / T_DOUBLE_QUOTED_STRING.
263
-     *
264
-     * @param string $string The raw string.
265
-     *
266
-     * @return string String without quotes around it.
267
-     */
268
-    public function stripQuotes($string)
269
-    {
270
-        return preg_replace('`^([\'"])(.*)\1$`Ds', '$2', $string);
271
-    }
272
-
273
-
274
-    /**
275
-     * Strip variables from an arbitrary double quoted string.
276
-     *
277
-     * Intended for use with the contents of a T_DOUBLE_QUOTED_STRING.
278
-     *
279
-     * @param string $string The raw string.
280
-     *
281
-     * @return string String without variables in it.
282
-     */
283
-    public function stripVariables($string)
284
-    {
285
-        if (strpos($string, '$') === false) {
286
-            return $string;
287
-        }
288
-
289
-        return preg_replace(self::REGEX_COMPLEX_VARS, '', $string);
290
-    }
291
-
292
-
293
-    /**
294
-     * Make all top level array keys in an array lowercase.
295
-     *
296
-     * @param array $array Initial array.
297
-     *
298
-     * @return array Same array, but with all lowercase top level keys.
299
-     */
300
-    public function arrayKeysToLowercase($array)
301
-    {
302
-        return array_change_key_case($array, \CASE_LOWER);
303
-    }
304
-
305
-
306
-    /**
307
-     * Checks if a function call has parameters.
308
-     *
309
-     * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
310
-     * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
311
-     *
312
-     * Extra feature: If passed an T_ARRAY or T_OPEN_SHORT_ARRAY stack pointer, it
313
-     * will detect whether the array has values or is empty.
314
-     *
315
-     * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/120
316
-     * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/152
317
-     *
318
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
319
-     * @param int                   $stackPtr  The position of the function call token.
320
-     *
321
-     * @return bool
322
-     */
323
-    public function doesFunctionCallHaveParameters(File $phpcsFile, $stackPtr)
324
-    {
325
-        $tokens = $phpcsFile->getTokens();
326
-
327
-        // Check for the existence of the token.
328
-        if (isset($tokens[$stackPtr]) === false) {
329
-            return false;
330
-        }
331
-
332
-        // Is this one of the tokens this function handles ?
333
-        if (\in_array($tokens[$stackPtr]['code'], array(\T_STRING, \T_ARRAY, \T_OPEN_SHORT_ARRAY, \T_VARIABLE), true) === false) {
334
-            return false;
335
-        }
336
-
337
-        $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
338
-
339
-        // Deal with short array syntax.
340
-        if ($tokens[$stackPtr]['code'] === \T_OPEN_SHORT_ARRAY) {
341
-            if (isset($tokens[$stackPtr]['bracket_closer']) === false) {
342
-                return false;
343
-            }
344
-
345
-            if ($nextNonEmpty === $tokens[$stackPtr]['bracket_closer']) {
346
-                // No parameters.
347
-                return false;
348
-            } else {
349
-                return true;
350
-            }
351
-        }
352
-
353
-        // Deal with function calls & long arrays.
354
-        // Next non-empty token should be the open parenthesis.
355
-        if ($nextNonEmpty === false && $tokens[$nextNonEmpty]['code'] !== \T_OPEN_PARENTHESIS) {
356
-            return false;
357
-        }
358
-
359
-        if (isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false) {
360
-            return false;
361
-        }
362
-
363
-        $closeParenthesis = $tokens[$nextNonEmpty]['parenthesis_closer'];
364
-        $nextNextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $nextNonEmpty + 1, $closeParenthesis + 1, true);
365
-
366
-        if ($nextNextNonEmpty === $closeParenthesis) {
367
-            // No parameters.
368
-            return false;
369
-        }
370
-
371
-        return true;
372
-    }
373
-
374
-
375
-    /**
376
-     * Count the number of parameters a function call has been passed.
377
-     *
378
-     * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
379
-     * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
380
-     *
381
-     * Extra feature: If passed an T_ARRAY or T_OPEN_SHORT_ARRAY stack pointer,
382
-     * it will return the number of values in the array.
383
-     *
384
-     * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/111
385
-     * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/114
386
-     * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/151
387
-     *
388
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
389
-     * @param int                   $stackPtr  The position of the function call token.
390
-     *
391
-     * @return int
392
-     */
393
-    public function getFunctionCallParameterCount(File $phpcsFile, $stackPtr)
394
-    {
395
-        if ($this->doesFunctionCallHaveParameters($phpcsFile, $stackPtr) === false) {
396
-            return 0;
397
-        }
398
-
399
-        return \count($this->getFunctionCallParameters($phpcsFile, $stackPtr));
400
-    }
401
-
402
-
403
-    /**
404
-     * Get information on all parameters passed to a function call.
405
-     *
406
-     * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
407
-     * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
408
-     *
409
-     * Will return an multi-dimentional array with the start token pointer, end token
410
-     * pointer and raw parameter value for all parameters. Index will be 1-based.
411
-     * If no parameters are found, will return an empty array.
412
-     *
413
-     * Extra feature: If passed an T_ARRAY or T_OPEN_SHORT_ARRAY stack pointer,
414
-     * it will tokenize the values / key/value pairs contained in the array call.
415
-     *
416
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
417
-     * @param int                   $stackPtr  The position of the function call token.
418
-     *
419
-     * @return array
420
-     */
421
-    public function getFunctionCallParameters(File $phpcsFile, $stackPtr)
422
-    {
423
-        if ($this->doesFunctionCallHaveParameters($phpcsFile, $stackPtr) === false) {
424
-            return array();
425
-        }
426
-
427
-        // Ok, we know we have a T_STRING, T_VARIABLE, T_ARRAY or T_OPEN_SHORT_ARRAY with parameters
428
-        // and valid open & close brackets/parenthesis.
429
-        $tokens = $phpcsFile->getTokens();
430
-
431
-        // Mark the beginning and end tokens.
432
-        if ($tokens[$stackPtr]['code'] === \T_OPEN_SHORT_ARRAY) {
433
-            $opener = $stackPtr;
434
-            $closer = $tokens[$stackPtr]['bracket_closer'];
435
-
436
-            $nestedParenthesisCount = 0;
437
-
438
-        } else {
439
-            $opener = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
440
-            $closer = $tokens[$opener]['parenthesis_closer'];
441
-
442
-            $nestedParenthesisCount = 1;
443
-        }
444
-
445
-        // Which nesting level is the one we are interested in ?
446
-        if (isset($tokens[$opener]['nested_parenthesis'])) {
447
-            $nestedParenthesisCount += \count($tokens[$opener]['nested_parenthesis']);
448
-        }
449
-
450
-        $parameters = array();
451
-        $nextComma  = $opener;
452
-        $paramStart = $opener + 1;
453
-        $cnt        = 1;
454
-        while (($nextComma = $phpcsFile->findNext(array(\T_COMMA, $tokens[$closer]['code'], \T_OPEN_SHORT_ARRAY, \T_CLOSURE), $nextComma + 1, $closer + 1)) !== false) {
455
-            // Ignore anything within short array definition brackets.
456
-            if ($tokens[$nextComma]['type'] === 'T_OPEN_SHORT_ARRAY'
457
-                && (isset($tokens[$nextComma]['bracket_opener'])
458
-                    && $tokens[$nextComma]['bracket_opener'] === $nextComma)
459
-                && isset($tokens[$nextComma]['bracket_closer'])
460
-            ) {
461
-                // Skip forward to the end of the short array definition.
462
-                $nextComma = $tokens[$nextComma]['bracket_closer'];
463
-                continue;
464
-            }
465
-
466
-            // Skip past closures passed as function parameters.
467
-            if ($tokens[$nextComma]['type'] === 'T_CLOSURE'
468
-                && (isset($tokens[$nextComma]['scope_condition'])
469
-                    && $tokens[$nextComma]['scope_condition'] === $nextComma)
470
-                && isset($tokens[$nextComma]['scope_closer'])
471
-            ) {
472
-                // Skip forward to the end of the closure declaration.
473
-                $nextComma = $tokens[$nextComma]['scope_closer'];
474
-                continue;
475
-            }
476
-
477
-            // Ignore comma's at a lower nesting level.
478
-            if ($tokens[$nextComma]['type'] === 'T_COMMA'
479
-                && isset($tokens[$nextComma]['nested_parenthesis'])
480
-                && \count($tokens[$nextComma]['nested_parenthesis']) !== $nestedParenthesisCount
481
-            ) {
482
-                continue;
483
-            }
484
-
485
-            // Ignore closing parenthesis/bracket if not 'ours'.
486
-            if ($tokens[$nextComma]['type'] === $tokens[$closer]['type'] && $nextComma !== $closer) {
487
-                continue;
488
-            }
489
-
490
-            // Ok, we've reached the end of the parameter.
491
-            $parameters[$cnt]['start'] = $paramStart;
492
-            $parameters[$cnt]['end']   = $nextComma - 1;
493
-            $parameters[$cnt]['raw']   = trim($phpcsFile->getTokensAsString($paramStart, ($nextComma - $paramStart)));
494
-
495
-            // Check if there are more tokens before the closing parenthesis.
496
-            // Prevents code like the following from setting a third parameter:
497
-            // functionCall( $param1, $param2, );
498
-            $hasNextParam = $phpcsFile->findNext(Tokens::$emptyTokens, $nextComma + 1, $closer, true, null, true);
499
-            if ($hasNextParam === false) {
500
-                break;
501
-            }
502
-
503
-            // Prepare for the next parameter.
504
-            $paramStart = $nextComma + 1;
505
-            $cnt++;
506
-        }
507
-
508
-        return $parameters;
509
-    }
510
-
511
-
512
-    /**
513
-     * Get information on a specific parameter passed to a function call.
514
-     *
515
-     * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
516
-     * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
517
-     *
518
-     * Will return a array with the start token pointer, end token pointer and the raw value
519
-     * of the parameter at a specific offset.
520
-     * If the specified parameter is not found, will return false.
521
-     *
522
-     * @param \PHP_CodeSniffer_File $phpcsFile   The file being scanned.
523
-     * @param int                   $stackPtr    The position of the function call token.
524
-     * @param int                   $paramOffset The 1-based index position of the parameter to retrieve.
525
-     *
526
-     * @return array|false
527
-     */
528
-    public function getFunctionCallParameter(File $phpcsFile, $stackPtr, $paramOffset)
529
-    {
530
-        $parameters = $this->getFunctionCallParameters($phpcsFile, $stackPtr);
531
-
532
-        if (isset($parameters[$paramOffset]) === false) {
533
-            return false;
534
-        } else {
535
-            return $parameters[$paramOffset];
536
-        }
537
-    }
538
-
539
-
540
-    /**
541
-     * Verify whether a token is within a scoped condition.
542
-     *
543
-     * If the optional $validScopes parameter has been passed, the function
544
-     * will check that the token has at least one condition which is of a
545
-     * type defined in $validScopes.
546
-     *
547
-     * @param \PHP_CodeSniffer_File $phpcsFile   The file being scanned.
548
-     * @param int                   $stackPtr    The position of the token.
549
-     * @param array|int             $validScopes Optional. Array of valid scopes
550
-     *                                           or int value of a valid scope.
551
-     *                                           Pass the T_.. constant(s) for the
552
-     *                                           desired scope to this parameter.
553
-     *
554
-     * @return bool Without the optional $scopeTypes: True if within a scope, false otherwise.
555
-     *              If the $scopeTypes are set: True if *one* of the conditions is a
556
-     *              valid scope, false otherwise.
557
-     */
558
-    public function tokenHasScope(File $phpcsFile, $stackPtr, $validScopes = null)
559
-    {
560
-        $tokens = $phpcsFile->getTokens();
561
-
562
-        // Check for the existence of the token.
563
-        if (isset($tokens[$stackPtr]) === false) {
564
-            return false;
565
-        }
566
-
567
-        // No conditions = no scope.
568
-        if (empty($tokens[$stackPtr]['conditions'])) {
569
-            return false;
570
-        }
571
-
572
-        // Ok, there are conditions, do we have to check for specific ones ?
573
-        if (isset($validScopes) === false) {
574
-            return true;
575
-        }
576
-
577
-        return $phpcsFile->hasCondition($stackPtr, $validScopes);
578
-    }
579
-
580
-
581
-    /**
582
-     * Verify whether a token is within a class scope.
583
-     *
584
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
585
-     * @param int                   $stackPtr  The position of the token.
586
-     * @param bool                  $strict    Whether to strictly check for the T_CLASS
587
-     *                                         scope or also accept interfaces and traits
588
-     *                                         as scope.
589
-     *
590
-     * @return bool True if within class scope, false otherwise.
591
-     */
592
-    public function inClassScope(File $phpcsFile, $stackPtr, $strict = true)
593
-    {
594
-        $validScopes = array(\T_CLASS);
595
-        if (\defined('T_ANON_CLASS') === true) {
596
-            $validScopes[] = \T_ANON_CLASS;
597
-        }
598
-
599
-        if ($strict === false) {
600
-            $validScopes[] = \T_INTERFACE;
601
-            $validScopes[] = \T_TRAIT;
602
-        }
603
-
604
-        return $phpcsFile->hasCondition($stackPtr, $validScopes);
605
-    }
606
-
607
-
608
-    /**
609
-     * Returns the fully qualified class name for a new class instantiation.
610
-     *
611
-     * Returns an empty string if the class name could not be reliably inferred.
612
-     *
613
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
614
-     * @param int                   $stackPtr  The position of a T_NEW token.
615
-     *
616
-     * @return string
617
-     */
618
-    public function getFQClassNameFromNewToken(File $phpcsFile, $stackPtr)
619
-    {
620
-        $tokens = $phpcsFile->getTokens();
621
-
622
-        // Check for the existence of the token.
623
-        if (isset($tokens[$stackPtr]) === false) {
624
-            return '';
625
-        }
626
-
627
-        if ($tokens[$stackPtr]['code'] !== \T_NEW) {
628
-            return '';
629
-        }
630
-
631
-        $start = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
632
-        if ($start === false) {
633
-            return '';
634
-        }
635
-
636
-        // Bow out if the next token is a variable as we don't know where it was defined.
637
-        if ($tokens[$start]['code'] === \T_VARIABLE) {
638
-            return '';
639
-        }
640
-
641
-        // Bow out if the next token is the class keyword.
642
-        if ($tokens[$start]['type'] === 'T_ANON_CLASS' || $tokens[$start]['code'] === \T_CLASS) {
643
-            return '';
644
-        }
645
-
646
-        $find = array(
647
-            \T_NS_SEPARATOR,
648
-            \T_STRING,
649
-            \T_NAMESPACE,
650
-            \T_WHITESPACE,
651
-        );
652
-
653
-        $end       = $phpcsFile->findNext($find, ($start + 1), null, true, null, true);
654
-        $className = $phpcsFile->getTokensAsString($start, ($end - $start));
655
-        $className = trim($className);
656
-
657
-        return $this->getFQName($phpcsFile, $stackPtr, $className);
658
-    }
659
-
660
-
661
-    /**
662
-     * Returns the fully qualified name of the class that the specified class extends.
663
-     *
664
-     * Returns an empty string if the class does not extend another class or if
665
-     * the class name could not be reliably inferred.
666
-     *
667
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
668
-     * @param int                   $stackPtr  The position of a T_CLASS token.
669
-     *
670
-     * @return string
671
-     */
672
-    public function getFQExtendedClassName(File $phpcsFile, $stackPtr)
673
-    {
674
-        $tokens = $phpcsFile->getTokens();
675
-
676
-        // Check for the existence of the token.
677
-        if (isset($tokens[$stackPtr]) === false) {
678
-            return '';
679
-        }
680
-
681
-        if ($tokens[$stackPtr]['code'] !== \T_CLASS
682
-            && $tokens[$stackPtr]['type'] !== 'T_ANON_CLASS'
683
-            && $tokens[$stackPtr]['type'] !== 'T_INTERFACE'
684
-        ) {
685
-            return '';
686
-        }
687
-
688
-        $extends = PHPCSHelper::findExtendedClassName($phpcsFile, $stackPtr);
689
-        if (empty($extends) || \is_string($extends) === false) {
690
-            return '';
691
-        }
692
-
693
-        return $this->getFQName($phpcsFile, $stackPtr, $extends);
694
-    }
695
-
696
-
697
-    /**
698
-     * Returns the class name for the static usage of a class.
699
-     * This can be a call to a method, the use of a property or constant.
700
-     *
701
-     * Returns an empty string if the class name could not be reliably inferred.
702
-     *
703
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
704
-     * @param int                   $stackPtr  The position of a T_NEW token.
705
-     *
706
-     * @return string
707
-     */
708
-    public function getFQClassNameFromDoubleColonToken(File $phpcsFile, $stackPtr)
709
-    {
710
-        $tokens = $phpcsFile->getTokens();
711
-
712
-        // Check for the existence of the token.
713
-        if (isset($tokens[$stackPtr]) === false) {
714
-            return '';
715
-        }
716
-
717
-        if ($tokens[$stackPtr]['code'] !== \T_DOUBLE_COLON) {
718
-            return '';
719
-        }
720
-
721
-        // Nothing to do if previous token is a variable as we don't know where it was defined.
722
-        if ($tokens[$stackPtr - 1]['code'] === \T_VARIABLE) {
723
-            return '';
724
-        }
725
-
726
-        // Nothing to do if 'parent' or 'static' as we don't know how far the class tree extends.
727
-        if (\in_array($tokens[$stackPtr - 1]['code'], array(\T_PARENT, \T_STATIC), true)) {
728
-            return '';
729
-        }
730
-
731
-        // Get the classname from the class declaration if self is used.
732
-        if ($tokens[$stackPtr - 1]['code'] === \T_SELF) {
733
-            $classDeclarationPtr = $phpcsFile->findPrevious(\T_CLASS, $stackPtr - 1);
734
-            if ($classDeclarationPtr === false) {
735
-                return '';
736
-            }
737
-            $className = $phpcsFile->getDeclarationName($classDeclarationPtr);
738
-            return $this->getFQName($phpcsFile, $classDeclarationPtr, $className);
739
-        }
740
-
741
-        $find = array(
742
-            \T_NS_SEPARATOR,
743
-            \T_STRING,
744
-            \T_NAMESPACE,
745
-            \T_WHITESPACE,
746
-        );
747
-
748
-        $start = $phpcsFile->findPrevious($find, $stackPtr - 1, null, true, null, true);
749
-        if ($start === false || isset($tokens[($start + 1)]) === false) {
750
-            return '';
751
-        }
752
-
753
-        $start     = ($start + 1);
754
-        $className = $phpcsFile->getTokensAsString($start, ($stackPtr - $start));
755
-        $className = trim($className);
756
-
757
-        return $this->getFQName($phpcsFile, $stackPtr, $className);
758
-    }
759
-
760
-
761
-    /**
762
-     * Get the Fully Qualified name for a class/function/constant etc.
763
-     *
764
-     * Checks if a class/function/constant name is already fully qualified and
765
-     * if not, enrich it with the relevant namespace information.
766
-     *
767
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
768
-     * @param int                   $stackPtr  The position of the token.
769
-     * @param string                $name      The class / function / constant name.
770
-     *
771
-     * @return string
772
-     */
773
-    public function getFQName(File $phpcsFile, $stackPtr, $name)
774
-    {
775
-        if (strpos($name, '\\') === 0) {
776
-            // Already fully qualified.
777
-            return $name;
778
-        }
779
-
780
-        // Remove the namespace keyword if used.
781
-        if (strpos($name, 'namespace\\') === 0) {
782
-            $name = substr($name, 10);
783
-        }
784
-
785
-        $namespace = $this->determineNamespace($phpcsFile, $stackPtr);
786
-
787
-        if ($namespace === '') {
788
-            return '\\' . $name;
789
-        } else {
790
-            return '\\' . $namespace . '\\' . $name;
791
-        }
792
-    }
793
-
794
-
795
-    /**
796
-     * Is the class/function/constant name namespaced or global ?
797
-     *
798
-     * @param string $FQName Fully Qualified name of a class, function etc.
799
-     *                       I.e. should always start with a `\`.
800
-     *
801
-     * @return bool True if namespaced, false if global.
802
-     */
803
-    public function isNamespaced($FQName)
804
-    {
805
-        if (strpos($FQName, '\\') !== 0) {
806
-            throw new PHPCS_Exception('$FQName must be a fully qualified name');
807
-        }
808
-
809
-        return (strpos(substr($FQName, 1), '\\') !== false);
810
-    }
811
-
812
-
813
-    /**
814
-     * Determine the namespace name an arbitrary token lives in.
815
-     *
816
-     * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
817
-     * @param int                   $stackPtr  The token position for which to determine the namespace.
818
-     *
819
-     * @return string Namespace name or empty string if it couldn't be determined or no namespace applies.
820
-     */
821
-    public function determineNamespace(File $phpcsFile, $stackPtr)
822
-    {
823
-        $tokens = $phpcsFile->getTokens();
824
-
825
-        // Check for the existence of the token.
826
-        if (isset($tokens[$stackPtr]) === false) {
827
-            return '';
828
-        }
829
-
830
-        // Check for scoped namespace {}.
831
-        if (empty($tokens[$stackPtr]['conditions']) === false) {
832
-            $namespacePtr = $phpcsFile->getCondition($stackPtr, \T_NAMESPACE);
833
-            if ($namespacePtr !== false) {
834
-                $namespace = $this->getDeclaredNamespaceName($phpcsFile, $namespacePtr);
835
-                if ($namespace !== false) {
836
-                    return $namespace;
837
-                }
838
-
839
-                // We are in a scoped namespace, but couldn't determine the name. Searching for a global namespace is futile.
840
-                return '';
841
-            }
842
-        }
843
-
844
-        /*
30
+	const REGEX_COMPLEX_VARS = '`(?:(\{)?(?<!\\\\)\$)?(\{)?(?<!\\\\)\$(\{)?(?P<varname>[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)(?:->\$?(?P>varname)|\[[^\]]+\]|::\$?(?P>varname)|\([^\)]*\))*(?(3)\}|)(?(2)\}|)(?(1)\}|)`';
31
+
32
+	/**
33
+	 * List of superglobals as an array of strings.
34
+	 *
35
+	 * Used by the ParameterShadowSuperGlobals and ForbiddenClosureUseVariableNames sniffs.
36
+	 *
37
+	 * @var array
38
+	 */
39
+	protected $superglobals = array(
40
+		'$GLOBALS'  => true,
41
+		'$_SERVER'  => true,
42
+		'$_GET'     => true,
43
+		'$_POST'    => true,
44
+		'$_FILES'   => true,
45
+		'$_COOKIE'  => true,
46
+		'$_SESSION' => true,
47
+		'$_REQUEST' => true,
48
+		'$_ENV'     => true,
49
+	);
50
+
51
+	/**
52
+	 * List of functions using hash algorithm as parameter (always the first parameter).
53
+	 *
54
+	 * Used by the new/removed hash algorithm sniffs.
55
+	 * Key is the function name, value is the 1-based parameter position in the function call.
56
+	 *
57
+	 * @var array
58
+	 */
59
+	protected $hashAlgoFunctions = array(
60
+		'hash_file'      => 1,
61
+		'hash_hmac_file' => 1,
62
+		'hash_hmac'      => 1,
63
+		'hash_init'      => 1,
64
+		'hash_pbkdf2'    => 1,
65
+		'hash'           => 1,
66
+	);
67
+
68
+
69
+	/**
70
+	 * List of functions which take an ini directive as parameter (always the first parameter).
71
+	 *
72
+	 * Used by the new/removed ini directives sniffs.
73
+	 * Key is the function name, value is the 1-based parameter position in the function call.
74
+	 *
75
+	 * @var array
76
+	 */
77
+	protected $iniFunctions = array(
78
+		'ini_get' => 1,
79
+		'ini_set' => 1,
80
+	);
81
+
82
+
83
+	/**
84
+	 * Get the testVersion configuration variable.
85
+	 *
86
+	 * The testVersion configuration variable may be in any of the following formats:
87
+	 * 1) Omitted/empty, in which case no version is specified. This effectively
88
+	 *    disables all the checks for new PHP features provided by this standard.
89
+	 * 2) A single PHP version number, e.g. "5.4" in which case the standard checks that
90
+	 *    the code will run on that version of PHP (no deprecated features or newer
91
+	 *    features being used).
92
+	 * 3) A range, e.g. "5.0-5.5", in which case the standard checks the code will run
93
+	 *    on all PHP versions in that range, and that it doesn't use any features that
94
+	 *    were deprecated by the final version in the list, or which were not available
95
+	 *    for the first version in the list.
96
+	 *    We accept ranges where one of the components is missing, e.g. "-5.6" means
97
+	 *    all versions up to PHP 5.6, and "7.0-" means all versions above PHP 7.0.
98
+	 * PHP version numbers should always be in Major.Minor format.  Both "5", "5.3.2"
99
+	 * would be treated as invalid, and ignored.
100
+	 *
101
+	 * @return array $arrTestVersions will hold an array containing min/max version
102
+	 *               of PHP that we are checking against (see above).  If only a
103
+	 *               single version number is specified, then this is used as
104
+	 *               both the min and max.
105
+	 *
106
+	 * @throws \PHP_CodeSniffer_Exception If testVersion is invalid.
107
+	 */
108
+	private function getTestVersion()
109
+	{
110
+		static $arrTestVersions = array();
111
+
112
+		$default     = array(null, null);
113
+		$testVersion = trim(PHPCSHelper::getConfigData('testVersion'));
114
+
115
+		if (empty($testVersion) === false && isset($arrTestVersions[$testVersion]) === false) {
116
+
117
+			$arrTestVersions[$testVersion] = $default;
118
+
119
+			if (preg_match('`^\d+\.\d+$`', $testVersion)) {
120
+				$arrTestVersions[$testVersion] = array($testVersion, $testVersion);
121
+				return $arrTestVersions[$testVersion];
122
+			}
123
+
124
+			if (preg_match('`^(\d+\.\d+)?\s*-\s*(\d+\.\d+)?$`', $testVersion, $matches)) {
125
+				if (empty($matches[1]) === false || empty($matches[2]) === false) {
126
+					// If no lower-limit is set, we set the min version to 4.0.
127
+					// Whilst development focuses on PHP 5 and above, we also accept
128
+					// sniffs for PHP 4, so we include that as the minimum.
129
+					// (It makes no sense to support PHP 3 as this was effectively a
130
+					// different language).
131
+					$min = empty($matches[1]) ? '4.0' : $matches[1];
132
+
133
+					// If no upper-limit is set, we set the max version to 99.9.
134
+					$max = empty($matches[2]) ? '99.9' : $matches[2];
135
+
136
+					if (version_compare($min, $max, '>')) {
137
+						trigger_error(
138
+							"Invalid range in testVersion setting: '" . $testVersion . "'",
139
+							\E_USER_WARNING
140
+						);
141
+						return $default;
142
+					} else {
143
+						$arrTestVersions[$testVersion] = array($min, $max);
144
+						return $arrTestVersions[$testVersion];
145
+					}
146
+				}
147
+			}
148
+
149
+			trigger_error(
150
+				"Invalid testVersion setting: '" . $testVersion . "'",
151
+				\E_USER_WARNING
152
+			);
153
+			return $default;
154
+		}
155
+
156
+		if (isset($arrTestVersions[$testVersion])) {
157
+			return $arrTestVersions[$testVersion];
158
+		}
159
+
160
+		return $default;
161
+	}
162
+
163
+
164
+	/**
165
+	 * Check whether a specific PHP version is equal to or higher than the maximum
166
+	 * supported PHP version as provided by the user in `testVersion`.
167
+	 *
168
+	 * Should be used when sniffing for *old* PHP features (deprecated/removed).
169
+	 *
170
+	 * @param string $phpVersion A PHP version number in 'major.minor' format.
171
+	 *
172
+	 * @return bool True if testVersion has not been provided or if the PHP version
173
+	 *              is equal to or higher than the highest supported PHP version
174
+	 *              in testVersion. False otherwise.
175
+	 */
176
+	public function supportsAbove($phpVersion)
177
+	{
178
+		$testVersion = $this->getTestVersion();
179
+		$testVersion = $testVersion[1];
180
+
181
+		if (\is_null($testVersion)
182
+			|| version_compare($testVersion, $phpVersion) >= 0
183
+		) {
184
+			return true;
185
+		} else {
186
+			return false;
187
+		}
188
+	}
189
+
190
+
191
+	/**
192
+	 * Check whether a specific PHP version is equal to or lower than the minimum
193
+	 * supported PHP version as provided by the user in `testVersion`.
194
+	 *
195
+	 * Should be used when sniffing for *new* PHP features.
196
+	 *
197
+	 * @param string $phpVersion A PHP version number in 'major.minor' format.
198
+	 *
199
+	 * @return bool True if the PHP version is equal to or lower than the lowest
200
+	 *              supported PHP version in testVersion.
201
+	 *              False otherwise or if no testVersion is provided.
202
+	 */
203
+	public function supportsBelow($phpVersion)
204
+	{
205
+		$testVersion = $this->getTestVersion();
206
+		$testVersion = $testVersion[0];
207
+
208
+		if (\is_null($testVersion) === false
209
+			&& version_compare($testVersion, $phpVersion) <= 0
210
+		) {
211
+			return true;
212
+		} else {
213
+			return false;
214
+		}
215
+	}
216
+
217
+
218
+	/**
219
+	 * Add a PHPCS message to the output stack as either a warning or an error.
220
+	 *
221
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file the message applies to.
222
+	 * @param string                $message   The message.
223
+	 * @param int                   $stackPtr  The position of the token
224
+	 *                                         the message relates to.
225
+	 * @param bool                  $isError   Whether to report the message as an
226
+	 *                                         'error' or 'warning'.
227
+	 *                                         Defaults to true (error).
228
+	 * @param string                $code      The error code for the message.
229
+	 *                                         Defaults to 'Found'.
230
+	 * @param array                 $data      Optional input for the data replacements.
231
+	 *
232
+	 * @return void
233
+	 */
234
+	public function addMessage(File $phpcsFile, $message, $stackPtr, $isError, $code = 'Found', $data = array())
235
+	{
236
+		if ($isError === true) {
237
+			$phpcsFile->addError($message, $stackPtr, $code, $data);
238
+		} else {
239
+			$phpcsFile->addWarning($message, $stackPtr, $code, $data);
240
+		}
241
+	}
242
+
243
+
244
+	/**
245
+	 * Convert an arbitrary string to an alphanumeric string with underscores.
246
+	 *
247
+	 * Pre-empt issues with arbitrary strings being used as error codes in XML and PHP.
248
+	 *
249
+	 * @param string $baseString Arbitrary string.
250
+	 *
251
+	 * @return string
252
+	 */
253
+	public function stringToErrorCode($baseString)
254
+	{
255
+		return preg_replace('`[^a-z0-9_]`i', '_', strtolower($baseString));
256
+	}
257
+
258
+
259
+	/**
260
+	 * Strip quotes surrounding an arbitrary string.
261
+	 *
262
+	 * Intended for use with the contents of a T_CONSTANT_ENCAPSED_STRING / T_DOUBLE_QUOTED_STRING.
263
+	 *
264
+	 * @param string $string The raw string.
265
+	 *
266
+	 * @return string String without quotes around it.
267
+	 */
268
+	public function stripQuotes($string)
269
+	{
270
+		return preg_replace('`^([\'"])(.*)\1$`Ds', '$2', $string);
271
+	}
272
+
273
+
274
+	/**
275
+	 * Strip variables from an arbitrary double quoted string.
276
+	 *
277
+	 * Intended for use with the contents of a T_DOUBLE_QUOTED_STRING.
278
+	 *
279
+	 * @param string $string The raw string.
280
+	 *
281
+	 * @return string String without variables in it.
282
+	 */
283
+	public function stripVariables($string)
284
+	{
285
+		if (strpos($string, '$') === false) {
286
+			return $string;
287
+		}
288
+
289
+		return preg_replace(self::REGEX_COMPLEX_VARS, '', $string);
290
+	}
291
+
292
+
293
+	/**
294
+	 * Make all top level array keys in an array lowercase.
295
+	 *
296
+	 * @param array $array Initial array.
297
+	 *
298
+	 * @return array Same array, but with all lowercase top level keys.
299
+	 */
300
+	public function arrayKeysToLowercase($array)
301
+	{
302
+		return array_change_key_case($array, \CASE_LOWER);
303
+	}
304
+
305
+
306
+	/**
307
+	 * Checks if a function call has parameters.
308
+	 *
309
+	 * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
310
+	 * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
311
+	 *
312
+	 * Extra feature: If passed an T_ARRAY or T_OPEN_SHORT_ARRAY stack pointer, it
313
+	 * will detect whether the array has values or is empty.
314
+	 *
315
+	 * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/120
316
+	 * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/152
317
+	 *
318
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
319
+	 * @param int                   $stackPtr  The position of the function call token.
320
+	 *
321
+	 * @return bool
322
+	 */
323
+	public function doesFunctionCallHaveParameters(File $phpcsFile, $stackPtr)
324
+	{
325
+		$tokens = $phpcsFile->getTokens();
326
+
327
+		// Check for the existence of the token.
328
+		if (isset($tokens[$stackPtr]) === false) {
329
+			return false;
330
+		}
331
+
332
+		// Is this one of the tokens this function handles ?
333
+		if (\in_array($tokens[$stackPtr]['code'], array(\T_STRING, \T_ARRAY, \T_OPEN_SHORT_ARRAY, \T_VARIABLE), true) === false) {
334
+			return false;
335
+		}
336
+
337
+		$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
338
+
339
+		// Deal with short array syntax.
340
+		if ($tokens[$stackPtr]['code'] === \T_OPEN_SHORT_ARRAY) {
341
+			if (isset($tokens[$stackPtr]['bracket_closer']) === false) {
342
+				return false;
343
+			}
344
+
345
+			if ($nextNonEmpty === $tokens[$stackPtr]['bracket_closer']) {
346
+				// No parameters.
347
+				return false;
348
+			} else {
349
+				return true;
350
+			}
351
+		}
352
+
353
+		// Deal with function calls & long arrays.
354
+		// Next non-empty token should be the open parenthesis.
355
+		if ($nextNonEmpty === false && $tokens[$nextNonEmpty]['code'] !== \T_OPEN_PARENTHESIS) {
356
+			return false;
357
+		}
358
+
359
+		if (isset($tokens[$nextNonEmpty]['parenthesis_closer']) === false) {
360
+			return false;
361
+		}
362
+
363
+		$closeParenthesis = $tokens[$nextNonEmpty]['parenthesis_closer'];
364
+		$nextNextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $nextNonEmpty + 1, $closeParenthesis + 1, true);
365
+
366
+		if ($nextNextNonEmpty === $closeParenthesis) {
367
+			// No parameters.
368
+			return false;
369
+		}
370
+
371
+		return true;
372
+	}
373
+
374
+
375
+	/**
376
+	 * Count the number of parameters a function call has been passed.
377
+	 *
378
+	 * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
379
+	 * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
380
+	 *
381
+	 * Extra feature: If passed an T_ARRAY or T_OPEN_SHORT_ARRAY stack pointer,
382
+	 * it will return the number of values in the array.
383
+	 *
384
+	 * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/111
385
+	 * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/114
386
+	 * @link https://github.com/PHPCompatibility/PHPCompatibility/issues/151
387
+	 *
388
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
389
+	 * @param int                   $stackPtr  The position of the function call token.
390
+	 *
391
+	 * @return int
392
+	 */
393
+	public function getFunctionCallParameterCount(File $phpcsFile, $stackPtr)
394
+	{
395
+		if ($this->doesFunctionCallHaveParameters($phpcsFile, $stackPtr) === false) {
396
+			return 0;
397
+		}
398
+
399
+		return \count($this->getFunctionCallParameters($phpcsFile, $stackPtr));
400
+	}
401
+
402
+
403
+	/**
404
+	 * Get information on all parameters passed to a function call.
405
+	 *
406
+	 * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
407
+	 * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
408
+	 *
409
+	 * Will return an multi-dimentional array with the start token pointer, end token
410
+	 * pointer and raw parameter value for all parameters. Index will be 1-based.
411
+	 * If no parameters are found, will return an empty array.
412
+	 *
413
+	 * Extra feature: If passed an T_ARRAY or T_OPEN_SHORT_ARRAY stack pointer,
414
+	 * it will tokenize the values / key/value pairs contained in the array call.
415
+	 *
416
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
417
+	 * @param int                   $stackPtr  The position of the function call token.
418
+	 *
419
+	 * @return array
420
+	 */
421
+	public function getFunctionCallParameters(File $phpcsFile, $stackPtr)
422
+	{
423
+		if ($this->doesFunctionCallHaveParameters($phpcsFile, $stackPtr) === false) {
424
+			return array();
425
+		}
426
+
427
+		// Ok, we know we have a T_STRING, T_VARIABLE, T_ARRAY or T_OPEN_SHORT_ARRAY with parameters
428
+		// and valid open & close brackets/parenthesis.
429
+		$tokens = $phpcsFile->getTokens();
430
+
431
+		// Mark the beginning and end tokens.
432
+		if ($tokens[$stackPtr]['code'] === \T_OPEN_SHORT_ARRAY) {
433
+			$opener = $stackPtr;
434
+			$closer = $tokens[$stackPtr]['bracket_closer'];
435
+
436
+			$nestedParenthesisCount = 0;
437
+
438
+		} else {
439
+			$opener = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
440
+			$closer = $tokens[$opener]['parenthesis_closer'];
441
+
442
+			$nestedParenthesisCount = 1;
443
+		}
444
+
445
+		// Which nesting level is the one we are interested in ?
446
+		if (isset($tokens[$opener]['nested_parenthesis'])) {
447
+			$nestedParenthesisCount += \count($tokens[$opener]['nested_parenthesis']);
448
+		}
449
+
450
+		$parameters = array();
451
+		$nextComma  = $opener;
452
+		$paramStart = $opener + 1;
453
+		$cnt        = 1;
454
+		while (($nextComma = $phpcsFile->findNext(array(\T_COMMA, $tokens[$closer]['code'], \T_OPEN_SHORT_ARRAY, \T_CLOSURE), $nextComma + 1, $closer + 1)) !== false) {
455
+			// Ignore anything within short array definition brackets.
456
+			if ($tokens[$nextComma]['type'] === 'T_OPEN_SHORT_ARRAY'
457
+				&& (isset($tokens[$nextComma]['bracket_opener'])
458
+					&& $tokens[$nextComma]['bracket_opener'] === $nextComma)
459
+				&& isset($tokens[$nextComma]['bracket_closer'])
460
+			) {
461
+				// Skip forward to the end of the short array definition.
462
+				$nextComma = $tokens[$nextComma]['bracket_closer'];
463
+				continue;
464
+			}
465
+
466
+			// Skip past closures passed as function parameters.
467
+			if ($tokens[$nextComma]['type'] === 'T_CLOSURE'
468
+				&& (isset($tokens[$nextComma]['scope_condition'])
469
+					&& $tokens[$nextComma]['scope_condition'] === $nextComma)
470
+				&& isset($tokens[$nextComma]['scope_closer'])
471
+			) {
472
+				// Skip forward to the end of the closure declaration.
473
+				$nextComma = $tokens[$nextComma]['scope_closer'];
474
+				continue;
475
+			}
476
+
477
+			// Ignore comma's at a lower nesting level.
478
+			if ($tokens[$nextComma]['type'] === 'T_COMMA'
479
+				&& isset($tokens[$nextComma]['nested_parenthesis'])
480
+				&& \count($tokens[$nextComma]['nested_parenthesis']) !== $nestedParenthesisCount
481
+			) {
482
+				continue;
483
+			}
484
+
485
+			// Ignore closing parenthesis/bracket if not 'ours'.
486
+			if ($tokens[$nextComma]['type'] === $tokens[$closer]['type'] && $nextComma !== $closer) {
487
+				continue;
488
+			}
489
+
490
+			// Ok, we've reached the end of the parameter.
491
+			$parameters[$cnt]['start'] = $paramStart;
492
+			$parameters[$cnt]['end']   = $nextComma - 1;
493
+			$parameters[$cnt]['raw']   = trim($phpcsFile->getTokensAsString($paramStart, ($nextComma - $paramStart)));
494
+
495
+			// Check if there are more tokens before the closing parenthesis.
496
+			// Prevents code like the following from setting a third parameter:
497
+			// functionCall( $param1, $param2, );
498
+			$hasNextParam = $phpcsFile->findNext(Tokens::$emptyTokens, $nextComma + 1, $closer, true, null, true);
499
+			if ($hasNextParam === false) {
500
+				break;
501
+			}
502
+
503
+			// Prepare for the next parameter.
504
+			$paramStart = $nextComma + 1;
505
+			$cnt++;
506
+		}
507
+
508
+		return $parameters;
509
+	}
510
+
511
+
512
+	/**
513
+	 * Get information on a specific parameter passed to a function call.
514
+	 *
515
+	 * Expects to be passed the T_STRING or T_VARIABLE stack pointer for the function call.
516
+	 * If passed a T_STRING which is *not* a function call, the behaviour is unreliable.
517
+	 *
518
+	 * Will return a array with the start token pointer, end token pointer and the raw value
519
+	 * of the parameter at a specific offset.
520
+	 * If the specified parameter is not found, will return false.
521
+	 *
522
+	 * @param \PHP_CodeSniffer_File $phpcsFile   The file being scanned.
523
+	 * @param int                   $stackPtr    The position of the function call token.
524
+	 * @param int                   $paramOffset The 1-based index position of the parameter to retrieve.
525
+	 *
526
+	 * @return array|false
527
+	 */
528
+	public function getFunctionCallParameter(File $phpcsFile, $stackPtr, $paramOffset)
529
+	{
530
+		$parameters = $this->getFunctionCallParameters($phpcsFile, $stackPtr);
531
+
532
+		if (isset($parameters[$paramOffset]) === false) {
533
+			return false;
534
+		} else {
535
+			return $parameters[$paramOffset];
536
+		}
537
+	}
538
+
539
+
540
+	/**
541
+	 * Verify whether a token is within a scoped condition.
542
+	 *
543
+	 * If the optional $validScopes parameter has been passed, the function
544
+	 * will check that the token has at least one condition which is of a
545
+	 * type defined in $validScopes.
546
+	 *
547
+	 * @param \PHP_CodeSniffer_File $phpcsFile   The file being scanned.
548
+	 * @param int                   $stackPtr    The position of the token.
549
+	 * @param array|int             $validScopes Optional. Array of valid scopes
550
+	 *                                           or int value of a valid scope.
551
+	 *                                           Pass the T_.. constant(s) for the
552
+	 *                                           desired scope to this parameter.
553
+	 *
554
+	 * @return bool Without the optional $scopeTypes: True if within a scope, false otherwise.
555
+	 *              If the $scopeTypes are set: True if *one* of the conditions is a
556
+	 *              valid scope, false otherwise.
557
+	 */
558
+	public function tokenHasScope(File $phpcsFile, $stackPtr, $validScopes = null)
559
+	{
560
+		$tokens = $phpcsFile->getTokens();
561
+
562
+		// Check for the existence of the token.
563
+		if (isset($tokens[$stackPtr]) === false) {
564
+			return false;
565
+		}
566
+
567
+		// No conditions = no scope.
568
+		if (empty($tokens[$stackPtr]['conditions'])) {
569
+			return false;
570
+		}
571
+
572
+		// Ok, there are conditions, do we have to check for specific ones ?
573
+		if (isset($validScopes) === false) {
574
+			return true;
575
+		}
576
+
577
+		return $phpcsFile->hasCondition($stackPtr, $validScopes);
578
+	}
579
+
580
+
581
+	/**
582
+	 * Verify whether a token is within a class scope.
583
+	 *
584
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
585
+	 * @param int                   $stackPtr  The position of the token.
586
+	 * @param bool                  $strict    Whether to strictly check for the T_CLASS
587
+	 *                                         scope or also accept interfaces and traits
588
+	 *                                         as scope.
589
+	 *
590
+	 * @return bool True if within class scope, false otherwise.
591
+	 */
592
+	public function inClassScope(File $phpcsFile, $stackPtr, $strict = true)
593
+	{
594
+		$validScopes = array(\T_CLASS);
595
+		if (\defined('T_ANON_CLASS') === true) {
596
+			$validScopes[] = \T_ANON_CLASS;
597
+		}
598
+
599
+		if ($strict === false) {
600
+			$validScopes[] = \T_INTERFACE;
601
+			$validScopes[] = \T_TRAIT;
602
+		}
603
+
604
+		return $phpcsFile->hasCondition($stackPtr, $validScopes);
605
+	}
606
+
607
+
608
+	/**
609
+	 * Returns the fully qualified class name for a new class instantiation.
610
+	 *
611
+	 * Returns an empty string if the class name could not be reliably inferred.
612
+	 *
613
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
614
+	 * @param int                   $stackPtr  The position of a T_NEW token.
615
+	 *
616
+	 * @return string
617
+	 */
618
+	public function getFQClassNameFromNewToken(File $phpcsFile, $stackPtr)
619
+	{
620
+		$tokens = $phpcsFile->getTokens();
621
+
622
+		// Check for the existence of the token.
623
+		if (isset($tokens[$stackPtr]) === false) {
624
+			return '';
625
+		}
626
+
627
+		if ($tokens[$stackPtr]['code'] !== \T_NEW) {
628
+			return '';
629
+		}
630
+
631
+		$start = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true, null, true);
632
+		if ($start === false) {
633
+			return '';
634
+		}
635
+
636
+		// Bow out if the next token is a variable as we don't know where it was defined.
637
+		if ($tokens[$start]['code'] === \T_VARIABLE) {
638
+			return '';
639
+		}
640
+
641
+		// Bow out if the next token is the class keyword.
642
+		if ($tokens[$start]['type'] === 'T_ANON_CLASS' || $tokens[$start]['code'] === \T_CLASS) {
643
+			return '';
644
+		}
645
+
646
+		$find = array(
647
+			\T_NS_SEPARATOR,
648
+			\T_STRING,
649
+			\T_NAMESPACE,
650
+			\T_WHITESPACE,
651
+		);
652
+
653
+		$end       = $phpcsFile->findNext($find, ($start + 1), null, true, null, true);
654
+		$className = $phpcsFile->getTokensAsString($start, ($end - $start));
655
+		$className = trim($className);
656
+
657
+		return $this->getFQName($phpcsFile, $stackPtr, $className);
658
+	}
659
+
660
+
661
+	/**
662
+	 * Returns the fully qualified name of the class that the specified class extends.
663
+	 *
664
+	 * Returns an empty string if the class does not extend another class or if
665
+	 * the class name could not be reliably inferred.
666
+	 *
667
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
668
+	 * @param int                   $stackPtr  The position of a T_CLASS token.
669
+	 *
670
+	 * @return string
671
+	 */
672
+	public function getFQExtendedClassName(File $phpcsFile, $stackPtr)
673
+	{
674
+		$tokens = $phpcsFile->getTokens();
675
+
676
+		// Check for the existence of the token.
677
+		if (isset($tokens[$stackPtr]) === false) {
678
+			return '';
679
+		}
680
+
681
+		if ($tokens[$stackPtr]['code'] !== \T_CLASS
682
+			&& $tokens[$stackPtr]['type'] !== 'T_ANON_CLASS'
683
+			&& $tokens[$stackPtr]['type'] !== 'T_INTERFACE'
684
+		) {
685
+			return '';
686
+		}
687
+
688
+		$extends = PHPCSHelper::findExtendedClassName($phpcsFile, $stackPtr);
689
+		if (empty($extends) || \is_string($extends) === false) {
690
+			return '';
691
+		}
692
+
693
+		return $this->getFQName($phpcsFile, $stackPtr, $extends);
694
+	}
695
+
696
+
697
+	/**
698
+	 * Returns the class name for the static usage of a class.
699
+	 * This can be a call to a method, the use of a property or constant.
700
+	 *
701
+	 * Returns an empty string if the class name could not be reliably inferred.
702
+	 *
703
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
704
+	 * @param int                   $stackPtr  The position of a T_NEW token.
705
+	 *
706
+	 * @return string
707
+	 */
708
+	public function getFQClassNameFromDoubleColonToken(File $phpcsFile, $stackPtr)
709
+	{
710
+		$tokens = $phpcsFile->getTokens();
711
+
712
+		// Check for the existence of the token.
713
+		if (isset($tokens[$stackPtr]) === false) {
714
+			return '';
715
+		}
716
+
717
+		if ($tokens[$stackPtr]['code'] !== \T_DOUBLE_COLON) {
718
+			return '';
719
+		}
720
+
721
+		// Nothing to do if previous token is a variable as we don't know where it was defined.
722
+		if ($tokens[$stackPtr - 1]['code'] === \T_VARIABLE) {
723
+			return '';
724
+		}
725
+
726
+		// Nothing to do if 'parent' or 'static' as we don't know how far the class tree extends.
727
+		if (\in_array($tokens[$stackPtr - 1]['code'], array(\T_PARENT, \T_STATIC), true)) {
728
+			return '';
729
+		}
730
+
731
+		// Get the classname from the class declaration if self is used.
732
+		if ($tokens[$stackPtr - 1]['code'] === \T_SELF) {
733
+			$classDeclarationPtr = $phpcsFile->findPrevious(\T_CLASS, $stackPtr - 1);
734
+			if ($classDeclarationPtr === false) {
735
+				return '';
736
+			}
737
+			$className = $phpcsFile->getDeclarationName($classDeclarationPtr);
738
+			return $this->getFQName($phpcsFile, $classDeclarationPtr, $className);
739
+		}
740
+
741
+		$find = array(
742
+			\T_NS_SEPARATOR,
743
+			\T_STRING,
744
+			\T_NAMESPACE,
745
+			\T_WHITESPACE,
746
+		);
747
+
748
+		$start = $phpcsFile->findPrevious($find, $stackPtr - 1, null, true, null, true);
749
+		if ($start === false || isset($tokens[($start + 1)]) === false) {
750
+			return '';
751
+		}
752
+
753
+		$start     = ($start + 1);
754
+		$className = $phpcsFile->getTokensAsString($start, ($stackPtr - $start));
755
+		$className = trim($className);
756
+
757
+		return $this->getFQName($phpcsFile, $stackPtr, $className);
758
+	}
759
+
760
+
761
+	/**
762
+	 * Get the Fully Qualified name for a class/function/constant etc.
763
+	 *
764
+	 * Checks if a class/function/constant name is already fully qualified and
765
+	 * if not, enrich it with the relevant namespace information.
766
+	 *
767
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
768
+	 * @param int                   $stackPtr  The position of the token.
769
+	 * @param string                $name      The class / function / constant name.
770
+	 *
771
+	 * @return string
772
+	 */
773
+	public function getFQName(File $phpcsFile, $stackPtr, $name)
774
+	{
775
+		if (strpos($name, '\\') === 0) {
776
+			// Already fully qualified.
777
+			return $name;
778
+		}
779
+
780
+		// Remove the namespace keyword if used.
781
+		if (strpos($name, 'namespace\\') === 0) {
782
+			$name = substr($name, 10);
783
+		}
784
+
785
+		$namespace = $this->determineNamespace($phpcsFile, $stackPtr);
786
+
787
+		if ($namespace === '') {
788
+			return '\\' . $name;
789
+		} else {
790
+			return '\\' . $namespace . '\\' . $name;
791
+		}
792
+	}
793
+
794
+
795
+	/**
796
+	 * Is the class/function/constant name namespaced or global ?
797
+	 *
798
+	 * @param string $FQName Fully Qualified name of a class, function etc.
799
+	 *                       I.e. should always start with a `\`.
800
+	 *
801
+	 * @return bool True if namespaced, false if global.
802
+	 */
803
+	public function isNamespaced($FQName)
804
+	{
805
+		if (strpos($FQName, '\\') !== 0) {
806
+			throw new PHPCS_Exception('$FQName must be a fully qualified name');
807
+		}
808
+
809
+		return (strpos(substr($FQName, 1), '\\') !== false);
810
+	}
811
+
812
+
813
+	/**
814
+	 * Determine the namespace name an arbitrary token lives in.
815
+	 *
816
+	 * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
817
+	 * @param int                   $stackPtr  The token position for which to determine the namespace.
818
+	 *
819
+	 * @return string Namespace name or empty string if it couldn't be determined or no namespace applies.
820
+	 */
821
+	public function determineNamespace(File $phpcsFile, $stackPtr)
822
+	{
823
+		$tokens = $phpcsFile->getTokens();
824
+
825
+		// Check for the existence of the token.
826
+		if (isset($tokens[$stackPtr]) === false) {
827
+			return '';
828
+		}
829
+
830
+		// Check for scoped namespace {}.
831
+		if (empty($tokens[$stackPtr]['conditions']) === false) {
832
+			$namespacePtr = $phpcsFile->getCondition($stackPtr, \T_NAMESPACE);
833
+			if ($namespacePtr !== false) {
834
+				$namespace = $this->getDeclaredNamespaceName($phpcsFile, $namespacePtr);
835
+				if ($namespace !== false) {
836
+					return $namespace;
837
+				}
838
+
839
+				// We are in a scoped namespace, but couldn't determine the name. Searching for a global namespace is futile.
840
+				return '';
841
+			}
842
+		}
843
+
844
+		/*
845 845
          * Not in a scoped namespace, so let's see if we can find a non-scoped namespace instead.
846 846
          * Keeping in mind that:
847 847
          * - there can be multiple non-scoped namespaces in a file (bad practice, but it happens).
848 848
          * - the namespace keyword can also be used as part of a function/method call and such.
849 849
          * - that a non-named namespace resolves to the global namespace.
850 850
          */
851
-        $previousNSToken = $stackPtr;
852
-        $namespace       = false;
853
-        do {
854
-            $previousNSToken = $phpcsFile->findPrevious(\T_NAMESPACE, ($previousNSToken - 1));
855
-
856
-            // Stop if we encounter a scoped namespace declaration as we already know we're not in one.
857
-            if (empty($tokens[$previousNSToken]['scope_condition']) === false && $tokens[$previousNSToken]['scope_condition'] === $previousNSToken) {
858
-                break;
859
-            }
860
-
861
-            $namespace = $this->getDeclaredNamespaceName($phpcsFile, $previousNSToken);
862
-
863
-        } while ($namespace === false && $previousNSToken !== false);
864
-
865
-        // If we still haven't got a namespace, return an empty string.
866
-        if ($namespace === false) {
867
-            return '';
868
-        } else {
869
-            return $namespace;
870
-        }
871
-    }
872
-
873
-    /**
874
-     * Get the complete namespace name for a namespace declaration.
875
-     *
876
-     * For hierarchical namespaces, the name will be composed of several tokens,
877
-     * i.e. MyProject\Sub\Level which will be returned together as one string.
878
-     *
879
-     * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
880
-     * @param int|bool              $stackPtr  The position of a T_NAMESPACE token.
881
-     *
882
-     * @return string|false Namespace name or false if not a namespace declaration.
883
-     *                      Namespace name can be an empty string for global namespace declaration.
884
-     */
885
-    public function getDeclaredNamespaceName(File $phpcsFile, $stackPtr)
886
-    {
887
-        $tokens = $phpcsFile->getTokens();
888
-
889
-        // Check for the existence of the token.
890
-        if ($stackPtr === false || isset($tokens[$stackPtr]) === false) {
891
-            return false;
892
-        }
893
-
894
-        if ($tokens[$stackPtr]['code'] !== \T_NAMESPACE) {
895
-            return false;
896
-        }
897
-
898
-        if ($tokens[($stackPtr + 1)]['code'] === \T_NS_SEPARATOR) {
899
-            // Not a namespace declaration, but use of, i.e. namespace\someFunction();
900
-            return false;
901
-        }
902
-
903
-        $nextToken = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
904
-        if ($tokens[$nextToken]['code'] === \T_OPEN_CURLY_BRACKET) {
905
-            // Declaration for global namespace when using multiple namespaces in a file.
906
-            // I.e.: namespace {}
907
-            return '';
908
-        }
909
-
910
-        // Ok, this should be a namespace declaration, so get all the parts together.
911
-        $validTokens = array(
912
-            \T_STRING       => true,
913
-            \T_NS_SEPARATOR => true,
914
-            \T_WHITESPACE   => true,
915
-        );
916
-
917
-        $namespaceName = '';
918
-        while (isset($validTokens[$tokens[$nextToken]['code']]) === true) {
919
-            $namespaceName .= trim($tokens[$nextToken]['content']);
920
-            $nextToken++;
921
-        }
922
-
923
-        return $namespaceName;
924
-    }
925
-
926
-
927
-    /**
928
-     * Get the stack pointer for a return type token for a given function.
929
-     *
930
-     * Compatible layer for older PHPCS versions which don't recognize
931
-     * return type hints correctly.
932
-     *
933
-     * Expects to be passed T_RETURN_TYPE, T_FUNCTION or T_CLOSURE token.
934
-     *
935
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
936
-     * @param int                   $stackPtr  The position of the token.
937
-     *
938
-     * @return int|false Stack pointer to the return type token or false if
939
-     *                   no return type was found or the passed token was
940
-     *                   not of the correct type.
941
-     */
942
-    public function getReturnTypeHintToken(File $phpcsFile, $stackPtr)
943
-    {
944
-        $tokens = $phpcsFile->getTokens();
945
-
946
-        if (\defined('T_RETURN_TYPE') && $tokens[$stackPtr]['code'] === \T_RETURN_TYPE) {
947
-            return $stackPtr;
948
-        }
949
-
950
-        if ($tokens[$stackPtr]['code'] !== \T_FUNCTION && $tokens[$stackPtr]['code'] !== \T_CLOSURE) {
951
-            return false;
952
-        }
953
-
954
-        if (isset($tokens[$stackPtr]['parenthesis_closer']) === false) {
955
-            return false;
956
-        }
957
-
958
-        // Allow for interface and abstract method declarations.
959
-        $endOfFunctionDeclaration = null;
960
-        if (isset($tokens[$stackPtr]['scope_opener'])) {
961
-            $endOfFunctionDeclaration = $tokens[$stackPtr]['scope_opener'];
962
-        } else {
963
-            $nextSemiColon = $phpcsFile->findNext(\T_SEMICOLON, ($tokens[$stackPtr]['parenthesis_closer'] + 1), null, false, null, true);
964
-            if ($nextSemiColon !== false) {
965
-                $endOfFunctionDeclaration = $nextSemiColon;
966
-            }
967
-        }
968
-
969
-        if (isset($endOfFunctionDeclaration) === false) {
970
-            return false;
971
-        }
972
-
973
-        $hasColon = $phpcsFile->findNext(
974
-            array(\T_COLON, \T_INLINE_ELSE),
975
-            ($tokens[$stackPtr]['parenthesis_closer'] + 1),
976
-            $endOfFunctionDeclaration
977
-        );
978
-        if ($hasColon === false) {
979
-            return false;
980
-        }
981
-
982
-        /*
851
+		$previousNSToken = $stackPtr;
852
+		$namespace       = false;
853
+		do {
854
+			$previousNSToken = $phpcsFile->findPrevious(\T_NAMESPACE, ($previousNSToken - 1));
855
+
856
+			// Stop if we encounter a scoped namespace declaration as we already know we're not in one.
857
+			if (empty($tokens[$previousNSToken]['scope_condition']) === false && $tokens[$previousNSToken]['scope_condition'] === $previousNSToken) {
858
+				break;
859
+			}
860
+
861
+			$namespace = $this->getDeclaredNamespaceName($phpcsFile, $previousNSToken);
862
+
863
+		} while ($namespace === false && $previousNSToken !== false);
864
+
865
+		// If we still haven't got a namespace, return an empty string.
866
+		if ($namespace === false) {
867
+			return '';
868
+		} else {
869
+			return $namespace;
870
+		}
871
+	}
872
+
873
+	/**
874
+	 * Get the complete namespace name for a namespace declaration.
875
+	 *
876
+	 * For hierarchical namespaces, the name will be composed of several tokens,
877
+	 * i.e. MyProject\Sub\Level which will be returned together as one string.
878
+	 *
879
+	 * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
880
+	 * @param int|bool              $stackPtr  The position of a T_NAMESPACE token.
881
+	 *
882
+	 * @return string|false Namespace name or false if not a namespace declaration.
883
+	 *                      Namespace name can be an empty string for global namespace declaration.
884
+	 */
885
+	public function getDeclaredNamespaceName(File $phpcsFile, $stackPtr)
886
+	{
887
+		$tokens = $phpcsFile->getTokens();
888
+
889
+		// Check for the existence of the token.
890
+		if ($stackPtr === false || isset($tokens[$stackPtr]) === false) {
891
+			return false;
892
+		}
893
+
894
+		if ($tokens[$stackPtr]['code'] !== \T_NAMESPACE) {
895
+			return false;
896
+		}
897
+
898
+		if ($tokens[($stackPtr + 1)]['code'] === \T_NS_SEPARATOR) {
899
+			// Not a namespace declaration, but use of, i.e. namespace\someFunction();
900
+			return false;
901
+		}
902
+
903
+		$nextToken = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
904
+		if ($tokens[$nextToken]['code'] === \T_OPEN_CURLY_BRACKET) {
905
+			// Declaration for global namespace when using multiple namespaces in a file.
906
+			// I.e.: namespace {}
907
+			return '';
908
+		}
909
+
910
+		// Ok, this should be a namespace declaration, so get all the parts together.
911
+		$validTokens = array(
912
+			\T_STRING       => true,
913
+			\T_NS_SEPARATOR => true,
914
+			\T_WHITESPACE   => true,
915
+		);
916
+
917
+		$namespaceName = '';
918
+		while (isset($validTokens[$tokens[$nextToken]['code']]) === true) {
919
+			$namespaceName .= trim($tokens[$nextToken]['content']);
920
+			$nextToken++;
921
+		}
922
+
923
+		return $namespaceName;
924
+	}
925
+
926
+
927
+	/**
928
+	 * Get the stack pointer for a return type token for a given function.
929
+	 *
930
+	 * Compatible layer for older PHPCS versions which don't recognize
931
+	 * return type hints correctly.
932
+	 *
933
+	 * Expects to be passed T_RETURN_TYPE, T_FUNCTION or T_CLOSURE token.
934
+	 *
935
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
936
+	 * @param int                   $stackPtr  The position of the token.
937
+	 *
938
+	 * @return int|false Stack pointer to the return type token or false if
939
+	 *                   no return type was found or the passed token was
940
+	 *                   not of the correct type.
941
+	 */
942
+	public function getReturnTypeHintToken(File $phpcsFile, $stackPtr)
943
+	{
944
+		$tokens = $phpcsFile->getTokens();
945
+
946
+		if (\defined('T_RETURN_TYPE') && $tokens[$stackPtr]['code'] === \T_RETURN_TYPE) {
947
+			return $stackPtr;
948
+		}
949
+
950
+		if ($tokens[$stackPtr]['code'] !== \T_FUNCTION && $tokens[$stackPtr]['code'] !== \T_CLOSURE) {
951
+			return false;
952
+		}
953
+
954
+		if (isset($tokens[$stackPtr]['parenthesis_closer']) === false) {
955
+			return false;
956
+		}
957
+
958
+		// Allow for interface and abstract method declarations.
959
+		$endOfFunctionDeclaration = null;
960
+		if (isset($tokens[$stackPtr]['scope_opener'])) {
961
+			$endOfFunctionDeclaration = $tokens[$stackPtr]['scope_opener'];
962
+		} else {
963
+			$nextSemiColon = $phpcsFile->findNext(\T_SEMICOLON, ($tokens[$stackPtr]['parenthesis_closer'] + 1), null, false, null, true);
964
+			if ($nextSemiColon !== false) {
965
+				$endOfFunctionDeclaration = $nextSemiColon;
966
+			}
967
+		}
968
+
969
+		if (isset($endOfFunctionDeclaration) === false) {
970
+			return false;
971
+		}
972
+
973
+		$hasColon = $phpcsFile->findNext(
974
+			array(\T_COLON, \T_INLINE_ELSE),
975
+			($tokens[$stackPtr]['parenthesis_closer'] + 1),
976
+			$endOfFunctionDeclaration
977
+		);
978
+		if ($hasColon === false) {
979
+			return false;
980
+		}
981
+
982
+		/*
983 983
          * - `self`, `parent` and `callable` are not being recognized as return types in PHPCS < 2.6.0.
984 984
          * - Return types are not recognized at all in PHPCS < 2.4.0.
985 985
          * - The T_RETURN_TYPE token is defined, but no longer in use since PHPCS 3.3.0+.
@@ -988,1107 +988,1107 @@  discard block
 block discarded – undo
988 988
          *   to prevent confusing sniffs looking for array declarations.
989 989
          *   As of PHPCS 3.3.0 `array` as a type declaration will be tokenized as `T_STRING`.
990 990
          */
991
-        $unrecognizedTypes = array(
992
-            \T_CALLABLE,
993
-            \T_SELF,
994
-            \T_PARENT,
995
-            \T_ARRAY, // PHPCS < 2.4.0.
996
-            \T_STRING,
997
-        );
998
-
999
-        return $phpcsFile->findPrevious($unrecognizedTypes, ($endOfFunctionDeclaration - 1), $hasColon);
1000
-    }
1001
-
1002
-
1003
-    /**
1004
-     * Get the complete return type declaration for a given function.
1005
-     *
1006
-     * Cross-version compatible way to retrieve the complete return type declaration.
1007
-     *
1008
-     * For a classname-based return type, PHPCS, as well as the Sniff::getReturnTypeHintToken()
1009
-     * method will mark the classname as the return type token.
1010
-     * This method will find preceeding namespaces and namespace separators and will return a
1011
-     * string containing the qualified return type declaration.
1012
-     *
1013
-     * Expects to be passed a T_RETURN_TYPE token or the return value from a call to
1014
-     * the Sniff::getReturnTypeHintToken() method.
1015
-     *
1016
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1017
-     * @param int                   $stackPtr  The position of the return type token.
1018
-     *
1019
-     * @return string|false The name of the return type token.
1020
-     */
1021
-    public function getReturnTypeHintName(File $phpcsFile, $stackPtr)
1022
-    {
1023
-        $tokens = $phpcsFile->getTokens();
1024
-
1025
-        // In older PHPCS versions, the nullable indicator will turn a return type colon into a T_INLINE_ELSE.
1026
-        $colon = $phpcsFile->findPrevious(array(\T_COLON, \T_INLINE_ELSE, \T_FUNCTION, \T_CLOSE_PARENTHESIS), ($stackPtr - 1));
1027
-        if ($colon === false
1028
-            || ($tokens[$colon]['code'] !== \T_COLON && $tokens[$colon]['code'] !== \T_INLINE_ELSE)
1029
-        ) {
1030
-            // Shouldn't happen, just in case.
1031
-            return;
1032
-        }
1033
-
1034
-        $returnTypeHint = '';
1035
-        for ($i = ($colon + 1); $i <= $stackPtr; $i++) {
1036
-            // As of PHPCS 3.3.0+, all tokens are tokenized as "normal", so T_CALLABLE, T_SELF etc are
1037
-            // all possible, just exclude anything that's regarded as empty and the nullable indicator.
1038
-            if (isset(Tokens::$emptyTokens[$tokens[$i]['code']])) {
1039
-                continue;
1040
-            }
1041
-
1042
-            if ($tokens[$i]['type'] === 'T_NULLABLE') {
1043
-                continue;
1044
-            }
1045
-
1046
-            if (\defined('T_NULLABLE') === false && $tokens[$i]['code'] === \T_INLINE_THEN) {
1047
-                // Old PHPCS.
1048
-                continue;
1049
-            }
1050
-
1051
-            $returnTypeHint .= $tokens[$i]['content'];
1052
-        }
1053
-
1054
-        return $returnTypeHint;
1055
-    }
1056
-
1057
-
1058
-    /**
1059
-     * Check whether a T_VARIABLE token is a class property declaration.
1060
-     *
1061
-     * Compatibility layer for PHPCS cross-version compatibility
1062
-     * as PHPCS 2.4.0 - 2.7.1 does not have good enough support for
1063
-     * anonymous classes. Along the same lines, the`getMemberProperties()`
1064
-     * method does not support the `var` prefix.
1065
-     *
1066
-     * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
1067
-     * @param int                   $stackPtr  The position in the stack of the
1068
-     *                                         T_VARIABLE token to verify.
1069
-     *
1070
-     * @return bool
1071
-     */
1072
-    public function isClassProperty(File $phpcsFile, $stackPtr)
1073
-    {
1074
-        $tokens = $phpcsFile->getTokens();
1075
-
1076
-        if (isset($tokens[$stackPtr]) === false || $tokens[$stackPtr]['code'] !== \T_VARIABLE) {
1077
-            return false;
1078
-        }
1079
-
1080
-        // Note: interfaces can not declare properties.
1081
-        $validScopes = array(
1082
-            'T_CLASS'      => true,
1083
-            'T_ANON_CLASS' => true,
1084
-            'T_TRAIT'      => true,
1085
-        );
1086
-
1087
-        $scopePtr = $this->validDirectScope($phpcsFile, $stackPtr, $validScopes);
1088
-        if ($scopePtr !== false) {
1089
-            // Make sure it's not a method parameter.
1090
-            if (empty($tokens[$stackPtr]['nested_parenthesis']) === true) {
1091
-                return true;
1092
-            } else {
1093
-                $parenthesis = array_keys($tokens[$stackPtr]['nested_parenthesis']);
1094
-                $deepestOpen = array_pop($parenthesis);
1095
-                if ($deepestOpen < $scopePtr
1096
-                    || isset($tokens[$deepestOpen]['parenthesis_owner']) === false
1097
-                    || $tokens[$tokens[$deepestOpen]['parenthesis_owner']]['code'] !== \T_FUNCTION
1098
-                ) {
1099
-                    return true;
1100
-                }
1101
-            }
1102
-        }
1103
-
1104
-        return false;
1105
-    }
1106
-
1107
-
1108
-    /**
1109
-     * Check whether a T_CONST token is a class constant declaration.
1110
-     *
1111
-     * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
1112
-     * @param int                   $stackPtr  The position in the stack of the
1113
-     *                                         T_CONST token to verify.
1114
-     *
1115
-     * @return bool
1116
-     */
1117
-    public function isClassConstant(File $phpcsFile, $stackPtr)
1118
-    {
1119
-        $tokens = $phpcsFile->getTokens();
1120
-
1121
-        if (isset($tokens[$stackPtr]) === false || $tokens[$stackPtr]['code'] !== \T_CONST) {
1122
-            return false;
1123
-        }
1124
-
1125
-        // Note: traits can not declare constants.
1126
-        $validScopes = array(
1127
-            'T_CLASS'      => true,
1128
-            'T_ANON_CLASS' => true,
1129
-            'T_INTERFACE'  => true,
1130
-        );
1131
-        if ($this->validDirectScope($phpcsFile, $stackPtr, $validScopes) !== false) {
1132
-            return true;
1133
-        }
1134
-
1135
-        return false;
1136
-    }
1137
-
1138
-
1139
-    /**
1140
-     * Check whether the direct wrapping scope of a token is within a limited set of
1141
-     * acceptable tokens.
1142
-     *
1143
-     * Used to check, for instance, if a T_CONST is a class constant.
1144
-     *
1145
-     * @param \PHP_CodeSniffer_File $phpcsFile   Instance of phpcsFile.
1146
-     * @param int                   $stackPtr    The position in the stack of the
1147
-     *                                           token to verify.
1148
-     * @param array                 $validScopes Array of token types.
1149
-     *                                           Keys should be the token types in string
1150
-     *                                           format to allow for newer token types.
1151
-     *                                           Value is irrelevant.
1152
-     *
1153
-     * @return int|bool StackPtr to the scope if valid, false otherwise.
1154
-     */
1155
-    protected function validDirectScope(File $phpcsFile, $stackPtr, $validScopes)
1156
-    {
1157
-        $tokens = $phpcsFile->getTokens();
1158
-
1159
-        if (empty($tokens[$stackPtr]['conditions']) === true) {
1160
-            return false;
1161
-        }
1162
-
1163
-        /*
991
+		$unrecognizedTypes = array(
992
+			\T_CALLABLE,
993
+			\T_SELF,
994
+			\T_PARENT,
995
+			\T_ARRAY, // PHPCS < 2.4.0.
996
+			\T_STRING,
997
+		);
998
+
999
+		return $phpcsFile->findPrevious($unrecognizedTypes, ($endOfFunctionDeclaration - 1), $hasColon);
1000
+	}
1001
+
1002
+
1003
+	/**
1004
+	 * Get the complete return type declaration for a given function.
1005
+	 *
1006
+	 * Cross-version compatible way to retrieve the complete return type declaration.
1007
+	 *
1008
+	 * For a classname-based return type, PHPCS, as well as the Sniff::getReturnTypeHintToken()
1009
+	 * method will mark the classname as the return type token.
1010
+	 * This method will find preceeding namespaces and namespace separators and will return a
1011
+	 * string containing the qualified return type declaration.
1012
+	 *
1013
+	 * Expects to be passed a T_RETURN_TYPE token or the return value from a call to
1014
+	 * the Sniff::getReturnTypeHintToken() method.
1015
+	 *
1016
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1017
+	 * @param int                   $stackPtr  The position of the return type token.
1018
+	 *
1019
+	 * @return string|false The name of the return type token.
1020
+	 */
1021
+	public function getReturnTypeHintName(File $phpcsFile, $stackPtr)
1022
+	{
1023
+		$tokens = $phpcsFile->getTokens();
1024
+
1025
+		// In older PHPCS versions, the nullable indicator will turn a return type colon into a T_INLINE_ELSE.
1026
+		$colon = $phpcsFile->findPrevious(array(\T_COLON, \T_INLINE_ELSE, \T_FUNCTION, \T_CLOSE_PARENTHESIS), ($stackPtr - 1));
1027
+		if ($colon === false
1028
+			|| ($tokens[$colon]['code'] !== \T_COLON && $tokens[$colon]['code'] !== \T_INLINE_ELSE)
1029
+		) {
1030
+			// Shouldn't happen, just in case.
1031
+			return;
1032
+		}
1033
+
1034
+		$returnTypeHint = '';
1035
+		for ($i = ($colon + 1); $i <= $stackPtr; $i++) {
1036
+			// As of PHPCS 3.3.0+, all tokens are tokenized as "normal", so T_CALLABLE, T_SELF etc are
1037
+			// all possible, just exclude anything that's regarded as empty and the nullable indicator.
1038
+			if (isset(Tokens::$emptyTokens[$tokens[$i]['code']])) {
1039
+				continue;
1040
+			}
1041
+
1042
+			if ($tokens[$i]['type'] === 'T_NULLABLE') {
1043
+				continue;
1044
+			}
1045
+
1046
+			if (\defined('T_NULLABLE') === false && $tokens[$i]['code'] === \T_INLINE_THEN) {
1047
+				// Old PHPCS.
1048
+				continue;
1049
+			}
1050
+
1051
+			$returnTypeHint .= $tokens[$i]['content'];
1052
+		}
1053
+
1054
+		return $returnTypeHint;
1055
+	}
1056
+
1057
+
1058
+	/**
1059
+	 * Check whether a T_VARIABLE token is a class property declaration.
1060
+	 *
1061
+	 * Compatibility layer for PHPCS cross-version compatibility
1062
+	 * as PHPCS 2.4.0 - 2.7.1 does not have good enough support for
1063
+	 * anonymous classes. Along the same lines, the`getMemberProperties()`
1064
+	 * method does not support the `var` prefix.
1065
+	 *
1066
+	 * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
1067
+	 * @param int                   $stackPtr  The position in the stack of the
1068
+	 *                                         T_VARIABLE token to verify.
1069
+	 *
1070
+	 * @return bool
1071
+	 */
1072
+	public function isClassProperty(File $phpcsFile, $stackPtr)
1073
+	{
1074
+		$tokens = $phpcsFile->getTokens();
1075
+
1076
+		if (isset($tokens[$stackPtr]) === false || $tokens[$stackPtr]['code'] !== \T_VARIABLE) {
1077
+			return false;
1078
+		}
1079
+
1080
+		// Note: interfaces can not declare properties.
1081
+		$validScopes = array(
1082
+			'T_CLASS'      => true,
1083
+			'T_ANON_CLASS' => true,
1084
+			'T_TRAIT'      => true,
1085
+		);
1086
+
1087
+		$scopePtr = $this->validDirectScope($phpcsFile, $stackPtr, $validScopes);
1088
+		if ($scopePtr !== false) {
1089
+			// Make sure it's not a method parameter.
1090
+			if (empty($tokens[$stackPtr]['nested_parenthesis']) === true) {
1091
+				return true;
1092
+			} else {
1093
+				$parenthesis = array_keys($tokens[$stackPtr]['nested_parenthesis']);
1094
+				$deepestOpen = array_pop($parenthesis);
1095
+				if ($deepestOpen < $scopePtr
1096
+					|| isset($tokens[$deepestOpen]['parenthesis_owner']) === false
1097
+					|| $tokens[$tokens[$deepestOpen]['parenthesis_owner']]['code'] !== \T_FUNCTION
1098
+				) {
1099
+					return true;
1100
+				}
1101
+			}
1102
+		}
1103
+
1104
+		return false;
1105
+	}
1106
+
1107
+
1108
+	/**
1109
+	 * Check whether a T_CONST token is a class constant declaration.
1110
+	 *
1111
+	 * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
1112
+	 * @param int                   $stackPtr  The position in the stack of the
1113
+	 *                                         T_CONST token to verify.
1114
+	 *
1115
+	 * @return bool
1116
+	 */
1117
+	public function isClassConstant(File $phpcsFile, $stackPtr)
1118
+	{
1119
+		$tokens = $phpcsFile->getTokens();
1120
+
1121
+		if (isset($tokens[$stackPtr]) === false || $tokens[$stackPtr]['code'] !== \T_CONST) {
1122
+			return false;
1123
+		}
1124
+
1125
+		// Note: traits can not declare constants.
1126
+		$validScopes = array(
1127
+			'T_CLASS'      => true,
1128
+			'T_ANON_CLASS' => true,
1129
+			'T_INTERFACE'  => true,
1130
+		);
1131
+		if ($this->validDirectScope($phpcsFile, $stackPtr, $validScopes) !== false) {
1132
+			return true;
1133
+		}
1134
+
1135
+		return false;
1136
+	}
1137
+
1138
+
1139
+	/**
1140
+	 * Check whether the direct wrapping scope of a token is within a limited set of
1141
+	 * acceptable tokens.
1142
+	 *
1143
+	 * Used to check, for instance, if a T_CONST is a class constant.
1144
+	 *
1145
+	 * @param \PHP_CodeSniffer_File $phpcsFile   Instance of phpcsFile.
1146
+	 * @param int                   $stackPtr    The position in the stack of the
1147
+	 *                                           token to verify.
1148
+	 * @param array                 $validScopes Array of token types.
1149
+	 *                                           Keys should be the token types in string
1150
+	 *                                           format to allow for newer token types.
1151
+	 *                                           Value is irrelevant.
1152
+	 *
1153
+	 * @return int|bool StackPtr to the scope if valid, false otherwise.
1154
+	 */
1155
+	protected function validDirectScope(File $phpcsFile, $stackPtr, $validScopes)
1156
+	{
1157
+		$tokens = $phpcsFile->getTokens();
1158
+
1159
+		if (empty($tokens[$stackPtr]['conditions']) === true) {
1160
+			return false;
1161
+		}
1162
+
1163
+		/*
1164 1164
          * Check only the direct wrapping scope of the token.
1165 1165
          */
1166
-        $conditions = array_keys($tokens[$stackPtr]['conditions']);
1167
-        $ptr        = array_pop($conditions);
1168
-
1169
-        if (isset($tokens[$ptr]) === false) {
1170
-            return false;
1171
-        }
1172
-
1173
-        if (isset($validScopes[$tokens[$ptr]['type']]) === true) {
1174
-            return $ptr;
1175
-        }
1176
-
1177
-        return false;
1178
-    }
1179
-
1180
-
1181
-    /**
1182
-     * Get an array of just the type hints from a function declaration.
1183
-     *
1184
-     * Expects to be passed T_FUNCTION or T_CLOSURE token.
1185
-     *
1186
-     * Strips potential nullable indicator and potential global namespace
1187
-     * indicator from the type hints before returning them.
1188
-     *
1189
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1190
-     * @param int                   $stackPtr  The position of the token.
1191
-     *
1192
-     * @return array Array with type hints or an empty array if
1193
-     *               - the function does not have any parameters
1194
-     *               - no type hints were found
1195
-     *               - or the passed token was not of the correct type.
1196
-     */
1197
-    public function getTypeHintsFromFunctionDeclaration(File $phpcsFile, $stackPtr)
1198
-    {
1199
-        $tokens = $phpcsFile->getTokens();
1200
-
1201
-        if ($tokens[$stackPtr]['code'] !== \T_FUNCTION && $tokens[$stackPtr]['code'] !== \T_CLOSURE) {
1202
-            return array();
1203
-        }
1204
-
1205
-        $parameters = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
1206
-        if (empty($parameters) || \is_array($parameters) === false) {
1207
-            return array();
1208
-        }
1209
-
1210
-        $typeHints = array();
1211
-
1212
-        foreach ($parameters as $param) {
1213
-            if ($param['type_hint'] === '') {
1214
-                continue;
1215
-            }
1216
-
1217
-            // Strip off potential nullable indication.
1218
-            $typeHint = ltrim($param['type_hint'], '?');
1219
-
1220
-            // Strip off potential (global) namespace indication.
1221
-            $typeHint = ltrim($typeHint, '\\');
1222
-
1223
-            if ($typeHint !== '') {
1224
-                $typeHints[] = $typeHint;
1225
-            }
1226
-        }
1227
-
1228
-        return $typeHints;
1229
-    }
1230
-
1231
-
1232
-    /**
1233
-     * Get the hash algorithm name from the parameter in a hash function call.
1234
-     *
1235
-     * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
1236
-     * @param int                   $stackPtr  The position of the T_STRING function token.
1237
-     *
1238
-     * @return string|false The algorithm name without quotes if this was a relevant hash
1239
-     *                      function call or false if it was not.
1240
-     */
1241
-    public function getHashAlgorithmParameter(File $phpcsFile, $stackPtr)
1242
-    {
1243
-        $tokens = $phpcsFile->getTokens();
1244
-
1245
-        // Check for the existence of the token.
1246
-        if (isset($tokens[$stackPtr]) === false) {
1247
-            return false;
1248
-        }
1249
-
1250
-        if ($tokens[$stackPtr]['code'] !== \T_STRING) {
1251
-            return false;
1252
-        }
1253
-
1254
-        $functionName   = $tokens[$stackPtr]['content'];
1255
-        $functionNameLc = strtolower($functionName);
1256
-
1257
-        // Bow out if not one of the functions we're targetting.
1258
-        if (isset($this->hashAlgoFunctions[$functionNameLc]) === false) {
1259
-            return false;
1260
-        }
1261
-
1262
-        // Get the parameter from the function call which should contain the algorithm name.
1263
-        $algoParam = $this->getFunctionCallParameter($phpcsFile, $stackPtr, $this->hashAlgoFunctions[$functionNameLc]);
1264
-        if ($algoParam === false) {
1265
-            return false;
1266
-        }
1267
-
1268
-        // Algorithm is a text string, so we need to remove the quotes.
1269
-        $algo = strtolower(trim($algoParam['raw']));
1270
-        $algo = $this->stripQuotes($algo);
1271
-
1272
-        return $algo;
1273
-    }
1274
-
1275
-
1276
-    /**
1277
-     * Determine whether an arbitrary T_STRING token is the use of a global constant.
1278
-     *
1279
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1280
-     * @param int                   $stackPtr  The position of the function call token.
1281
-     *
1282
-     * @return bool
1283
-     */
1284
-    public function isUseOfGlobalConstant(File $phpcsFile, $stackPtr)
1285
-    {
1286
-        static $isLowPHPCS, $isLowPHP;
1287
-
1288
-        $tokens = $phpcsFile->getTokens();
1289
-
1290
-        // Check for the existence of the token.
1291
-        if (isset($tokens[$stackPtr]) === false) {
1292
-            return false;
1293
-        }
1294
-
1295
-        // Is this one of the tokens this function handles ?
1296
-        if ($tokens[$stackPtr]['code'] !== \T_STRING) {
1297
-            return false;
1298
-        }
1299
-
1300
-        // Check for older PHP, PHPCS version so we can compensate for misidentified tokens.
1301
-        if (isset($isLowPHPCS, $isLowPHP) === false) {
1302
-            $isLowPHP   = false;
1303
-            $isLowPHPCS = false;
1304
-            if (version_compare(\PHP_VERSION_ID, '50400', '<')) {
1305
-                $isLowPHP   = true;
1306
-                $isLowPHPCS = version_compare(PHPCSHelper::getVersion(), '2.4.0', '<');
1307
-            }
1308
-        }
1309
-
1310
-        $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
1311
-        if ($next !== false
1312
-            && ($tokens[$next]['code'] === \T_OPEN_PARENTHESIS
1313
-                || $tokens[$next]['code'] === \T_DOUBLE_COLON)
1314
-        ) {
1315
-            // Function call or declaration.
1316
-            return false;
1317
-        }
1318
-
1319
-        // Array of tokens which if found preceding the $stackPtr indicate that a T_STRING is not a global constant.
1320
-        $tokensToIgnore = array(
1321
-            'T_NAMESPACE'       => true,
1322
-            'T_USE'             => true,
1323
-            'T_CLASS'           => true,
1324
-            'T_TRAIT'           => true,
1325
-            'T_INTERFACE'       => true,
1326
-            'T_EXTENDS'         => true,
1327
-            'T_IMPLEMENTS'      => true,
1328
-            'T_NEW'             => true,
1329
-            'T_FUNCTION'        => true,
1330
-            'T_DOUBLE_COLON'    => true,
1331
-            'T_OBJECT_OPERATOR' => true,
1332
-            'T_INSTANCEOF'      => true,
1333
-            'T_INSTEADOF'       => true,
1334
-            'T_GOTO'            => true,
1335
-            'T_AS'              => true,
1336
-            'T_PUBLIC'          => true,
1337
-            'T_PROTECTED'       => true,
1338
-            'T_PRIVATE'         => true,
1339
-        );
1340
-
1341
-        $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
1342
-        if ($prev !== false
1343
-            && (isset($tokensToIgnore[$tokens[$prev]['type']]) === true
1344
-                || ($tokens[$prev]['code'] === \T_STRING
1345
-                    && (($isLowPHPCS === true
1346
-                        && $tokens[$prev]['content'] === 'trait')
1347
-                    || ($isLowPHP === true
1348
-                        && $tokens[$prev]['content'] === 'insteadof'))))
1349
-        ) {
1350
-            // Not the use of a constant.
1351
-            return false;
1352
-        }
1353
-
1354
-        if ($prev !== false
1355
-            && $tokens[$prev]['code'] === \T_NS_SEPARATOR
1356
-            && $tokens[($prev - 1)]['code'] === \T_STRING
1357
-        ) {
1358
-            // Namespaced constant of the same name.
1359
-            return false;
1360
-        }
1361
-
1362
-        if ($prev !== false
1363
-            && $tokens[$prev]['code'] === \T_CONST
1364
-            && $this->isClassConstant($phpcsFile, $prev) === true
1365
-        ) {
1366
-            // Class constant declaration of the same name.
1367
-            return false;
1368
-        }
1369
-
1370
-        /*
1166
+		$conditions = array_keys($tokens[$stackPtr]['conditions']);
1167
+		$ptr        = array_pop($conditions);
1168
+
1169
+		if (isset($tokens[$ptr]) === false) {
1170
+			return false;
1171
+		}
1172
+
1173
+		if (isset($validScopes[$tokens[$ptr]['type']]) === true) {
1174
+			return $ptr;
1175
+		}
1176
+
1177
+		return false;
1178
+	}
1179
+
1180
+
1181
+	/**
1182
+	 * Get an array of just the type hints from a function declaration.
1183
+	 *
1184
+	 * Expects to be passed T_FUNCTION or T_CLOSURE token.
1185
+	 *
1186
+	 * Strips potential nullable indicator and potential global namespace
1187
+	 * indicator from the type hints before returning them.
1188
+	 *
1189
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1190
+	 * @param int                   $stackPtr  The position of the token.
1191
+	 *
1192
+	 * @return array Array with type hints or an empty array if
1193
+	 *               - the function does not have any parameters
1194
+	 *               - no type hints were found
1195
+	 *               - or the passed token was not of the correct type.
1196
+	 */
1197
+	public function getTypeHintsFromFunctionDeclaration(File $phpcsFile, $stackPtr)
1198
+	{
1199
+		$tokens = $phpcsFile->getTokens();
1200
+
1201
+		if ($tokens[$stackPtr]['code'] !== \T_FUNCTION && $tokens[$stackPtr]['code'] !== \T_CLOSURE) {
1202
+			return array();
1203
+		}
1204
+
1205
+		$parameters = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
1206
+		if (empty($parameters) || \is_array($parameters) === false) {
1207
+			return array();
1208
+		}
1209
+
1210
+		$typeHints = array();
1211
+
1212
+		foreach ($parameters as $param) {
1213
+			if ($param['type_hint'] === '') {
1214
+				continue;
1215
+			}
1216
+
1217
+			// Strip off potential nullable indication.
1218
+			$typeHint = ltrim($param['type_hint'], '?');
1219
+
1220
+			// Strip off potential (global) namespace indication.
1221
+			$typeHint = ltrim($typeHint, '\\');
1222
+
1223
+			if ($typeHint !== '') {
1224
+				$typeHints[] = $typeHint;
1225
+			}
1226
+		}
1227
+
1228
+		return $typeHints;
1229
+	}
1230
+
1231
+
1232
+	/**
1233
+	 * Get the hash algorithm name from the parameter in a hash function call.
1234
+	 *
1235
+	 * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
1236
+	 * @param int                   $stackPtr  The position of the T_STRING function token.
1237
+	 *
1238
+	 * @return string|false The algorithm name without quotes if this was a relevant hash
1239
+	 *                      function call or false if it was not.
1240
+	 */
1241
+	public function getHashAlgorithmParameter(File $phpcsFile, $stackPtr)
1242
+	{
1243
+		$tokens = $phpcsFile->getTokens();
1244
+
1245
+		// Check for the existence of the token.
1246
+		if (isset($tokens[$stackPtr]) === false) {
1247
+			return false;
1248
+		}
1249
+
1250
+		if ($tokens[$stackPtr]['code'] !== \T_STRING) {
1251
+			return false;
1252
+		}
1253
+
1254
+		$functionName   = $tokens[$stackPtr]['content'];
1255
+		$functionNameLc = strtolower($functionName);
1256
+
1257
+		// Bow out if not one of the functions we're targetting.
1258
+		if (isset($this->hashAlgoFunctions[$functionNameLc]) === false) {
1259
+			return false;
1260
+		}
1261
+
1262
+		// Get the parameter from the function call which should contain the algorithm name.
1263
+		$algoParam = $this->getFunctionCallParameter($phpcsFile, $stackPtr, $this->hashAlgoFunctions[$functionNameLc]);
1264
+		if ($algoParam === false) {
1265
+			return false;
1266
+		}
1267
+
1268
+		// Algorithm is a text string, so we need to remove the quotes.
1269
+		$algo = strtolower(trim($algoParam['raw']));
1270
+		$algo = $this->stripQuotes($algo);
1271
+
1272
+		return $algo;
1273
+	}
1274
+
1275
+
1276
+	/**
1277
+	 * Determine whether an arbitrary T_STRING token is the use of a global constant.
1278
+	 *
1279
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1280
+	 * @param int                   $stackPtr  The position of the function call token.
1281
+	 *
1282
+	 * @return bool
1283
+	 */
1284
+	public function isUseOfGlobalConstant(File $phpcsFile, $stackPtr)
1285
+	{
1286
+		static $isLowPHPCS, $isLowPHP;
1287
+
1288
+		$tokens = $phpcsFile->getTokens();
1289
+
1290
+		// Check for the existence of the token.
1291
+		if (isset($tokens[$stackPtr]) === false) {
1292
+			return false;
1293
+		}
1294
+
1295
+		// Is this one of the tokens this function handles ?
1296
+		if ($tokens[$stackPtr]['code'] !== \T_STRING) {
1297
+			return false;
1298
+		}
1299
+
1300
+		// Check for older PHP, PHPCS version so we can compensate for misidentified tokens.
1301
+		if (isset($isLowPHPCS, $isLowPHP) === false) {
1302
+			$isLowPHP   = false;
1303
+			$isLowPHPCS = false;
1304
+			if (version_compare(\PHP_VERSION_ID, '50400', '<')) {
1305
+				$isLowPHP   = true;
1306
+				$isLowPHPCS = version_compare(PHPCSHelper::getVersion(), '2.4.0', '<');
1307
+			}
1308
+		}
1309
+
1310
+		$next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
1311
+		if ($next !== false
1312
+			&& ($tokens[$next]['code'] === \T_OPEN_PARENTHESIS
1313
+				|| $tokens[$next]['code'] === \T_DOUBLE_COLON)
1314
+		) {
1315
+			// Function call or declaration.
1316
+			return false;
1317
+		}
1318
+
1319
+		// Array of tokens which if found preceding the $stackPtr indicate that a T_STRING is not a global constant.
1320
+		$tokensToIgnore = array(
1321
+			'T_NAMESPACE'       => true,
1322
+			'T_USE'             => true,
1323
+			'T_CLASS'           => true,
1324
+			'T_TRAIT'           => true,
1325
+			'T_INTERFACE'       => true,
1326
+			'T_EXTENDS'         => true,
1327
+			'T_IMPLEMENTS'      => true,
1328
+			'T_NEW'             => true,
1329
+			'T_FUNCTION'        => true,
1330
+			'T_DOUBLE_COLON'    => true,
1331
+			'T_OBJECT_OPERATOR' => true,
1332
+			'T_INSTANCEOF'      => true,
1333
+			'T_INSTEADOF'       => true,
1334
+			'T_GOTO'            => true,
1335
+			'T_AS'              => true,
1336
+			'T_PUBLIC'          => true,
1337
+			'T_PROTECTED'       => true,
1338
+			'T_PRIVATE'         => true,
1339
+		);
1340
+
1341
+		$prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
1342
+		if ($prev !== false
1343
+			&& (isset($tokensToIgnore[$tokens[$prev]['type']]) === true
1344
+				|| ($tokens[$prev]['code'] === \T_STRING
1345
+					&& (($isLowPHPCS === true
1346
+						&& $tokens[$prev]['content'] === 'trait')
1347
+					|| ($isLowPHP === true
1348
+						&& $tokens[$prev]['content'] === 'insteadof'))))
1349
+		) {
1350
+			// Not the use of a constant.
1351
+			return false;
1352
+		}
1353
+
1354
+		if ($prev !== false
1355
+			&& $tokens[$prev]['code'] === \T_NS_SEPARATOR
1356
+			&& $tokens[($prev - 1)]['code'] === \T_STRING
1357
+		) {
1358
+			// Namespaced constant of the same name.
1359
+			return false;
1360
+		}
1361
+
1362
+		if ($prev !== false
1363
+			&& $tokens[$prev]['code'] === \T_CONST
1364
+			&& $this->isClassConstant($phpcsFile, $prev) === true
1365
+		) {
1366
+			// Class constant declaration of the same name.
1367
+			return false;
1368
+		}
1369
+
1370
+		/*
1371 1371
          * Deal with a number of variations of use statements.
1372 1372
          */
1373
-        for ($i = $stackPtr; $i > 0; $i--) {
1374
-            if ($tokens[$i]['line'] !== $tokens[$stackPtr]['line']) {
1375
-                break;
1376
-            }
1377
-        }
1378
-
1379
-        $firstOnLine = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true);
1380
-        if ($firstOnLine !== false && $tokens[$firstOnLine]['code'] === \T_USE) {
1381
-            $nextOnLine = $phpcsFile->findNext(Tokens::$emptyTokens, ($firstOnLine + 1), null, true);
1382
-            if ($nextOnLine !== false) {
1383
-                if (($tokens[$nextOnLine]['code'] === \T_STRING && $tokens[$nextOnLine]['content'] === 'const')
1384
-                    || $tokens[$nextOnLine]['code'] === \T_CONST // Happens in some PHPCS versions.
1385
-                ) {
1386
-                    $hasNsSep = $phpcsFile->findNext(\T_NS_SEPARATOR, ($nextOnLine + 1), $stackPtr);
1387
-                    if ($hasNsSep !== false) {
1388
-                        // Namespaced const (group) use statement.
1389
-                        return false;
1390
-                    }
1391
-                } else {
1392
-                    // Not a const use statement.
1393
-                    return false;
1394
-                }
1395
-            }
1396
-        }
1397
-
1398
-        return true;
1399
-    }
1400
-
1401
-
1402
-    /**
1403
-     * Determine whether the tokens between $start and $end together form a positive number
1404
-     * as recognized by PHP.
1405
-     *
1406
-     * The outcome of this function is reliable for `true`, `false` should be regarded as
1407
-     * "undetermined".
1408
-     *
1409
-     * Note: Zero is *not* regarded as a positive number.
1410
-     *
1411
-     * @param \PHP_CodeSniffer_File $phpcsFile   The file being scanned.
1412
-     * @param int                   $start       Start of the snippet (inclusive), i.e. this
1413
-     *                                           token will be examined as part of the snippet.
1414
-     * @param int                   $end         End of the snippet (inclusive), i.e. this
1415
-     *                                           token will be examined as part of the snippet.
1416
-     * @param bool                  $allowFloats Whether to only consider integers, or also floats.
1417
-     *
1418
-     * @return bool True if PHP would evaluate the snippet as a positive number.
1419
-     *              False if not or if it could not be reliably determined
1420
-     *              (variable or calculations and such).
1421
-     */
1422
-    public function isPositiveNumber(File $phpcsFile, $start, $end, $allowFloats = false)
1423
-    {
1424
-        $number = $this->isNumber($phpcsFile, $start, $end, $allowFloats);
1425
-
1426
-        if ($number === false) {
1427
-            return false;
1428
-        }
1429
-
1430
-        return ($number > 0);
1431
-    }
1432
-
1433
-
1434
-    /**
1435
-     * Determine whether the tokens between $start and $end together form a negative number
1436
-     * as recognized by PHP.
1437
-     *
1438
-     * The outcome of this function is reliable for `true`, `false` should be regarded as
1439
-     * "undetermined".
1440
-     *
1441
-     * Note: Zero is *not* regarded as a negative number.
1442
-     *
1443
-     * @param \PHP_CodeSniffer_File $phpcsFile   The file being scanned.
1444
-     * @param int                   $start       Start of the snippet (inclusive), i.e. this
1445
-     *                                           token will be examined as part of the snippet.
1446
-     * @param int                   $end         End of the snippet (inclusive), i.e. this
1447
-     *                                           token will be examined as part of the snippet.
1448
-     * @param bool                  $allowFloats Whether to only consider integers, or also floats.
1449
-     *
1450
-     * @return bool True if PHP would evaluate the snippet as a negative number.
1451
-     *              False if not or if it could not be reliably determined
1452
-     *              (variable or calculations and such).
1453
-     */
1454
-    public function isNegativeNumber(File $phpcsFile, $start, $end, $allowFloats = false)
1455
-    {
1456
-        $number = $this->isNumber($phpcsFile, $start, $end, $allowFloats);
1457
-
1458
-        if ($number === false) {
1459
-            return false;
1460
-        }
1461
-
1462
-        return ($number < 0);
1463
-    }
1464
-
1465
-    /**
1466
-     * Determine whether the tokens between $start and $end together form a number
1467
-     * as recognized by PHP.
1468
-     *
1469
-     * The outcome of this function is reliable for "true-ish" values, `false` should
1470
-     * be regarded as "undetermined".
1471
-     *
1472
-     * @link https://3v4l.org/npTeM
1473
-     *
1474
-     * Mainly intended for examining variable assignments, function call parameters, array values
1475
-     * where the start and end of the snippet to examine is very clear.
1476
-     *
1477
-     * @param \PHP_CodeSniffer_File $phpcsFile   The file being scanned.
1478
-     * @param int                   $start       Start of the snippet (inclusive), i.e. this
1479
-     *                                           token will be examined as part of the snippet.
1480
-     * @param int                   $end         End of the snippet (inclusive), i.e. this
1481
-     *                                           token will be examined as part of the snippet.
1482
-     * @param bool                  $allowFloats Whether to only consider integers, or also floats.
1483
-     *
1484
-     * @return int|float|bool The number found if PHP would evaluate the snippet as a number.
1485
-     *                        The return type will be int if $allowFloats is false, if
1486
-     *                        $allowFloats is true, the return type will be float.
1487
-     *                        False will be returned when the snippet does not evaluate to a
1488
-     *                        number or if it could not be reliably determined
1489
-     *                        (variable or calculations and such).
1490
-     */
1491
-    protected function isNumber(File $phpcsFile, $start, $end, $allowFloats = false)
1492
-    {
1493
-        $stringTokens = Tokens::$heredocTokens + Tokens::$stringTokens;
1494
-
1495
-        $validTokens             = array();
1496
-        $validTokens[\T_LNUMBER] = true;
1497
-        $validTokens[\T_TRUE]    = true; // Evaluates to int 1.
1498
-        $validTokens[\T_FALSE]   = true; // Evaluates to int 0.
1499
-        $validTokens[\T_NULL]    = true; // Evaluates to int 0.
1500
-
1501
-        if ($allowFloats === true) {
1502
-            $validTokens[\T_DNUMBER] = true;
1503
-        }
1504
-
1505
-        $maybeValidTokens = $stringTokens + $validTokens;
1506
-
1507
-        $tokens         = $phpcsFile->getTokens();
1508
-        $searchEnd      = ($end + 1);
1509
-        $negativeNumber = false;
1510
-
1511
-        if (isset($tokens[$start], $tokens[$searchEnd]) === false) {
1512
-            return false;
1513
-        }
1514
-
1515
-        $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $start, $searchEnd, true);
1516
-        while ($nextNonEmpty !== false
1517
-            && ($tokens[$nextNonEmpty]['code'] === \T_PLUS
1518
-            || $tokens[$nextNonEmpty]['code'] === \T_MINUS)
1519
-        ) {
1520
-
1521
-            if ($tokens[$nextNonEmpty]['code'] === \T_MINUS) {
1522
-                $negativeNumber = ($negativeNumber === false) ? true : false;
1523
-            }
1524
-
1525
-            $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), $searchEnd, true);
1526
-        }
1527
-
1528
-        if ($nextNonEmpty === false || isset($maybeValidTokens[$tokens[$nextNonEmpty]['code']]) === false) {
1529
-            return false;
1530
-        }
1531
-
1532
-        $content = false;
1533
-        if ($tokens[$nextNonEmpty]['code'] === \T_LNUMBER
1534
-            || $tokens[$nextNonEmpty]['code'] === \T_DNUMBER
1535
-        ) {
1536
-            $content = (float) $tokens[$nextNonEmpty]['content'];
1537
-        } elseif ($tokens[$nextNonEmpty]['code'] === \T_TRUE) {
1538
-            $content = 1.0;
1539
-        } elseif ($tokens[$nextNonEmpty]['code'] === \T_FALSE
1540
-            || $tokens[$nextNonEmpty]['code'] === \T_NULL
1541
-        ) {
1542
-            $content = 0.0;
1543
-        } elseif (isset($stringTokens[$tokens[$nextNonEmpty]['code']]) === true) {
1544
-
1545
-            if ($tokens[$nextNonEmpty]['code'] === \T_START_HEREDOC
1546
-                || $tokens[$nextNonEmpty]['code'] === \T_START_NOWDOC
1547
-            ) {
1548
-                // Skip past heredoc/nowdoc opener to the first content.
1549
-                $firstDocToken = $phpcsFile->findNext(array(\T_HEREDOC, \T_NOWDOC), ($nextNonEmpty + 1), $searchEnd);
1550
-                if ($firstDocToken === false) {
1551
-                    // Live coding or parse error.
1552
-                    return false;
1553
-                }
1554
-
1555
-                $stringContent = $content = $tokens[$firstDocToken]['content'];
1556
-
1557
-                // Skip forward to the end in preparation for the next part of the examination.
1558
-                $nextNonEmpty = $phpcsFile->findNext(array(\T_END_HEREDOC, \T_END_NOWDOC), ($nextNonEmpty + 1), $searchEnd);
1559
-                if ($nextNonEmpty === false) {
1560
-                    // Live coding or parse error.
1561
-                    return false;
1562
-                }
1563
-            } else {
1564
-                // Gather subsequent lines for a multi-line string.
1565
-                for ($i = $nextNonEmpty; $i < $searchEnd; $i++) {
1566
-                    if ($tokens[$i]['code'] !== $tokens[$nextNonEmpty]['code']) {
1567
-                        break;
1568
-                    }
1569
-                    $content .= $tokens[$i]['content'];
1570
-                }
1571
-
1572
-                $nextNonEmpty  = --$i;
1573
-                $content       = $this->stripQuotes($content);
1574
-                $stringContent = $content;
1575
-            }
1576
-
1577
-            /*
1373
+		for ($i = $stackPtr; $i > 0; $i--) {
1374
+			if ($tokens[$i]['line'] !== $tokens[$stackPtr]['line']) {
1375
+				break;
1376
+			}
1377
+		}
1378
+
1379
+		$firstOnLine = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true);
1380
+		if ($firstOnLine !== false && $tokens[$firstOnLine]['code'] === \T_USE) {
1381
+			$nextOnLine = $phpcsFile->findNext(Tokens::$emptyTokens, ($firstOnLine + 1), null, true);
1382
+			if ($nextOnLine !== false) {
1383
+				if (($tokens[$nextOnLine]['code'] === \T_STRING && $tokens[$nextOnLine]['content'] === 'const')
1384
+					|| $tokens[$nextOnLine]['code'] === \T_CONST // Happens in some PHPCS versions.
1385
+				) {
1386
+					$hasNsSep = $phpcsFile->findNext(\T_NS_SEPARATOR, ($nextOnLine + 1), $stackPtr);
1387
+					if ($hasNsSep !== false) {
1388
+						// Namespaced const (group) use statement.
1389
+						return false;
1390
+					}
1391
+				} else {
1392
+					// Not a const use statement.
1393
+					return false;
1394
+				}
1395
+			}
1396
+		}
1397
+
1398
+		return true;
1399
+	}
1400
+
1401
+
1402
+	/**
1403
+	 * Determine whether the tokens between $start and $end together form a positive number
1404
+	 * as recognized by PHP.
1405
+	 *
1406
+	 * The outcome of this function is reliable for `true`, `false` should be regarded as
1407
+	 * "undetermined".
1408
+	 *
1409
+	 * Note: Zero is *not* regarded as a positive number.
1410
+	 *
1411
+	 * @param \PHP_CodeSniffer_File $phpcsFile   The file being scanned.
1412
+	 * @param int                   $start       Start of the snippet (inclusive), i.e. this
1413
+	 *                                           token will be examined as part of the snippet.
1414
+	 * @param int                   $end         End of the snippet (inclusive), i.e. this
1415
+	 *                                           token will be examined as part of the snippet.
1416
+	 * @param bool                  $allowFloats Whether to only consider integers, or also floats.
1417
+	 *
1418
+	 * @return bool True if PHP would evaluate the snippet as a positive number.
1419
+	 *              False if not or if it could not be reliably determined
1420
+	 *              (variable or calculations and such).
1421
+	 */
1422
+	public function isPositiveNumber(File $phpcsFile, $start, $end, $allowFloats = false)
1423
+	{
1424
+		$number = $this->isNumber($phpcsFile, $start, $end, $allowFloats);
1425
+
1426
+		if ($number === false) {
1427
+			return false;
1428
+		}
1429
+
1430
+		return ($number > 0);
1431
+	}
1432
+
1433
+
1434
+	/**
1435
+	 * Determine whether the tokens between $start and $end together form a negative number
1436
+	 * as recognized by PHP.
1437
+	 *
1438
+	 * The outcome of this function is reliable for `true`, `false` should be regarded as
1439
+	 * "undetermined".
1440
+	 *
1441
+	 * Note: Zero is *not* regarded as a negative number.
1442
+	 *
1443
+	 * @param \PHP_CodeSniffer_File $phpcsFile   The file being scanned.
1444
+	 * @param int                   $start       Start of the snippet (inclusive), i.e. this
1445
+	 *                                           token will be examined as part of the snippet.
1446
+	 * @param int                   $end         End of the snippet (inclusive), i.e. this
1447
+	 *                                           token will be examined as part of the snippet.
1448
+	 * @param bool                  $allowFloats Whether to only consider integers, or also floats.
1449
+	 *
1450
+	 * @return bool True if PHP would evaluate the snippet as a negative number.
1451
+	 *              False if not or if it could not be reliably determined
1452
+	 *              (variable or calculations and such).
1453
+	 */
1454
+	public function isNegativeNumber(File $phpcsFile, $start, $end, $allowFloats = false)
1455
+	{
1456
+		$number = $this->isNumber($phpcsFile, $start, $end, $allowFloats);
1457
+
1458
+		if ($number === false) {
1459
+			return false;
1460
+		}
1461
+
1462
+		return ($number < 0);
1463
+	}
1464
+
1465
+	/**
1466
+	 * Determine whether the tokens between $start and $end together form a number
1467
+	 * as recognized by PHP.
1468
+	 *
1469
+	 * The outcome of this function is reliable for "true-ish" values, `false` should
1470
+	 * be regarded as "undetermined".
1471
+	 *
1472
+	 * @link https://3v4l.org/npTeM
1473
+	 *
1474
+	 * Mainly intended for examining variable assignments, function call parameters, array values
1475
+	 * where the start and end of the snippet to examine is very clear.
1476
+	 *
1477
+	 * @param \PHP_CodeSniffer_File $phpcsFile   The file being scanned.
1478
+	 * @param int                   $start       Start of the snippet (inclusive), i.e. this
1479
+	 *                                           token will be examined as part of the snippet.
1480
+	 * @param int                   $end         End of the snippet (inclusive), i.e. this
1481
+	 *                                           token will be examined as part of the snippet.
1482
+	 * @param bool                  $allowFloats Whether to only consider integers, or also floats.
1483
+	 *
1484
+	 * @return int|float|bool The number found if PHP would evaluate the snippet as a number.
1485
+	 *                        The return type will be int if $allowFloats is false, if
1486
+	 *                        $allowFloats is true, the return type will be float.
1487
+	 *                        False will be returned when the snippet does not evaluate to a
1488
+	 *                        number or if it could not be reliably determined
1489
+	 *                        (variable or calculations and such).
1490
+	 */
1491
+	protected function isNumber(File $phpcsFile, $start, $end, $allowFloats = false)
1492
+	{
1493
+		$stringTokens = Tokens::$heredocTokens + Tokens::$stringTokens;
1494
+
1495
+		$validTokens             = array();
1496
+		$validTokens[\T_LNUMBER] = true;
1497
+		$validTokens[\T_TRUE]    = true; // Evaluates to int 1.
1498
+		$validTokens[\T_FALSE]   = true; // Evaluates to int 0.
1499
+		$validTokens[\T_NULL]    = true; // Evaluates to int 0.
1500
+
1501
+		if ($allowFloats === true) {
1502
+			$validTokens[\T_DNUMBER] = true;
1503
+		}
1504
+
1505
+		$maybeValidTokens = $stringTokens + $validTokens;
1506
+
1507
+		$tokens         = $phpcsFile->getTokens();
1508
+		$searchEnd      = ($end + 1);
1509
+		$negativeNumber = false;
1510
+
1511
+		if (isset($tokens[$start], $tokens[$searchEnd]) === false) {
1512
+			return false;
1513
+		}
1514
+
1515
+		$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $start, $searchEnd, true);
1516
+		while ($nextNonEmpty !== false
1517
+			&& ($tokens[$nextNonEmpty]['code'] === \T_PLUS
1518
+			|| $tokens[$nextNonEmpty]['code'] === \T_MINUS)
1519
+		) {
1520
+
1521
+			if ($tokens[$nextNonEmpty]['code'] === \T_MINUS) {
1522
+				$negativeNumber = ($negativeNumber === false) ? true : false;
1523
+			}
1524
+
1525
+			$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), $searchEnd, true);
1526
+		}
1527
+
1528
+		if ($nextNonEmpty === false || isset($maybeValidTokens[$tokens[$nextNonEmpty]['code']]) === false) {
1529
+			return false;
1530
+		}
1531
+
1532
+		$content = false;
1533
+		if ($tokens[$nextNonEmpty]['code'] === \T_LNUMBER
1534
+			|| $tokens[$nextNonEmpty]['code'] === \T_DNUMBER
1535
+		) {
1536
+			$content = (float) $tokens[$nextNonEmpty]['content'];
1537
+		} elseif ($tokens[$nextNonEmpty]['code'] === \T_TRUE) {
1538
+			$content = 1.0;
1539
+		} elseif ($tokens[$nextNonEmpty]['code'] === \T_FALSE
1540
+			|| $tokens[$nextNonEmpty]['code'] === \T_NULL
1541
+		) {
1542
+			$content = 0.0;
1543
+		} elseif (isset($stringTokens[$tokens[$nextNonEmpty]['code']]) === true) {
1544
+
1545
+			if ($tokens[$nextNonEmpty]['code'] === \T_START_HEREDOC
1546
+				|| $tokens[$nextNonEmpty]['code'] === \T_START_NOWDOC
1547
+			) {
1548
+				// Skip past heredoc/nowdoc opener to the first content.
1549
+				$firstDocToken = $phpcsFile->findNext(array(\T_HEREDOC, \T_NOWDOC), ($nextNonEmpty + 1), $searchEnd);
1550
+				if ($firstDocToken === false) {
1551
+					// Live coding or parse error.
1552
+					return false;
1553
+				}
1554
+
1555
+				$stringContent = $content = $tokens[$firstDocToken]['content'];
1556
+
1557
+				// Skip forward to the end in preparation for the next part of the examination.
1558
+				$nextNonEmpty = $phpcsFile->findNext(array(\T_END_HEREDOC, \T_END_NOWDOC), ($nextNonEmpty + 1), $searchEnd);
1559
+				if ($nextNonEmpty === false) {
1560
+					// Live coding or parse error.
1561
+					return false;
1562
+				}
1563
+			} else {
1564
+				// Gather subsequent lines for a multi-line string.
1565
+				for ($i = $nextNonEmpty; $i < $searchEnd; $i++) {
1566
+					if ($tokens[$i]['code'] !== $tokens[$nextNonEmpty]['code']) {
1567
+						break;
1568
+					}
1569
+					$content .= $tokens[$i]['content'];
1570
+				}
1571
+
1572
+				$nextNonEmpty  = --$i;
1573
+				$content       = $this->stripQuotes($content);
1574
+				$stringContent = $content;
1575
+			}
1576
+
1577
+			/*
1578 1578
              * Regexes based on the formats outlined in the manual, created by JRF.
1579 1579
              * @link http://php.net/manual/en/language.types.float.php
1580 1580
              */
1581
-            $regexInt   = '`^\s*[0-9]+`';
1582
-            $regexFloat = '`^\s*(?:[+-]?(?:(?:(?P<LNUM>[0-9]+)|(?P<DNUM>([0-9]*\.(?P>LNUM)|(?P>LNUM)\.[0-9]*)))[eE][+-]?(?P>LNUM))|(?P>DNUM))`';
1583
-
1584
-            $intString   = preg_match($regexInt, $content, $intMatch);
1585
-            $floatString = preg_match($regexFloat, $content, $floatMatch);
1586
-
1587
-            // Does the text string start with a number ? If so, PHP would juggle it and use it as a number.
1588
-            if ($allowFloats === false) {
1589
-                if ($intString !== 1 || $floatString === 1) {
1590
-                    if ($floatString === 1) {
1591
-                        // Found float. Only integers targetted.
1592
-                        return false;
1593
-                    }
1594
-
1595
-                    $content = 0.0;
1596
-                } else {
1597
-                    $content = (float) trim($intMatch[0]);
1598
-                }
1599
-            } else {
1600
-                if ($intString !== 1 && $floatString !== 1) {
1601
-                    $content = 0.0;
1602
-                } else {
1603
-                    $content = ($floatString === 1) ? (float) trim($floatMatch[0]) : (float) trim($intMatch[0]);
1604
-                }
1605
-            }
1606
-
1607
-            // Allow for different behaviour for hex numeric strings between PHP 5 vs PHP 7.
1608
-            if ($intString === 1 && trim($intMatch[0]) === '0'
1609
-                && preg_match('`^\s*(0x[A-Fa-f0-9]+)`', $stringContent, $hexNumberString) === 1
1610
-                && $this->supportsBelow('5.6') === true
1611
-            ) {
1612
-                // The filter extension still allows for hex numeric strings in PHP 7, so
1613
-                // use that to get the numeric value if possible.
1614
-                // If the filter extension is not available, the value will be zero, but so be it.
1615
-                if (function_exists('filter_var')) {
1616
-                    $filtered = filter_var($hexNumberString[1], \FILTER_VALIDATE_INT, \FILTER_FLAG_ALLOW_HEX);
1617
-                    if ($filtered !== false) {
1618
-                        $content = $filtered;
1619
-                    }
1620
-                }
1621
-            }
1622
-        }
1623
-
1624
-        // OK, so we have a number, now is there still more code after it ?
1625
-        $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), $searchEnd, true);
1626
-        if ($nextNonEmpty !== false) {
1627
-            return false;
1628
-        }
1629
-
1630
-        if ($negativeNumber === true) {
1631
-            $content = -$content;
1632
-        }
1633
-
1634
-        if ($allowFloats === false) {
1635
-            return (int) $content;
1636
-        }
1637
-
1638
-        return $content;
1639
-    }
1640
-
1641
-
1642
-    /**
1643
-     * Determine whether the tokens between $start and $end together form a numberic calculation
1644
-     * as recognized by PHP.
1645
-     *
1646
-     * The outcome of this function is reliable for `true`, `false` should be regarded as "undetermined".
1647
-     *
1648
-     * Mainly intended for examining variable assignments, function call parameters, array values
1649
-     * where the start and end of the snippet to examine is very clear.
1650
-     *
1651
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1652
-     * @param int                   $start     Start of the snippet (inclusive), i.e. this
1653
-     *                                         token will be examined as part of the snippet.
1654
-     * @param int                   $end       End of the snippet (inclusive), i.e. this
1655
-     *                                         token will be examined as part of the snippet.
1656
-     *
1657
-     * @return bool
1658
-     */
1659
-    protected function isNumericCalculation(File $phpcsFile, $start, $end)
1660
-    {
1661
-        $arithmeticTokens = Tokens::$arithmeticTokens;
1662
-
1663
-        // phpcs:disable PHPCompatibility.Constants.NewConstants.t_powFound
1664
-        if (\defined('T_POW') && isset($arithmeticTokens[\T_POW]) === false) {
1665
-            // T_POW was not added to the arithmetic array until PHPCS 2.9.0.
1666
-            $arithmeticTokens[\T_POW] = \T_POW;
1667
-        }
1668
-        // phpcs:enable
1669
-
1670
-        $skipTokens   = Tokens::$emptyTokens;
1671
-        $skipTokens[] = \T_MINUS;
1672
-        $skipTokens[] = \T_PLUS;
1673
-
1674
-        // Find the first arithmetic operator, but skip past +/- signs before numbers.
1675
-        $nextNonEmpty = ($start - 1);
1676
-        do {
1677
-            $nextNonEmpty       = $phpcsFile->findNext($skipTokens, ($nextNonEmpty + 1), ($end + 1), true);
1678
-            $arithmeticOperator = $phpcsFile->findNext($arithmeticTokens, ($nextNonEmpty + 1), ($end + 1));
1679
-        } while ($nextNonEmpty !== false && $arithmeticOperator !== false && $nextNonEmpty === $arithmeticOperator);
1680
-
1681
-        if ($arithmeticOperator === false) {
1682
-            return false;
1683
-        }
1684
-
1685
-        $tokens      = $phpcsFile->getTokens();
1686
-        $subsetStart = $start;
1687
-        $subsetEnd   = ($arithmeticOperator - 1);
1688
-
1689
-        while ($this->isNumber($phpcsFile, $subsetStart, $subsetEnd, true) !== false
1690
-            && isset($tokens[($arithmeticOperator + 1)]) === true
1691
-        ) {
1692
-            // Recognize T_POW for PHPCS < 2.4.0 on low PHP versions.
1693
-            if (\defined('T_POW') === false
1694
-                && $tokens[$arithmeticOperator]['code'] === \T_MULTIPLY
1695
-                && $tokens[($arithmeticOperator + 1)]['code'] === \T_MULTIPLY
1696
-                && isset($tokens[$arithmeticOperator + 2]) === true
1697
-            ) {
1698
-                // Move operator one forward to the second * in T_POW.
1699
-                ++$arithmeticOperator;
1700
-            }
1701
-
1702
-            $subsetStart  = ($arithmeticOperator + 1);
1703
-            $nextNonEmpty = $arithmeticOperator;
1704
-            do {
1705
-                $nextNonEmpty       = $phpcsFile->findNext($skipTokens, ($nextNonEmpty + 1), ($end + 1), true);
1706
-                $arithmeticOperator = $phpcsFile->findNext($arithmeticTokens, ($nextNonEmpty + 1), ($end + 1));
1707
-            } while ($nextNonEmpty !== false && $arithmeticOperator !== false && $nextNonEmpty === $arithmeticOperator);
1708
-
1709
-            if ($arithmeticOperator === false) {
1710
-                // Last calculation operator already reached.
1711
-                if ($this->isNumber($phpcsFile, $subsetStart, $end, true) !== false) {
1712
-                    return true;
1713
-                }
1714
-
1715
-                return false;
1716
-            }
1717
-
1718
-            $subsetEnd = ($arithmeticOperator - 1);
1719
-        }
1720
-
1721
-        return false;
1722
-    }
1723
-
1724
-
1725
-
1726
-    /**
1727
-     * Determine whether a ternary is a short ternary, i.e. without "middle".
1728
-     *
1729
-     * N.B.: This is a back-fill for a new method which is expected to go into
1730
-     * PHP_CodeSniffer 3.5.0.
1731
-     * Once that method has been merged into PHPCS, this one should be moved
1732
-     * to the PHPCSHelper.php file.
1733
-     *
1734
-     * @since 9.2.0
1735
-     *
1736
-     * @codeCoverageIgnore Method as pulled upstream is accompanied by unit tests.
1737
-     *
1738
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1739
-     * @param int                   $stackPtr  The position of the ternary operator
1740
-     *                                         in the stack.
1741
-     *
1742
-     * @return bool True if short ternary, or false otherwise.
1743
-     */
1744
-    public function isShortTernary(File $phpcsFile, $stackPtr)
1745
-    {
1746
-        $tokens = $phpcsFile->getTokens();
1747
-        if (isset($tokens[$stackPtr]) === false
1748
-            || $tokens[$stackPtr]['code'] !== \T_INLINE_THEN
1749
-        ) {
1750
-            return false;
1751
-        }
1752
-
1753
-        $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
1754
-        if ($nextNonEmpty === false) {
1755
-            // Live coding or parse error.
1756
-            return false;
1757
-        }
1758
-
1759
-        if ($tokens[$nextNonEmpty]['code'] === \T_INLINE_ELSE) {
1760
-            return true;
1761
-        }
1762
-
1763
-        return false;
1764
-    }
1765
-
1766
-
1767
-    /**
1768
-     * Determine whether a T_OPEN/CLOSE_SHORT_ARRAY token is a list() construct.
1769
-     *
1770
-     * Note: A variety of PHPCS versions have bugs in the tokenizing of short arrays.
1771
-     * In that case, the tokens are identified as T_OPEN/CLOSE_SQUARE_BRACKET.
1772
-     *
1773
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1774
-     * @param int                   $stackPtr  The position of the function call token.
1775
-     *
1776
-     * @return bool
1777
-     */
1778
-    public function isShortList(File $phpcsFile, $stackPtr)
1779
-    {
1780
-        $tokens = $phpcsFile->getTokens();
1781
-
1782
-        // Check for the existence of the token.
1783
-        if (isset($tokens[$stackPtr]) === false) {
1784
-            return false;
1785
-        }
1786
-
1787
-        // Is this one of the tokens this function handles ?
1788
-        if ($tokens[$stackPtr]['code'] !== \T_OPEN_SHORT_ARRAY
1789
-            && $tokens[$stackPtr]['code'] !== \T_CLOSE_SHORT_ARRAY
1790
-        ) {
1791
-            return false;
1792
-        }
1793
-
1794
-        switch ($tokens[$stackPtr]['code']) {
1795
-            case \T_OPEN_SHORT_ARRAY:
1796
-                if (isset($tokens[$stackPtr]['bracket_closer']) === true) {
1797
-                    $opener = $stackPtr;
1798
-                    $closer = $tokens[$stackPtr]['bracket_closer'];
1799
-                }
1800
-                break;
1801
-
1802
-            case \T_CLOSE_SHORT_ARRAY:
1803
-                if (isset($tokens[$stackPtr]['bracket_opener']) === true) {
1804
-                    $opener = $tokens[$stackPtr]['bracket_opener'];
1805
-                    $closer = $stackPtr;
1806
-                }
1807
-                break;
1808
-        }
1809
-
1810
-        if (isset($opener, $closer) === false) {
1811
-            // Parse error, live coding or real square bracket.
1812
-            return false;
1813
-        }
1814
-
1815
-        /*
1581
+			$regexInt   = '`^\s*[0-9]+`';
1582
+			$regexFloat = '`^\s*(?:[+-]?(?:(?:(?P<LNUM>[0-9]+)|(?P<DNUM>([0-9]*\.(?P>LNUM)|(?P>LNUM)\.[0-9]*)))[eE][+-]?(?P>LNUM))|(?P>DNUM))`';
1583
+
1584
+			$intString   = preg_match($regexInt, $content, $intMatch);
1585
+			$floatString = preg_match($regexFloat, $content, $floatMatch);
1586
+
1587
+			// Does the text string start with a number ? If so, PHP would juggle it and use it as a number.
1588
+			if ($allowFloats === false) {
1589
+				if ($intString !== 1 || $floatString === 1) {
1590
+					if ($floatString === 1) {
1591
+						// Found float. Only integers targetted.
1592
+						return false;
1593
+					}
1594
+
1595
+					$content = 0.0;
1596
+				} else {
1597
+					$content = (float) trim($intMatch[0]);
1598
+				}
1599
+			} else {
1600
+				if ($intString !== 1 && $floatString !== 1) {
1601
+					$content = 0.0;
1602
+				} else {
1603
+					$content = ($floatString === 1) ? (float) trim($floatMatch[0]) : (float) trim($intMatch[0]);
1604
+				}
1605
+			}
1606
+
1607
+			// Allow for different behaviour for hex numeric strings between PHP 5 vs PHP 7.
1608
+			if ($intString === 1 && trim($intMatch[0]) === '0'
1609
+				&& preg_match('`^\s*(0x[A-Fa-f0-9]+)`', $stringContent, $hexNumberString) === 1
1610
+				&& $this->supportsBelow('5.6') === true
1611
+			) {
1612
+				// The filter extension still allows for hex numeric strings in PHP 7, so
1613
+				// use that to get the numeric value if possible.
1614
+				// If the filter extension is not available, the value will be zero, but so be it.
1615
+				if (function_exists('filter_var')) {
1616
+					$filtered = filter_var($hexNumberString[1], \FILTER_VALIDATE_INT, \FILTER_FLAG_ALLOW_HEX);
1617
+					if ($filtered !== false) {
1618
+						$content = $filtered;
1619
+					}
1620
+				}
1621
+			}
1622
+		}
1623
+
1624
+		// OK, so we have a number, now is there still more code after it ?
1625
+		$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonEmpty + 1), $searchEnd, true);
1626
+		if ($nextNonEmpty !== false) {
1627
+			return false;
1628
+		}
1629
+
1630
+		if ($negativeNumber === true) {
1631
+			$content = -$content;
1632
+		}
1633
+
1634
+		if ($allowFloats === false) {
1635
+			return (int) $content;
1636
+		}
1637
+
1638
+		return $content;
1639
+	}
1640
+
1641
+
1642
+	/**
1643
+	 * Determine whether the tokens between $start and $end together form a numberic calculation
1644
+	 * as recognized by PHP.
1645
+	 *
1646
+	 * The outcome of this function is reliable for `true`, `false` should be regarded as "undetermined".
1647
+	 *
1648
+	 * Mainly intended for examining variable assignments, function call parameters, array values
1649
+	 * where the start and end of the snippet to examine is very clear.
1650
+	 *
1651
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1652
+	 * @param int                   $start     Start of the snippet (inclusive), i.e. this
1653
+	 *                                         token will be examined as part of the snippet.
1654
+	 * @param int                   $end       End of the snippet (inclusive), i.e. this
1655
+	 *                                         token will be examined as part of the snippet.
1656
+	 *
1657
+	 * @return bool
1658
+	 */
1659
+	protected function isNumericCalculation(File $phpcsFile, $start, $end)
1660
+	{
1661
+		$arithmeticTokens = Tokens::$arithmeticTokens;
1662
+
1663
+		// phpcs:disable PHPCompatibility.Constants.NewConstants.t_powFound
1664
+		if (\defined('T_POW') && isset($arithmeticTokens[\T_POW]) === false) {
1665
+			// T_POW was not added to the arithmetic array until PHPCS 2.9.0.
1666
+			$arithmeticTokens[\T_POW] = \T_POW;
1667
+		}
1668
+		// phpcs:enable
1669
+
1670
+		$skipTokens   = Tokens::$emptyTokens;
1671
+		$skipTokens[] = \T_MINUS;
1672
+		$skipTokens[] = \T_PLUS;
1673
+
1674
+		// Find the first arithmetic operator, but skip past +/- signs before numbers.
1675
+		$nextNonEmpty = ($start - 1);
1676
+		do {
1677
+			$nextNonEmpty       = $phpcsFile->findNext($skipTokens, ($nextNonEmpty + 1), ($end + 1), true);
1678
+			$arithmeticOperator = $phpcsFile->findNext($arithmeticTokens, ($nextNonEmpty + 1), ($end + 1));
1679
+		} while ($nextNonEmpty !== false && $arithmeticOperator !== false && $nextNonEmpty === $arithmeticOperator);
1680
+
1681
+		if ($arithmeticOperator === false) {
1682
+			return false;
1683
+		}
1684
+
1685
+		$tokens      = $phpcsFile->getTokens();
1686
+		$subsetStart = $start;
1687
+		$subsetEnd   = ($arithmeticOperator - 1);
1688
+
1689
+		while ($this->isNumber($phpcsFile, $subsetStart, $subsetEnd, true) !== false
1690
+			&& isset($tokens[($arithmeticOperator + 1)]) === true
1691
+		) {
1692
+			// Recognize T_POW for PHPCS < 2.4.0 on low PHP versions.
1693
+			if (\defined('T_POW') === false
1694
+				&& $tokens[$arithmeticOperator]['code'] === \T_MULTIPLY
1695
+				&& $tokens[($arithmeticOperator + 1)]['code'] === \T_MULTIPLY
1696
+				&& isset($tokens[$arithmeticOperator + 2]) === true
1697
+			) {
1698
+				// Move operator one forward to the second * in T_POW.
1699
+				++$arithmeticOperator;
1700
+			}
1701
+
1702
+			$subsetStart  = ($arithmeticOperator + 1);
1703
+			$nextNonEmpty = $arithmeticOperator;
1704
+			do {
1705
+				$nextNonEmpty       = $phpcsFile->findNext($skipTokens, ($nextNonEmpty + 1), ($end + 1), true);
1706
+				$arithmeticOperator = $phpcsFile->findNext($arithmeticTokens, ($nextNonEmpty + 1), ($end + 1));
1707
+			} while ($nextNonEmpty !== false && $arithmeticOperator !== false && $nextNonEmpty === $arithmeticOperator);
1708
+
1709
+			if ($arithmeticOperator === false) {
1710
+				// Last calculation operator already reached.
1711
+				if ($this->isNumber($phpcsFile, $subsetStart, $end, true) !== false) {
1712
+					return true;
1713
+				}
1714
+
1715
+				return false;
1716
+			}
1717
+
1718
+			$subsetEnd = ($arithmeticOperator - 1);
1719
+		}
1720
+
1721
+		return false;
1722
+	}
1723
+
1724
+
1725
+
1726
+	/**
1727
+	 * Determine whether a ternary is a short ternary, i.e. without "middle".
1728
+	 *
1729
+	 * N.B.: This is a back-fill for a new method which is expected to go into
1730
+	 * PHP_CodeSniffer 3.5.0.
1731
+	 * Once that method has been merged into PHPCS, this one should be moved
1732
+	 * to the PHPCSHelper.php file.
1733
+	 *
1734
+	 * @since 9.2.0
1735
+	 *
1736
+	 * @codeCoverageIgnore Method as pulled upstream is accompanied by unit tests.
1737
+	 *
1738
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1739
+	 * @param int                   $stackPtr  The position of the ternary operator
1740
+	 *                                         in the stack.
1741
+	 *
1742
+	 * @return bool True if short ternary, or false otherwise.
1743
+	 */
1744
+	public function isShortTernary(File $phpcsFile, $stackPtr)
1745
+	{
1746
+		$tokens = $phpcsFile->getTokens();
1747
+		if (isset($tokens[$stackPtr]) === false
1748
+			|| $tokens[$stackPtr]['code'] !== \T_INLINE_THEN
1749
+		) {
1750
+			return false;
1751
+		}
1752
+
1753
+		$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
1754
+		if ($nextNonEmpty === false) {
1755
+			// Live coding or parse error.
1756
+			return false;
1757
+		}
1758
+
1759
+		if ($tokens[$nextNonEmpty]['code'] === \T_INLINE_ELSE) {
1760
+			return true;
1761
+		}
1762
+
1763
+		return false;
1764
+	}
1765
+
1766
+
1767
+	/**
1768
+	 * Determine whether a T_OPEN/CLOSE_SHORT_ARRAY token is a list() construct.
1769
+	 *
1770
+	 * Note: A variety of PHPCS versions have bugs in the tokenizing of short arrays.
1771
+	 * In that case, the tokens are identified as T_OPEN/CLOSE_SQUARE_BRACKET.
1772
+	 *
1773
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
1774
+	 * @param int                   $stackPtr  The position of the function call token.
1775
+	 *
1776
+	 * @return bool
1777
+	 */
1778
+	public function isShortList(File $phpcsFile, $stackPtr)
1779
+	{
1780
+		$tokens = $phpcsFile->getTokens();
1781
+
1782
+		// Check for the existence of the token.
1783
+		if (isset($tokens[$stackPtr]) === false) {
1784
+			return false;
1785
+		}
1786
+
1787
+		// Is this one of the tokens this function handles ?
1788
+		if ($tokens[$stackPtr]['code'] !== \T_OPEN_SHORT_ARRAY
1789
+			&& $tokens[$stackPtr]['code'] !== \T_CLOSE_SHORT_ARRAY
1790
+		) {
1791
+			return false;
1792
+		}
1793
+
1794
+		switch ($tokens[$stackPtr]['code']) {
1795
+			case \T_OPEN_SHORT_ARRAY:
1796
+				if (isset($tokens[$stackPtr]['bracket_closer']) === true) {
1797
+					$opener = $stackPtr;
1798
+					$closer = $tokens[$stackPtr]['bracket_closer'];
1799
+				}
1800
+				break;
1801
+
1802
+			case \T_CLOSE_SHORT_ARRAY:
1803
+				if (isset($tokens[$stackPtr]['bracket_opener']) === true) {
1804
+					$opener = $tokens[$stackPtr]['bracket_opener'];
1805
+					$closer = $stackPtr;
1806
+				}
1807
+				break;
1808
+		}
1809
+
1810
+		if (isset($opener, $closer) === false) {
1811
+			// Parse error, live coding or real square bracket.
1812
+			return false;
1813
+		}
1814
+
1815
+		/*
1816 1816
          * PHPCS cross-version compatibility: work around for square brackets misidentified
1817 1817
          * as short array when preceded by a variable variable in older PHPCS versions.
1818 1818
          */
1819
-        $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($opener - 1), null, true, null, true);
1820
-
1821
-        if ($prevNonEmpty !== false
1822
-            && $tokens[$prevNonEmpty]['code'] === \T_CLOSE_CURLY_BRACKET
1823
-            && isset($tokens[$prevNonEmpty]['bracket_opener']) === true
1824
-        ) {
1825
-            $maybeVariableVariable = $phpcsFile->findPrevious(
1826
-                Tokens::$emptyTokens,
1827
-                ($tokens[$prevNonEmpty]['bracket_opener'] - 1),
1828
-                null,
1829
-                true,
1830
-                null,
1831
-                true
1832
-            );
1833
-
1834
-            if ($tokens[$maybeVariableVariable]['code'] === \T_VARIABLE
1835
-                || $tokens[$maybeVariableVariable]['code'] === \T_DOLLAR
1836
-            ) {
1837
-                return false;
1838
-            }
1839
-        }
1840
-
1841
-        $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($closer + 1), null, true, null, true);
1842
-
1843
-        if ($nextNonEmpty !== false && $tokens[$nextNonEmpty]['code'] === \T_EQUAL) {
1844
-            return true;
1845
-        }
1846
-
1847
-        if ($prevNonEmpty !== false
1848
-            && $tokens[$prevNonEmpty]['code'] === \T_AS
1849
-            && isset($tokens[$prevNonEmpty]['nested_parenthesis']) === true
1850
-        ) {
1851
-            $parentheses = array_reverse($tokens[$prevNonEmpty]['nested_parenthesis'], true);
1852
-            foreach ($parentheses as $open => $close) {
1853
-                if (isset($tokens[$open]['parenthesis_owner'])
1854
-                    && $tokens[$tokens[$open]['parenthesis_owner']]['code'] === \T_FOREACH
1855
-                ) {
1856
-                    return true;
1857
-                }
1858
-            }
1859
-        }
1860
-
1861
-        // Maybe this is a short list syntax nested inside another short list syntax ?
1862
-        $parentOpener = $opener;
1863
-        do {
1864
-            $parentOpener = $phpcsFile->findPrevious(
1865
-                array(\T_OPEN_SHORT_ARRAY, \T_OPEN_SQUARE_BRACKET),
1866
-                ($parentOpener - 1),
1867
-                null,
1868
-                false,
1869
-                null,
1870
-                true
1871
-            );
1872
-
1873
-            if ($parentOpener === false) {
1874
-                return false;
1875
-            }
1876
-
1877
-        } while (isset($tokens[$parentOpener]['bracket_closer']) === true
1878
-            && $tokens[$parentOpener]['bracket_closer'] < $opener
1879
-        );
1880
-
1881
-        if (isset($tokens[$parentOpener]['bracket_closer']) === true
1882
-            && $tokens[$parentOpener]['bracket_closer'] > $closer
1883
-        ) {
1884
-            // Work around tokenizer issue in PHPCS 2.0 - 2.7.
1885
-            $phpcsVersion = PHPCSHelper::getVersion();
1886
-            if ((version_compare($phpcsVersion, '2.0', '>') === true
1887
-                && version_compare($phpcsVersion, '2.8', '<') === true)
1888
-                && $tokens[$parentOpener]['code'] === \T_OPEN_SQUARE_BRACKET
1889
-            ) {
1890
-                $nextNonEmpty = $phpcsFile->findNext(
1891
-                    Tokens::$emptyTokens,
1892
-                    ($tokens[$parentOpener]['bracket_closer'] + 1),
1893
-                    null,
1894
-                    true,
1895
-                    null,
1896
-                    true
1897
-                );
1898
-
1899
-                if ($nextNonEmpty !== false && $tokens[$nextNonEmpty]['code'] === \T_EQUAL) {
1900
-                    return true;
1901
-                }
1902
-
1903
-                return false;
1904
-            }
1905
-
1906
-            return $this->isShortList($phpcsFile, $parentOpener);
1907
-        }
1908
-
1909
-        return false;
1910
-    }
1911
-
1912
-
1913
-    /**
1914
-     * Determine whether the tokens between $start and $end could together represent a variable.
1915
-     *
1916
-     * @param \PHP_CodeSniffer_File $phpcsFile          The file being scanned.
1917
-     * @param int                   $start              Starting point stack pointer. Inclusive.
1918
-     *                                                  I.e. this token should be taken into account.
1919
-     * @param int                   $end                End point stack pointer. Exclusive.
1920
-     *                                                  I.e. this token should not be taken into account.
1921
-     * @param int                   $targetNestingLevel The nesting level the variable should be at.
1922
-     *
1923
-     * @return bool
1924
-     */
1925
-    public function isVariable(File $phpcsFile, $start, $end, $targetNestingLevel)
1926
-    {
1927
-        static $tokenBlackList, $bracketTokens;
1928
-
1929
-        // Create the token arrays only once.
1930
-        if (isset($tokenBlackList, $bracketTokens) === false) {
1931
-
1932
-            $tokenBlackList  = array(
1933
-                \T_OPEN_PARENTHESIS => \T_OPEN_PARENTHESIS,
1934
-                \T_STRING_CONCAT    => \T_STRING_CONCAT,
1935
-            );
1936
-            $tokenBlackList += Tokens::$assignmentTokens;
1937
-            $tokenBlackList += Tokens::$equalityTokens;
1938
-            $tokenBlackList += Tokens::$comparisonTokens;
1939
-            $tokenBlackList += Tokens::$operators;
1940
-            $tokenBlackList += Tokens::$booleanOperators;
1941
-            $tokenBlackList += Tokens::$castTokens;
1942
-
1943
-            /*
1819
+		$prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($opener - 1), null, true, null, true);
1820
+
1821
+		if ($prevNonEmpty !== false
1822
+			&& $tokens[$prevNonEmpty]['code'] === \T_CLOSE_CURLY_BRACKET
1823
+			&& isset($tokens[$prevNonEmpty]['bracket_opener']) === true
1824
+		) {
1825
+			$maybeVariableVariable = $phpcsFile->findPrevious(
1826
+				Tokens::$emptyTokens,
1827
+				($tokens[$prevNonEmpty]['bracket_opener'] - 1),
1828
+				null,
1829
+				true,
1830
+				null,
1831
+				true
1832
+			);
1833
+
1834
+			if ($tokens[$maybeVariableVariable]['code'] === \T_VARIABLE
1835
+				|| $tokens[$maybeVariableVariable]['code'] === \T_DOLLAR
1836
+			) {
1837
+				return false;
1838
+			}
1839
+		}
1840
+
1841
+		$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($closer + 1), null, true, null, true);
1842
+
1843
+		if ($nextNonEmpty !== false && $tokens[$nextNonEmpty]['code'] === \T_EQUAL) {
1844
+			return true;
1845
+		}
1846
+
1847
+		if ($prevNonEmpty !== false
1848
+			&& $tokens[$prevNonEmpty]['code'] === \T_AS
1849
+			&& isset($tokens[$prevNonEmpty]['nested_parenthesis']) === true
1850
+		) {
1851
+			$parentheses = array_reverse($tokens[$prevNonEmpty]['nested_parenthesis'], true);
1852
+			foreach ($parentheses as $open => $close) {
1853
+				if (isset($tokens[$open]['parenthesis_owner'])
1854
+					&& $tokens[$tokens[$open]['parenthesis_owner']]['code'] === \T_FOREACH
1855
+				) {
1856
+					return true;
1857
+				}
1858
+			}
1859
+		}
1860
+
1861
+		// Maybe this is a short list syntax nested inside another short list syntax ?
1862
+		$parentOpener = $opener;
1863
+		do {
1864
+			$parentOpener = $phpcsFile->findPrevious(
1865
+				array(\T_OPEN_SHORT_ARRAY, \T_OPEN_SQUARE_BRACKET),
1866
+				($parentOpener - 1),
1867
+				null,
1868
+				false,
1869
+				null,
1870
+				true
1871
+			);
1872
+
1873
+			if ($parentOpener === false) {
1874
+				return false;
1875
+			}
1876
+
1877
+		} while (isset($tokens[$parentOpener]['bracket_closer']) === true
1878
+			&& $tokens[$parentOpener]['bracket_closer'] < $opener
1879
+		);
1880
+
1881
+		if (isset($tokens[$parentOpener]['bracket_closer']) === true
1882
+			&& $tokens[$parentOpener]['bracket_closer'] > $closer
1883
+		) {
1884
+			// Work around tokenizer issue in PHPCS 2.0 - 2.7.
1885
+			$phpcsVersion = PHPCSHelper::getVersion();
1886
+			if ((version_compare($phpcsVersion, '2.0', '>') === true
1887
+				&& version_compare($phpcsVersion, '2.8', '<') === true)
1888
+				&& $tokens[$parentOpener]['code'] === \T_OPEN_SQUARE_BRACKET
1889
+			) {
1890
+				$nextNonEmpty = $phpcsFile->findNext(
1891
+					Tokens::$emptyTokens,
1892
+					($tokens[$parentOpener]['bracket_closer'] + 1),
1893
+					null,
1894
+					true,
1895
+					null,
1896
+					true
1897
+				);
1898
+
1899
+				if ($nextNonEmpty !== false && $tokens[$nextNonEmpty]['code'] === \T_EQUAL) {
1900
+					return true;
1901
+				}
1902
+
1903
+				return false;
1904
+			}
1905
+
1906
+			return $this->isShortList($phpcsFile, $parentOpener);
1907
+		}
1908
+
1909
+		return false;
1910
+	}
1911
+
1912
+
1913
+	/**
1914
+	 * Determine whether the tokens between $start and $end could together represent a variable.
1915
+	 *
1916
+	 * @param \PHP_CodeSniffer_File $phpcsFile          The file being scanned.
1917
+	 * @param int                   $start              Starting point stack pointer. Inclusive.
1918
+	 *                                                  I.e. this token should be taken into account.
1919
+	 * @param int                   $end                End point stack pointer. Exclusive.
1920
+	 *                                                  I.e. this token should not be taken into account.
1921
+	 * @param int                   $targetNestingLevel The nesting level the variable should be at.
1922
+	 *
1923
+	 * @return bool
1924
+	 */
1925
+	public function isVariable(File $phpcsFile, $start, $end, $targetNestingLevel)
1926
+	{
1927
+		static $tokenBlackList, $bracketTokens;
1928
+
1929
+		// Create the token arrays only once.
1930
+		if (isset($tokenBlackList, $bracketTokens) === false) {
1931
+
1932
+			$tokenBlackList  = array(
1933
+				\T_OPEN_PARENTHESIS => \T_OPEN_PARENTHESIS,
1934
+				\T_STRING_CONCAT    => \T_STRING_CONCAT,
1935
+			);
1936
+			$tokenBlackList += Tokens::$assignmentTokens;
1937
+			$tokenBlackList += Tokens::$equalityTokens;
1938
+			$tokenBlackList += Tokens::$comparisonTokens;
1939
+			$tokenBlackList += Tokens::$operators;
1940
+			$tokenBlackList += Tokens::$booleanOperators;
1941
+			$tokenBlackList += Tokens::$castTokens;
1942
+
1943
+			/*
1944 1944
              * List of brackets which can be part of a variable variable.
1945 1945
              *
1946 1946
              * Key is the open bracket token, value the close bracket token.
1947 1947
              */
1948
-            $bracketTokens = array(
1949
-                \T_OPEN_CURLY_BRACKET  => \T_CLOSE_CURLY_BRACKET,
1950
-                \T_OPEN_SQUARE_BRACKET => \T_CLOSE_SQUARE_BRACKET,
1951
-            );
1952
-        }
1953
-
1954
-        $tokens = $phpcsFile->getTokens();
1955
-
1956
-        // If no variable at all was found, then it's definitely a no-no.
1957
-        $hasVariable = $phpcsFile->findNext(\T_VARIABLE, $start, $end);
1958
-        if ($hasVariable === false) {
1959
-            return false;
1960
-        }
1961
-
1962
-        // Check if the variable found is at the right level. Deeper levels are always an error.
1963
-        if (isset($tokens[$hasVariable]['nested_parenthesis'])
1964
-            && \count($tokens[$hasVariable]['nested_parenthesis']) !== $targetNestingLevel
1965
-        ) {
1966
-                return false;
1967
-        }
1968
-
1969
-        // Ok, so the first variable is at the right level, now are there any
1970
-        // blacklisted tokens within the empty() ?
1971
-        $hasBadToken = $phpcsFile->findNext($tokenBlackList, $start, $end);
1972
-        if ($hasBadToken === false) {
1973
-            return true;
1974
-        }
1975
-
1976
-        // If there are also bracket tokens, the blacklisted token might be part of a variable
1977
-        // variable, but if there are no bracket tokens, we know we have an error.
1978
-        $hasBrackets = $phpcsFile->findNext($bracketTokens, $start, $end);
1979
-        if ($hasBrackets === false) {
1980
-            return false;
1981
-        }
1982
-
1983
-        // Ok, we have both a blacklisted token as well as brackets, so we need to walk
1984
-        // the tokens of the variable variable.
1985
-        for ($i = $start; $i < $end; $i++) {
1986
-            // If this is a bracket token, skip to the end of the bracketed expression.
1987
-            if (isset($bracketTokens[$tokens[$i]['code']], $tokens[$i]['bracket_closer'])) {
1988
-                $i = $tokens[$i]['bracket_closer'];
1989
-                continue;
1990
-            }
1991
-
1992
-            // If it's a blacklisted token, not within brackets, we have an error.
1993
-            if (isset($tokenBlackList[$tokens[$i]['code']])) {
1994
-                return false;
1995
-            }
1996
-        }
1997
-
1998
-        return true;
1999
-    }
2000
-
2001
-    /**
2002
-     * Determine whether a T_MINUS/T_PLUS token is a unary operator.
2003
-     *
2004
-     * N.B.: This is a back-fill for a new method which is expected to go into
2005
-     * PHP_CodeSniffer 3.5.0.
2006
-     * Once that method has been merged into PHPCS, this one should be moved
2007
-     * to the PHPCSHelper.php file.
2008
-     *
2009
-     * @since 9.2.0
2010
-     *
2011
-     * @codeCoverageIgnore Method as pulled upstream is accompanied by unit tests.
2012
-     *
2013
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
2014
-     * @param int                   $stackPtr  The position of the plus/minus token.
2015
-     *
2016
-     * @return bool True if the token passed is a unary operator.
2017
-     *              False otherwise or if the token is not a T_PLUS/T_MINUS token.
2018
-     */
2019
-    public static function isUnaryPlusMinus(File $phpcsFile, $stackPtr)
2020
-    {
2021
-        $tokens = $phpcsFile->getTokens();
2022
-
2023
-        if (isset($tokens[$stackPtr]) === false
2024
-            || ($tokens[$stackPtr]['code'] !== \T_PLUS
2025
-            && $tokens[$stackPtr]['code'] !== \T_MINUS)
2026
-        ) {
2027
-            return false;
2028
-        }
2029
-
2030
-        $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
2031
-        if ($next === false) {
2032
-            // Live coding or parse error.
2033
-            return false;
2034
-        }
2035
-
2036
-        if (isset(Tokens::$operators[$tokens[$next]['code']]) === true) {
2037
-            // Next token is an operator, so this is not a unary.
2038
-            return false;
2039
-        }
2040
-
2041
-        $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
2042
-
2043
-        if ($tokens[$prev]['code'] === \T_RETURN) {
2044
-            // Just returning a positive/negative value; eg. (return -1).
2045
-            return true;
2046
-        }
2047
-
2048
-        if (isset(Tokens::$operators[$tokens[$prev]['code']]) === true) {
2049
-            // Just trying to operate on a positive/negative value; eg. ($var * -1).
2050
-            return true;
2051
-        }
2052
-
2053
-        if (isset(Tokens::$comparisonTokens[$tokens[$prev]['code']]) === true) {
2054
-            // Just trying to compare a positive/negative value; eg. ($var === -1).
2055
-            return true;
2056
-        }
2057
-
2058
-        if (isset(Tokens::$booleanOperators[$tokens[$prev]['code']]) === true) {
2059
-            // Just trying to compare a positive/negative value; eg. ($var || -1 === $b).
2060
-            return true;
2061
-        }
2062
-
2063
-        if (isset(Tokens::$assignmentTokens[$tokens[$prev]['code']]) === true) {
2064
-            // Just trying to assign a positive/negative value; eg. ($var = -1).
2065
-            return true;
2066
-        }
2067
-
2068
-        if (isset(Tokens::$castTokens[$tokens[$prev]['code']]) === true) {
2069
-            // Just casting a positive/negative value; eg. (string) -$var.
2070
-            return true;
2071
-        }
2072
-
2073
-        // Other indicators that a plus/minus sign is a unary operator.
2074
-        $invalidTokens = array(
2075
-            \T_COMMA               => true,
2076
-            \T_OPEN_PARENTHESIS    => true,
2077
-            \T_OPEN_SQUARE_BRACKET => true,
2078
-            \T_OPEN_SHORT_ARRAY    => true,
2079
-            \T_COLON               => true,
2080
-            \T_INLINE_THEN         => true,
2081
-            \T_INLINE_ELSE         => true,
2082
-            \T_CASE                => true,
2083
-            \T_OPEN_CURLY_BRACKET  => true,
2084
-            \T_STRING_CONCAT       => true,
2085
-        );
2086
-
2087
-        if (isset($invalidTokens[$tokens[$prev]['code']]) === true) {
2088
-            // Just trying to use a positive/negative value; eg. myFunction($var, -2).
2089
-            return true;
2090
-        }
2091
-
2092
-        return false;
2093
-    }
1948
+			$bracketTokens = array(
1949
+				\T_OPEN_CURLY_BRACKET  => \T_CLOSE_CURLY_BRACKET,
1950
+				\T_OPEN_SQUARE_BRACKET => \T_CLOSE_SQUARE_BRACKET,
1951
+			);
1952
+		}
1953
+
1954
+		$tokens = $phpcsFile->getTokens();
1955
+
1956
+		// If no variable at all was found, then it's definitely a no-no.
1957
+		$hasVariable = $phpcsFile->findNext(\T_VARIABLE, $start, $end);
1958
+		if ($hasVariable === false) {
1959
+			return false;
1960
+		}
1961
+
1962
+		// Check if the variable found is at the right level. Deeper levels are always an error.
1963
+		if (isset($tokens[$hasVariable]['nested_parenthesis'])
1964
+			&& \count($tokens[$hasVariable]['nested_parenthesis']) !== $targetNestingLevel
1965
+		) {
1966
+				return false;
1967
+		}
1968
+
1969
+		// Ok, so the first variable is at the right level, now are there any
1970
+		// blacklisted tokens within the empty() ?
1971
+		$hasBadToken = $phpcsFile->findNext($tokenBlackList, $start, $end);
1972
+		if ($hasBadToken === false) {
1973
+			return true;
1974
+		}
1975
+
1976
+		// If there are also bracket tokens, the blacklisted token might be part of a variable
1977
+		// variable, but if there are no bracket tokens, we know we have an error.
1978
+		$hasBrackets = $phpcsFile->findNext($bracketTokens, $start, $end);
1979
+		if ($hasBrackets === false) {
1980
+			return false;
1981
+		}
1982
+
1983
+		// Ok, we have both a blacklisted token as well as brackets, so we need to walk
1984
+		// the tokens of the variable variable.
1985
+		for ($i = $start; $i < $end; $i++) {
1986
+			// If this is a bracket token, skip to the end of the bracketed expression.
1987
+			if (isset($bracketTokens[$tokens[$i]['code']], $tokens[$i]['bracket_closer'])) {
1988
+				$i = $tokens[$i]['bracket_closer'];
1989
+				continue;
1990
+			}
1991
+
1992
+			// If it's a blacklisted token, not within brackets, we have an error.
1993
+			if (isset($tokenBlackList[$tokens[$i]['code']])) {
1994
+				return false;
1995
+			}
1996
+		}
1997
+
1998
+		return true;
1999
+	}
2000
+
2001
+	/**
2002
+	 * Determine whether a T_MINUS/T_PLUS token is a unary operator.
2003
+	 *
2004
+	 * N.B.: This is a back-fill for a new method which is expected to go into
2005
+	 * PHP_CodeSniffer 3.5.0.
2006
+	 * Once that method has been merged into PHPCS, this one should be moved
2007
+	 * to the PHPCSHelper.php file.
2008
+	 *
2009
+	 * @since 9.2.0
2010
+	 *
2011
+	 * @codeCoverageIgnore Method as pulled upstream is accompanied by unit tests.
2012
+	 *
2013
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
2014
+	 * @param int                   $stackPtr  The position of the plus/minus token.
2015
+	 *
2016
+	 * @return bool True if the token passed is a unary operator.
2017
+	 *              False otherwise or if the token is not a T_PLUS/T_MINUS token.
2018
+	 */
2019
+	public static function isUnaryPlusMinus(File $phpcsFile, $stackPtr)
2020
+	{
2021
+		$tokens = $phpcsFile->getTokens();
2022
+
2023
+		if (isset($tokens[$stackPtr]) === false
2024
+			|| ($tokens[$stackPtr]['code'] !== \T_PLUS
2025
+			&& $tokens[$stackPtr]['code'] !== \T_MINUS)
2026
+		) {
2027
+			return false;
2028
+		}
2029
+
2030
+		$next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true);
2031
+		if ($next === false) {
2032
+			// Live coding or parse error.
2033
+			return false;
2034
+		}
2035
+
2036
+		if (isset(Tokens::$operators[$tokens[$next]['code']]) === true) {
2037
+			// Next token is an operator, so this is not a unary.
2038
+			return false;
2039
+		}
2040
+
2041
+		$prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
2042
+
2043
+		if ($tokens[$prev]['code'] === \T_RETURN) {
2044
+			// Just returning a positive/negative value; eg. (return -1).
2045
+			return true;
2046
+		}
2047
+
2048
+		if (isset(Tokens::$operators[$tokens[$prev]['code']]) === true) {
2049
+			// Just trying to operate on a positive/negative value; eg. ($var * -1).
2050
+			return true;
2051
+		}
2052
+
2053
+		if (isset(Tokens::$comparisonTokens[$tokens[$prev]['code']]) === true) {
2054
+			// Just trying to compare a positive/negative value; eg. ($var === -1).
2055
+			return true;
2056
+		}
2057
+
2058
+		if (isset(Tokens::$booleanOperators[$tokens[$prev]['code']]) === true) {
2059
+			// Just trying to compare a positive/negative value; eg. ($var || -1 === $b).
2060
+			return true;
2061
+		}
2062
+
2063
+		if (isset(Tokens::$assignmentTokens[$tokens[$prev]['code']]) === true) {
2064
+			// Just trying to assign a positive/negative value; eg. ($var = -1).
2065
+			return true;
2066
+		}
2067
+
2068
+		if (isset(Tokens::$castTokens[$tokens[$prev]['code']]) === true) {
2069
+			// Just casting a positive/negative value; eg. (string) -$var.
2070
+			return true;
2071
+		}
2072
+
2073
+		// Other indicators that a plus/minus sign is a unary operator.
2074
+		$invalidTokens = array(
2075
+			\T_COMMA               => true,
2076
+			\T_OPEN_PARENTHESIS    => true,
2077
+			\T_OPEN_SQUARE_BRACKET => true,
2078
+			\T_OPEN_SHORT_ARRAY    => true,
2079
+			\T_COLON               => true,
2080
+			\T_INLINE_THEN         => true,
2081
+			\T_INLINE_ELSE         => true,
2082
+			\T_CASE                => true,
2083
+			\T_OPEN_CURLY_BRACKET  => true,
2084
+			\T_STRING_CONCAT       => true,
2085
+		);
2086
+
2087
+		if (isset($invalidTokens[$tokens[$prev]['code']]) === true) {
2088
+			// Just trying to use a positive/negative value; eg. myFunction($var, -2).
2089
+			return true;
2090
+		}
2091
+
2092
+		return false;
2093
+	}
2094 2094
 }
Please login to merge, or discard this patch.
php-compatibility/PHPCompatibility/AbstractComplexVersionSniff.php 1 patch
Indentation   +107 added lines, -107 removed lines patch added patch discarded remove patch
@@ -22,111 +22,111 @@
 block discarded – undo
22 22
 {
23 23
 
24 24
 
25
-    /**
26
-     * Handle the retrieval of relevant information and - if necessary - throwing of an
27
-     * error/warning for an item.
28
-     *
29
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
30
-     * @param int                   $stackPtr  The position of the relevant token in
31
-     *                                         the stack.
32
-     * @param array                 $itemInfo  Base information about the item.
33
-     *
34
-     * @return void
35
-     */
36
-    public function handleFeature(File $phpcsFile, $stackPtr, array $itemInfo)
37
-    {
38
-        $itemArray = $this->getItemArray($itemInfo);
39
-        $errorInfo = $this->getErrorInfo($itemArray, $itemInfo);
40
-
41
-        if ($this->shouldThrowError($errorInfo) === true) {
42
-            $this->addError($phpcsFile, $stackPtr, $itemInfo, $errorInfo);
43
-        }
44
-    }
45
-
46
-
47
-    /**
48
-     * Determine whether an error/warning should be thrown for an item based on collected information.
49
-     *
50
-     * @param array $errorInfo Detail information about an item.
51
-     *
52
-     * @return bool
53
-     */
54
-    abstract protected function shouldThrowError(array $errorInfo);
55
-
56
-
57
-    /**
58
-     * Get an array of the non-PHP-version array keys used in a sub-array.
59
-     *
60
-     * @return array
61
-     */
62
-    protected function getNonVersionArrayKeys()
63
-    {
64
-        return array();
65
-    }
66
-
67
-
68
-    /**
69
-     * Retrieve a subset of an item array containing only the array keys which
70
-     * contain PHP version information.
71
-     *
72
-     * @param array $itemArray Version and other information about an item.
73
-     *
74
-     * @return array Array with only the version information.
75
-     */
76
-    protected function getVersionArray(array $itemArray)
77
-    {
78
-        return array_diff_key($itemArray, array_flip($this->getNonVersionArrayKeys()));
79
-    }
80
-
81
-
82
-    /**
83
-     * Get the item name to be used for the creation of the error code and in the error message.
84
-     *
85
-     * @param array $itemInfo  Base information about the item.
86
-     * @param array $errorInfo Detail information about an item.
87
-     *
88
-     * @return string
89
-     */
90
-    protected function getItemName(array $itemInfo, array $errorInfo)
91
-    {
92
-        return $itemInfo['name'];
93
-    }
94
-
95
-
96
-    /**
97
-     * Get the error message template for a specific sniff.
98
-     *
99
-     * @return string
100
-     */
101
-    abstract protected function getErrorMsgTemplate();
102
-
103
-
104
-    /**
105
-     * Allow for concrete child classes to filter the error message before it's passed to PHPCS.
106
-     *
107
-     * @param string $error     The error message which was created.
108
-     * @param array  $itemInfo  Base information about the item this error message applies to.
109
-     * @param array  $errorInfo Detail information about an item this error message applies to.
110
-     *
111
-     * @return string
112
-     */
113
-    protected function filterErrorMsg($error, array $itemInfo, array $errorInfo)
114
-    {
115
-        return $error;
116
-    }
117
-
118
-
119
-    /**
120
-     * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
121
-     *
122
-     * @param array $data      The error data array which was created.
123
-     * @param array $itemInfo  Base information about the item this error message applies to.
124
-     * @param array $errorInfo Detail information about an item this error message applies to.
125
-     *
126
-     * @return array
127
-     */
128
-    protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
129
-    {
130
-        return $data;
131
-    }
25
+	/**
26
+	 * Handle the retrieval of relevant information and - if necessary - throwing of an
27
+	 * error/warning for an item.
28
+	 *
29
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
30
+	 * @param int                   $stackPtr  The position of the relevant token in
31
+	 *                                         the stack.
32
+	 * @param array                 $itemInfo  Base information about the item.
33
+	 *
34
+	 * @return void
35
+	 */
36
+	public function handleFeature(File $phpcsFile, $stackPtr, array $itemInfo)
37
+	{
38
+		$itemArray = $this->getItemArray($itemInfo);
39
+		$errorInfo = $this->getErrorInfo($itemArray, $itemInfo);
40
+
41
+		if ($this->shouldThrowError($errorInfo) === true) {
42
+			$this->addError($phpcsFile, $stackPtr, $itemInfo, $errorInfo);
43
+		}
44
+	}
45
+
46
+
47
+	/**
48
+	 * Determine whether an error/warning should be thrown for an item based on collected information.
49
+	 *
50
+	 * @param array $errorInfo Detail information about an item.
51
+	 *
52
+	 * @return bool
53
+	 */
54
+	abstract protected function shouldThrowError(array $errorInfo);
55
+
56
+
57
+	/**
58
+	 * Get an array of the non-PHP-version array keys used in a sub-array.
59
+	 *
60
+	 * @return array
61
+	 */
62
+	protected function getNonVersionArrayKeys()
63
+	{
64
+		return array();
65
+	}
66
+
67
+
68
+	/**
69
+	 * Retrieve a subset of an item array containing only the array keys which
70
+	 * contain PHP version information.
71
+	 *
72
+	 * @param array $itemArray Version and other information about an item.
73
+	 *
74
+	 * @return array Array with only the version information.
75
+	 */
76
+	protected function getVersionArray(array $itemArray)
77
+	{
78
+		return array_diff_key($itemArray, array_flip($this->getNonVersionArrayKeys()));
79
+	}
80
+
81
+
82
+	/**
83
+	 * Get the item name to be used for the creation of the error code and in the error message.
84
+	 *
85
+	 * @param array $itemInfo  Base information about the item.
86
+	 * @param array $errorInfo Detail information about an item.
87
+	 *
88
+	 * @return string
89
+	 */
90
+	protected function getItemName(array $itemInfo, array $errorInfo)
91
+	{
92
+		return $itemInfo['name'];
93
+	}
94
+
95
+
96
+	/**
97
+	 * Get the error message template for a specific sniff.
98
+	 *
99
+	 * @return string
100
+	 */
101
+	abstract protected function getErrorMsgTemplate();
102
+
103
+
104
+	/**
105
+	 * Allow for concrete child classes to filter the error message before it's passed to PHPCS.
106
+	 *
107
+	 * @param string $error     The error message which was created.
108
+	 * @param array  $itemInfo  Base information about the item this error message applies to.
109
+	 * @param array  $errorInfo Detail information about an item this error message applies to.
110
+	 *
111
+	 * @return string
112
+	 */
113
+	protected function filterErrorMsg($error, array $itemInfo, array $errorInfo)
114
+	{
115
+		return $error;
116
+	}
117
+
118
+
119
+	/**
120
+	 * Allow for concrete child classes to filter the error data before it's passed to PHPCS.
121
+	 *
122
+	 * @param array $data      The error data array which was created.
123
+	 * @param array $itemInfo  Base information about the item this error message applies to.
124
+	 * @param array $errorInfo Detail information about an item this error message applies to.
125
+	 *
126
+	 * @return array
127
+	 */
128
+	protected function filterErrorData(array $data, array $itemInfo, array $errorInfo)
129
+	{
130
+		return $data;
131
+	}
132 132
 }
Please login to merge, or discard this patch.
php-compatibility/PHPCompatibility/AbstractNewFeatureSniff.php 1 patch
Indentation   +83 added lines, -83 removed lines patch added patch discarded remove patch
@@ -22,87 +22,87 @@
 block discarded – undo
22 22
 {
23 23
 
24 24
 
25
-    /**
26
-     * Determine whether an error/warning should be thrown for an item based on collected information.
27
-     *
28
-     * @param array $errorInfo Detail information about an item.
29
-     *
30
-     * @return bool
31
-     */
32
-    protected function shouldThrowError(array $errorInfo)
33
-    {
34
-        return ($errorInfo['not_in_version'] !== '');
35
-    }
36
-
37
-
38
-    /**
39
-     * Retrieve the relevant detail (version) information for use in an error message.
40
-     *
41
-     * @param array $itemArray Version and other information about the item.
42
-     * @param array $itemInfo  Base information about the item.
43
-     *
44
-     * @return array
45
-     */
46
-    public function getErrorInfo(array $itemArray, array $itemInfo)
47
-    {
48
-        $errorInfo = array(
49
-            'not_in_version' => '',
50
-            'error'          => true,
51
-        );
52
-
53
-        $versionArray = $this->getVersionArray($itemArray);
54
-
55
-        if (empty($versionArray) === false) {
56
-            foreach ($versionArray as $version => $present) {
57
-                if ($errorInfo['not_in_version'] === '' && $present === false
58
-                    && $this->supportsBelow($version) === true
59
-                ) {
60
-                    $errorInfo['not_in_version'] = $version;
61
-                }
62
-            }
63
-        }
64
-
65
-        return $errorInfo;
66
-    }
67
-
68
-
69
-    /**
70
-     * Get the error message template for this sniff.
71
-     *
72
-     * @return string
73
-     */
74
-    protected function getErrorMsgTemplate()
75
-    {
76
-        return '%s is not present in PHP version %s or earlier';
77
-    }
78
-
79
-
80
-    /**
81
-     * Generates the error or warning for this item.
82
-     *
83
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
84
-     * @param int                   $stackPtr  The position of the relevant token in
85
-     *                                         the stack.
86
-     * @param array                 $itemInfo  Base information about the item.
87
-     * @param array                 $errorInfo Array with detail (version) information
88
-     *                                         relevant to the item.
89
-     *
90
-     * @return void
91
-     */
92
-    public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo)
93
-    {
94
-        $itemName = $this->getItemName($itemInfo, $errorInfo);
95
-        $error    = $this->getErrorMsgTemplate();
96
-
97
-        $errorCode = $this->stringToErrorCode($itemName) . 'Found';
98
-        $data      = array(
99
-            $itemName,
100
-            $errorInfo['not_in_version'],
101
-        );
102
-
103
-        $error = $this->filterErrorMsg($error, $itemInfo, $errorInfo);
104
-        $data  = $this->filterErrorData($data, $itemInfo, $errorInfo);
105
-
106
-        $this->addMessage($phpcsFile, $error, $stackPtr, $errorInfo['error'], $errorCode, $data);
107
-    }
25
+	/**
26
+	 * Determine whether an error/warning should be thrown for an item based on collected information.
27
+	 *
28
+	 * @param array $errorInfo Detail information about an item.
29
+	 *
30
+	 * @return bool
31
+	 */
32
+	protected function shouldThrowError(array $errorInfo)
33
+	{
34
+		return ($errorInfo['not_in_version'] !== '');
35
+	}
36
+
37
+
38
+	/**
39
+	 * Retrieve the relevant detail (version) information for use in an error message.
40
+	 *
41
+	 * @param array $itemArray Version and other information about the item.
42
+	 * @param array $itemInfo  Base information about the item.
43
+	 *
44
+	 * @return array
45
+	 */
46
+	public function getErrorInfo(array $itemArray, array $itemInfo)
47
+	{
48
+		$errorInfo = array(
49
+			'not_in_version' => '',
50
+			'error'          => true,
51
+		);
52
+
53
+		$versionArray = $this->getVersionArray($itemArray);
54
+
55
+		if (empty($versionArray) === false) {
56
+			foreach ($versionArray as $version => $present) {
57
+				if ($errorInfo['not_in_version'] === '' && $present === false
58
+					&& $this->supportsBelow($version) === true
59
+				) {
60
+					$errorInfo['not_in_version'] = $version;
61
+				}
62
+			}
63
+		}
64
+
65
+		return $errorInfo;
66
+	}
67
+
68
+
69
+	/**
70
+	 * Get the error message template for this sniff.
71
+	 *
72
+	 * @return string
73
+	 */
74
+	protected function getErrorMsgTemplate()
75
+	{
76
+		return '%s is not present in PHP version %s or earlier';
77
+	}
78
+
79
+
80
+	/**
81
+	 * Generates the error or warning for this item.
82
+	 *
83
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
84
+	 * @param int                   $stackPtr  The position of the relevant token in
85
+	 *                                         the stack.
86
+	 * @param array                 $itemInfo  Base information about the item.
87
+	 * @param array                 $errorInfo Array with detail (version) information
88
+	 *                                         relevant to the item.
89
+	 *
90
+	 * @return void
91
+	 */
92
+	public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo)
93
+	{
94
+		$itemName = $this->getItemName($itemInfo, $errorInfo);
95
+		$error    = $this->getErrorMsgTemplate();
96
+
97
+		$errorCode = $this->stringToErrorCode($itemName) . 'Found';
98
+		$data      = array(
99
+			$itemName,
100
+			$errorInfo['not_in_version'],
101
+		);
102
+
103
+		$error = $this->filterErrorMsg($error, $itemInfo, $errorInfo);
104
+		$data  = $this->filterErrorData($data, $itemInfo, $errorInfo);
105
+
106
+		$this->addMessage($phpcsFile, $error, $stackPtr, $errorInfo['error'], $errorCode, $data);
107
+	}
108 108
 }
Please login to merge, or discard this patch.
php-compatibility/PHPCompatibility/ComplexVersionInterface.php 1 patch
Indentation   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -26,52 +26,52 @@
 block discarded – undo
26 26
 {
27 27
 
28 28
 
29
-    /**
30
-     * Handle the retrieval of relevant information and - if necessary - throwing of an
31
-     * error/warning for an item.
32
-     *
33
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
34
-     * @param int                   $stackPtr  The position of the relevant token in
35
-     *                                         the stack.
36
-     * @param array                 $itemInfo  Base information about the item.
37
-     *
38
-     * @return void
39
-     */
40
-    public function handleFeature(File $phpcsFile, $stackPtr, array $itemInfo);
29
+	/**
30
+	 * Handle the retrieval of relevant information and - if necessary - throwing of an
31
+	 * error/warning for an item.
32
+	 *
33
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
34
+	 * @param int                   $stackPtr  The position of the relevant token in
35
+	 *                                         the stack.
36
+	 * @param array                 $itemInfo  Base information about the item.
37
+	 *
38
+	 * @return void
39
+	 */
40
+	public function handleFeature(File $phpcsFile, $stackPtr, array $itemInfo);
41 41
 
42 42
 
43
-    /**
44
-     * Get the relevant sub-array for a specific item from a multi-dimensional array.
45
-     *
46
-     * @param array $itemInfo Base information about the item.
47
-     *
48
-     * @return array Version and other information about the item.
49
-     */
50
-    public function getItemArray(array $itemInfo);
43
+	/**
44
+	 * Get the relevant sub-array for a specific item from a multi-dimensional array.
45
+	 *
46
+	 * @param array $itemInfo Base information about the item.
47
+	 *
48
+	 * @return array Version and other information about the item.
49
+	 */
50
+	public function getItemArray(array $itemInfo);
51 51
 
52 52
 
53
-    /**
54
-     * Retrieve the relevant detail (version) information for use in an error message.
55
-     *
56
-     * @param array $itemArray Version and other information about the item.
57
-     * @param array $itemInfo  Base information about the item.
58
-     *
59
-     * @return array
60
-     */
61
-    public function getErrorInfo(array $itemArray, array $itemInfo);
53
+	/**
54
+	 * Retrieve the relevant detail (version) information for use in an error message.
55
+	 *
56
+	 * @param array $itemArray Version and other information about the item.
57
+	 * @param array $itemInfo  Base information about the item.
58
+	 *
59
+	 * @return array
60
+	 */
61
+	public function getErrorInfo(array $itemArray, array $itemInfo);
62 62
 
63 63
 
64
-    /**
65
-     * Generates the error or warning for this item.
66
-     *
67
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
68
-     * @param int                   $stackPtr  The position of the relevant token in
69
-     *                                         the stack.
70
-     * @param array                 $itemInfo  Base information about the item.
71
-     * @param array                 $errorInfo Array with detail (version) information
72
-     *                                         relevant to the item.
73
-     *
74
-     * @return void
75
-     */
76
-    public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo);
64
+	/**
65
+	 * Generates the error or warning for this item.
66
+	 *
67
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
68
+	 * @param int                   $stackPtr  The position of the relevant token in
69
+	 *                                         the stack.
70
+	 * @param array                 $itemInfo  Base information about the item.
71
+	 * @param array                 $errorInfo Array with detail (version) information
72
+	 *                                         relevant to the item.
73
+	 *
74
+	 * @return void
75
+	 */
76
+	public function addError(File $phpcsFile, $stackPtr, array $itemInfo, array $errorInfo);
77 77
 }
Please login to merge, or discard this patch.
PHPCompatibility/Sniffs/InitialValue/NewConstantScalarExpressionsSniff.php 1 patch
Indentation   +486 added lines, -486 removed lines patch added patch discarded remove patch
@@ -33,502 +33,502 @@
 block discarded – undo
33 33
 class NewConstantScalarExpressionsSniff extends Sniff
34 34
 {
35 35
 
36
-    /**
37
-     * Error message.
38
-     *
39
-     * @var string
40
-     */
41
-    const ERROR_PHRASE = 'Constant scalar expressions are not allowed %s in PHP 5.5 or earlier.';
42
-
43
-    /**
44
-     * Partial error phrases to be used in combination with the error message constant.
45
-     *
46
-     * @var array
47
-     */
48
-    protected $errorPhrases = array(
49
-        'const'     => 'when defining constants using the const keyword',
50
-        'property'  => 'in property declarations',
51
-        'staticvar' => 'in static variable declarations',
52
-        'default'   => 'in default function arguments',
53
-    );
54
-
55
-    /**
56
-     * Tokens which were allowed to be used in these declarations prior to PHP 5.6.
57
-     *
58
-     * This list will be enriched in the setProperties() method.
59
-     *
60
-     * @var array
61
-     */
62
-    protected $safeOperands = array(
63
-        \T_LNUMBER                  => \T_LNUMBER,
64
-        \T_DNUMBER                  => \T_DNUMBER,
65
-        \T_CONSTANT_ENCAPSED_STRING => \T_CONSTANT_ENCAPSED_STRING,
66
-        \T_TRUE                     => \T_TRUE,
67
-        \T_FALSE                    => \T_FALSE,
68
-        \T_NULL                     => \T_NULL,
69
-
70
-        \T_LINE                     => \T_LINE,
71
-        \T_FILE                     => \T_FILE,
72
-        \T_DIR                      => \T_DIR,
73
-        \T_FUNC_C                   => \T_FUNC_C,
74
-        \T_CLASS_C                  => \T_CLASS_C,
75
-        \T_TRAIT_C                  => \T_TRAIT_C,
76
-        \T_METHOD_C                 => \T_METHOD_C,
77
-        \T_NS_C                     => \T_NS_C,
78
-
79
-        // Special cases:
80
-        \T_NS_SEPARATOR             => \T_NS_SEPARATOR,
81
-        /*
36
+	/**
37
+	 * Error message.
38
+	 *
39
+	 * @var string
40
+	 */
41
+	const ERROR_PHRASE = 'Constant scalar expressions are not allowed %s in PHP 5.5 or earlier.';
42
+
43
+	/**
44
+	 * Partial error phrases to be used in combination with the error message constant.
45
+	 *
46
+	 * @var array
47
+	 */
48
+	protected $errorPhrases = array(
49
+		'const'     => 'when defining constants using the const keyword',
50
+		'property'  => 'in property declarations',
51
+		'staticvar' => 'in static variable declarations',
52
+		'default'   => 'in default function arguments',
53
+	);
54
+
55
+	/**
56
+	 * Tokens which were allowed to be used in these declarations prior to PHP 5.6.
57
+	 *
58
+	 * This list will be enriched in the setProperties() method.
59
+	 *
60
+	 * @var array
61
+	 */
62
+	protected $safeOperands = array(
63
+		\T_LNUMBER                  => \T_LNUMBER,
64
+		\T_DNUMBER                  => \T_DNUMBER,
65
+		\T_CONSTANT_ENCAPSED_STRING => \T_CONSTANT_ENCAPSED_STRING,
66
+		\T_TRUE                     => \T_TRUE,
67
+		\T_FALSE                    => \T_FALSE,
68
+		\T_NULL                     => \T_NULL,
69
+
70
+		\T_LINE                     => \T_LINE,
71
+		\T_FILE                     => \T_FILE,
72
+		\T_DIR                      => \T_DIR,
73
+		\T_FUNC_C                   => \T_FUNC_C,
74
+		\T_CLASS_C                  => \T_CLASS_C,
75
+		\T_TRAIT_C                  => \T_TRAIT_C,
76
+		\T_METHOD_C                 => \T_METHOD_C,
77
+		\T_NS_C                     => \T_NS_C,
78
+
79
+		// Special cases:
80
+		\T_NS_SEPARATOR             => \T_NS_SEPARATOR,
81
+		/*
82 82
          * This can be neigh anything, but for any usage except constants,
83 83
          * the T_STRING will be combined with non-allowed tokens, so we should be good.
84 84
          */
85
-        \T_STRING                   => \T_STRING,
86
-    );
87
-
88
-
89
-    /**
90
-     * Returns an array of tokens this test wants to listen for.
91
-     *
92
-     * @return array
93
-     */
94
-    public function register()
95
-    {
96
-        // Set the properties up only once.
97
-        $this->setProperties();
98
-
99
-        return array(
100
-            \T_CONST,
101
-            \T_VARIABLE,
102
-            \T_FUNCTION,
103
-            \T_CLOSURE,
104
-            \T_STATIC,
105
-        );
106
-    }
107
-
108
-
109
-    /**
110
-     * Make some adjustments to the $safeOperands property.
111
-     *
112
-     * @return void
113
-     */
114
-    public function setProperties()
115
-    {
116
-        $this->safeOperands += Tokens::$heredocTokens;
117
-        $this->safeOperands += Tokens::$emptyTokens;
118
-    }
119
-
120
-
121
-    /**
122
-     * Do a version check to determine if this sniff needs to run at all.
123
-     *
124
-     * @return bool
125
-     */
126
-    protected function bowOutEarly()
127
-    {
128
-        return ($this->supportsBelow('5.5') !== true);
129
-    }
130
-
131
-
132
-    /**
133
-     * Processes this test, when one of its tokens is encountered.
134
-     *
135
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
136
-     * @param int                   $stackPtr  The position of the current token in the
137
-     *                                         stack passed in $tokens.
138
-     *
139
-     * @return void|int Null or integer stack pointer to skip forward.
140
-     */
141
-    public function process(File $phpcsFile, $stackPtr)
142
-    {
143
-        if ($this->bowOutEarly() === true) {
144
-            return;
145
-        }
146
-
147
-        $tokens = $phpcsFile->getTokens();
148
-
149
-        switch ($tokens[$stackPtr]['type']) {
150
-            case 'T_FUNCTION':
151
-            case 'T_CLOSURE':
152
-                $params = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
153
-                if (empty($params)) {
154
-                    // No parameters.
155
-                    return;
156
-                }
157
-
158
-                $funcToken = $tokens[$stackPtr];
159
-
160
-                if (isset($funcToken['parenthesis_owner'], $funcToken['parenthesis_opener'], $funcToken['parenthesis_closer']) === false
161
-                    || $funcToken['parenthesis_owner'] !== $stackPtr
162
-                    || isset($tokens[$funcToken['parenthesis_opener']], $tokens[$funcToken['parenthesis_closer']]) === false
163
-                ) {
164
-                    // Hmm.. something is going wrong as these should all be available & valid.
165
-                    return;
166
-                }
167
-
168
-                $opener = $funcToken['parenthesis_opener'];
169
-                $closer = $funcToken['parenthesis_closer'];
170
-
171
-                // Which nesting level is the one we are interested in ?
172
-                $nestedParenthesisCount = 1;
173
-                if (isset($tokens[$opener]['nested_parenthesis'])) {
174
-                    $nestedParenthesisCount += \count($tokens[$opener]['nested_parenthesis']);
175
-                }
176
-
177
-                foreach ($params as $param) {
178
-                    if (isset($param['default']) === false) {
179
-                        continue;
180
-                    }
181
-
182
-                    $end = $param['token'];
183
-                    while (($end = $phpcsFile->findNext(array(\T_COMMA, \T_CLOSE_PARENTHESIS), ($end + 1), ($closer + 1))) !== false) {
184
-                        $maybeSkipTo = $this->isRealEndOfDeclaration($tokens, $end, $nestedParenthesisCount);
185
-                        if ($maybeSkipTo !== true) {
186
-                            $end = $maybeSkipTo;
187
-                            continue;
188
-                        }
189
-
190
-                        // Ignore closing parenthesis/bracket if not 'ours'.
191
-                        if ($tokens[$end]['code'] === \T_CLOSE_PARENTHESIS && $end !== $closer) {
192
-                            continue;
193
-                        }
194
-
195
-                        // Ok, we've found the end of the param default value declaration.
196
-                        break;
197
-                    }
198
-
199
-                    if ($this->isValidAssignment($phpcsFile, $param['token'], $end) === false) {
200
-                        $this->throwError($phpcsFile, $param['token'], 'default', $param['content']);
201
-                    }
202
-                }
203
-
204
-                /*
85
+		\T_STRING                   => \T_STRING,
86
+	);
87
+
88
+
89
+	/**
90
+	 * Returns an array of tokens this test wants to listen for.
91
+	 *
92
+	 * @return array
93
+	 */
94
+	public function register()
95
+	{
96
+		// Set the properties up only once.
97
+		$this->setProperties();
98
+
99
+		return array(
100
+			\T_CONST,
101
+			\T_VARIABLE,
102
+			\T_FUNCTION,
103
+			\T_CLOSURE,
104
+			\T_STATIC,
105
+		);
106
+	}
107
+
108
+
109
+	/**
110
+	 * Make some adjustments to the $safeOperands property.
111
+	 *
112
+	 * @return void
113
+	 */
114
+	public function setProperties()
115
+	{
116
+		$this->safeOperands += Tokens::$heredocTokens;
117
+		$this->safeOperands += Tokens::$emptyTokens;
118
+	}
119
+
120
+
121
+	/**
122
+	 * Do a version check to determine if this sniff needs to run at all.
123
+	 *
124
+	 * @return bool
125
+	 */
126
+	protected function bowOutEarly()
127
+	{
128
+		return ($this->supportsBelow('5.5') !== true);
129
+	}
130
+
131
+
132
+	/**
133
+	 * Processes this test, when one of its tokens is encountered.
134
+	 *
135
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
136
+	 * @param int                   $stackPtr  The position of the current token in the
137
+	 *                                         stack passed in $tokens.
138
+	 *
139
+	 * @return void|int Null or integer stack pointer to skip forward.
140
+	 */
141
+	public function process(File $phpcsFile, $stackPtr)
142
+	{
143
+		if ($this->bowOutEarly() === true) {
144
+			return;
145
+		}
146
+
147
+		$tokens = $phpcsFile->getTokens();
148
+
149
+		switch ($tokens[$stackPtr]['type']) {
150
+			case 'T_FUNCTION':
151
+			case 'T_CLOSURE':
152
+				$params = PHPCSHelper::getMethodParameters($phpcsFile, $stackPtr);
153
+				if (empty($params)) {
154
+					// No parameters.
155
+					return;
156
+				}
157
+
158
+				$funcToken = $tokens[$stackPtr];
159
+
160
+				if (isset($funcToken['parenthesis_owner'], $funcToken['parenthesis_opener'], $funcToken['parenthesis_closer']) === false
161
+					|| $funcToken['parenthesis_owner'] !== $stackPtr
162
+					|| isset($tokens[$funcToken['parenthesis_opener']], $tokens[$funcToken['parenthesis_closer']]) === false
163
+				) {
164
+					// Hmm.. something is going wrong as these should all be available & valid.
165
+					return;
166
+				}
167
+
168
+				$opener = $funcToken['parenthesis_opener'];
169
+				$closer = $funcToken['parenthesis_closer'];
170
+
171
+				// Which nesting level is the one we are interested in ?
172
+				$nestedParenthesisCount = 1;
173
+				if (isset($tokens[$opener]['nested_parenthesis'])) {
174
+					$nestedParenthesisCount += \count($tokens[$opener]['nested_parenthesis']);
175
+				}
176
+
177
+				foreach ($params as $param) {
178
+					if (isset($param['default']) === false) {
179
+						continue;
180
+					}
181
+
182
+					$end = $param['token'];
183
+					while (($end = $phpcsFile->findNext(array(\T_COMMA, \T_CLOSE_PARENTHESIS), ($end + 1), ($closer + 1))) !== false) {
184
+						$maybeSkipTo = $this->isRealEndOfDeclaration($tokens, $end, $nestedParenthesisCount);
185
+						if ($maybeSkipTo !== true) {
186
+							$end = $maybeSkipTo;
187
+							continue;
188
+						}
189
+
190
+						// Ignore closing parenthesis/bracket if not 'ours'.
191
+						if ($tokens[$end]['code'] === \T_CLOSE_PARENTHESIS && $end !== $closer) {
192
+							continue;
193
+						}
194
+
195
+						// Ok, we've found the end of the param default value declaration.
196
+						break;
197
+					}
198
+
199
+					if ($this->isValidAssignment($phpcsFile, $param['token'], $end) === false) {
200
+						$this->throwError($phpcsFile, $param['token'], 'default', $param['content']);
201
+					}
202
+				}
203
+
204
+				/*
205 205
                  * No need for the sniff to be triggered by the T_VARIABLEs in the function
206 206
                  * definition as we've already examined them above, so let's skip over them.
207 207
                  */
208
-                return $closer;
209
-
210
-            case 'T_VARIABLE':
211
-            case 'T_STATIC':
212
-            case 'T_CONST':
213
-                $type = 'const';
214
-
215
-                // Filter out non-property declarations.
216
-                if ($tokens[$stackPtr]['code'] === \T_VARIABLE) {
217
-                    if ($this->isClassProperty($phpcsFile, $stackPtr) === false) {
218
-                        return;
219
-                    }
220
-
221
-                    $type = 'property';
222
-
223
-                    // Move back one token to have the same starting point as the others.
224
-                    $stackPtr = ($stackPtr - 1);
225
-                }
226
-
227
-                // Filter out late static binding and class properties.
228
-                if ($tokens[$stackPtr]['code'] === \T_STATIC) {
229
-                    $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
230
-                    if ($next === false || $tokens[$next]['code'] !== \T_VARIABLE) {
231
-                        // Late static binding.
232
-                        return;
233
-                    }
234
-
235
-                    if ($this->isClassProperty($phpcsFile, $next) === true) {
236
-                        // Class properties are examined based on the T_VARIABLE token.
237
-                        return;
238
-                    }
239
-                    unset($next);
240
-
241
-                    $type = 'staticvar';
242
-                }
243
-
244
-                $endOfStatement = $phpcsFile->findNext(array(\T_SEMICOLON, \T_CLOSE_TAG), ($stackPtr + 1));
245
-                if ($endOfStatement === false) {
246
-                    // No semi-colon - live coding.
247
-                    return;
248
-                }
249
-
250
-                $targetNestingLevel = 0;
251
-                if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
252
-                    $targetNestingLevel = \count($tokens[$stackPtr]['nested_parenthesis']);
253
-                }
254
-
255
-                // Examine each variable/constant in multi-declarations.
256
-                $start = $stackPtr;
257
-                $end   = $stackPtr;
258
-                while (($end = $phpcsFile->findNext(array(\T_COMMA, \T_SEMICOLON, \T_OPEN_SHORT_ARRAY, \T_CLOSE_TAG), ($end + 1), ($endOfStatement + 1))) !== false) {
259
-
260
-                    $maybeSkipTo = $this->isRealEndOfDeclaration($tokens, $end, $targetNestingLevel);
261
-                    if ($maybeSkipTo !== true) {
262
-                        $end = $maybeSkipTo;
263
-                        continue;
264
-                    }
265
-
266
-                    $start = $phpcsFile->findNext(Tokens::$emptyTokens, ($start + 1), $end, true);
267
-                    if ($start === false
268
-                        || ($tokens[$stackPtr]['code'] === \T_CONST && $tokens[$start]['code'] !== \T_STRING)
269
-                        || ($tokens[$stackPtr]['code'] !== \T_CONST && $tokens[$start]['code'] !== \T_VARIABLE)
270
-                    ) {
271
-                        // Shouldn't be possible.
272
-                        continue;
273
-                    }
274
-
275
-                    if ($this->isValidAssignment($phpcsFile, $start, $end) === false) {
276
-                        // Create the "found" snippet.
277
-                        $content    = '';
278
-                        $tokenCount = ($end - $start);
279
-                        if ($tokenCount < 20) {
280
-                            // Prevent large arrays from being added to the error message.
281
-                            $content = $phpcsFile->getTokensAsString($start, ($tokenCount + 1));
282
-                        }
283
-
284
-                        $this->throwError($phpcsFile, $start, $type, $content);
285
-                    }
286
-
287
-                    $start = $end;
288
-                }
289
-
290
-                // Skip to the end of the statement to prevent duplicate messages for multi-declarations.
291
-                return $endOfStatement;
292
-        }
293
-    }
294
-
295
-
296
-    /**
297
-     * Is a value declared and is the value declared valid pre-PHP 5.6 ?
298
-     *
299
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
300
-     * @param int                   $stackPtr  The position of the current token in the
301
-     *                                         stack passed in $tokens.
302
-     * @param int                   $end       The end of the value definition.
303
-     *                                         This will normally be a comma or semi-colon.
304
-     *
305
-     * @return bool
306
-     */
307
-    protected function isValidAssignment(File $phpcsFile, $stackPtr, $end)
308
-    {
309
-        $tokens = $phpcsFile->getTokens();
310
-        $next   = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), $end, true);
311
-        if ($next === false || $tokens[$next]['code'] !== \T_EQUAL) {
312
-            // No value assigned.
313
-            return true;
314
-        }
315
-
316
-        return $this->isStaticValue($phpcsFile, $tokens, ($next + 1), ($end - 1));
317
-    }
318
-
319
-
320
-    /**
321
-     * Is a value declared and is the value declared constant as accepted in PHP 5.5 and lower ?
322
-     *
323
-     * @param \PHP_CodeSniffer_File $phpcsFile    The file being scanned.
324
-     * @param array                 $tokens       The token stack of the current file.
325
-     * @param int                   $start        The stackPtr from which to start examining.
326
-     * @param int                   $end          The end of the value definition (inclusive),
327
-     *                                            i.e. this token will be examined as part of
328
-     *                                            the snippet.
329
-     * @param bool                  $nestedArrays Optional. Array nesting level when examining
330
-     *                                            the content of an array.
331
-     *
332
-     * @return bool
333
-     */
334
-    protected function isStaticValue(File $phpcsFile, $tokens, $start, $end, $nestedArrays = 0)
335
-    {
336
-        $nextNonSimple = $phpcsFile->findNext($this->safeOperands, $start, ($end + 1), true);
337
-        if ($nextNonSimple === false) {
338
-            return true;
339
-        }
340
-
341
-        /*
208
+				return $closer;
209
+
210
+			case 'T_VARIABLE':
211
+			case 'T_STATIC':
212
+			case 'T_CONST':
213
+				$type = 'const';
214
+
215
+				// Filter out non-property declarations.
216
+				if ($tokens[$stackPtr]['code'] === \T_VARIABLE) {
217
+					if ($this->isClassProperty($phpcsFile, $stackPtr) === false) {
218
+						return;
219
+					}
220
+
221
+					$type = 'property';
222
+
223
+					// Move back one token to have the same starting point as the others.
224
+					$stackPtr = ($stackPtr - 1);
225
+				}
226
+
227
+				// Filter out late static binding and class properties.
228
+				if ($tokens[$stackPtr]['code'] === \T_STATIC) {
229
+					$next = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true, null, true);
230
+					if ($next === false || $tokens[$next]['code'] !== \T_VARIABLE) {
231
+						// Late static binding.
232
+						return;
233
+					}
234
+
235
+					if ($this->isClassProperty($phpcsFile, $next) === true) {
236
+						// Class properties are examined based on the T_VARIABLE token.
237
+						return;
238
+					}
239
+					unset($next);
240
+
241
+					$type = 'staticvar';
242
+				}
243
+
244
+				$endOfStatement = $phpcsFile->findNext(array(\T_SEMICOLON, \T_CLOSE_TAG), ($stackPtr + 1));
245
+				if ($endOfStatement === false) {
246
+					// No semi-colon - live coding.
247
+					return;
248
+				}
249
+
250
+				$targetNestingLevel = 0;
251
+				if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
252
+					$targetNestingLevel = \count($tokens[$stackPtr]['nested_parenthesis']);
253
+				}
254
+
255
+				// Examine each variable/constant in multi-declarations.
256
+				$start = $stackPtr;
257
+				$end   = $stackPtr;
258
+				while (($end = $phpcsFile->findNext(array(\T_COMMA, \T_SEMICOLON, \T_OPEN_SHORT_ARRAY, \T_CLOSE_TAG), ($end + 1), ($endOfStatement + 1))) !== false) {
259
+
260
+					$maybeSkipTo = $this->isRealEndOfDeclaration($tokens, $end, $targetNestingLevel);
261
+					if ($maybeSkipTo !== true) {
262
+						$end = $maybeSkipTo;
263
+						continue;
264
+					}
265
+
266
+					$start = $phpcsFile->findNext(Tokens::$emptyTokens, ($start + 1), $end, true);
267
+					if ($start === false
268
+						|| ($tokens[$stackPtr]['code'] === \T_CONST && $tokens[$start]['code'] !== \T_STRING)
269
+						|| ($tokens[$stackPtr]['code'] !== \T_CONST && $tokens[$start]['code'] !== \T_VARIABLE)
270
+					) {
271
+						// Shouldn't be possible.
272
+						continue;
273
+					}
274
+
275
+					if ($this->isValidAssignment($phpcsFile, $start, $end) === false) {
276
+						// Create the "found" snippet.
277
+						$content    = '';
278
+						$tokenCount = ($end - $start);
279
+						if ($tokenCount < 20) {
280
+							// Prevent large arrays from being added to the error message.
281
+							$content = $phpcsFile->getTokensAsString($start, ($tokenCount + 1));
282
+						}
283
+
284
+						$this->throwError($phpcsFile, $start, $type, $content);
285
+					}
286
+
287
+					$start = $end;
288
+				}
289
+
290
+				// Skip to the end of the statement to prevent duplicate messages for multi-declarations.
291
+				return $endOfStatement;
292
+		}
293
+	}
294
+
295
+
296
+	/**
297
+	 * Is a value declared and is the value declared valid pre-PHP 5.6 ?
298
+	 *
299
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
300
+	 * @param int                   $stackPtr  The position of the current token in the
301
+	 *                                         stack passed in $tokens.
302
+	 * @param int                   $end       The end of the value definition.
303
+	 *                                         This will normally be a comma or semi-colon.
304
+	 *
305
+	 * @return bool
306
+	 */
307
+	protected function isValidAssignment(File $phpcsFile, $stackPtr, $end)
308
+	{
309
+		$tokens = $phpcsFile->getTokens();
310
+		$next   = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), $end, true);
311
+		if ($next === false || $tokens[$next]['code'] !== \T_EQUAL) {
312
+			// No value assigned.
313
+			return true;
314
+		}
315
+
316
+		return $this->isStaticValue($phpcsFile, $tokens, ($next + 1), ($end - 1));
317
+	}
318
+
319
+
320
+	/**
321
+	 * Is a value declared and is the value declared constant as accepted in PHP 5.5 and lower ?
322
+	 *
323
+	 * @param \PHP_CodeSniffer_File $phpcsFile    The file being scanned.
324
+	 * @param array                 $tokens       The token stack of the current file.
325
+	 * @param int                   $start        The stackPtr from which to start examining.
326
+	 * @param int                   $end          The end of the value definition (inclusive),
327
+	 *                                            i.e. this token will be examined as part of
328
+	 *                                            the snippet.
329
+	 * @param bool                  $nestedArrays Optional. Array nesting level when examining
330
+	 *                                            the content of an array.
331
+	 *
332
+	 * @return bool
333
+	 */
334
+	protected function isStaticValue(File $phpcsFile, $tokens, $start, $end, $nestedArrays = 0)
335
+	{
336
+		$nextNonSimple = $phpcsFile->findNext($this->safeOperands, $start, ($end + 1), true);
337
+		if ($nextNonSimple === false) {
338
+			return true;
339
+		}
340
+
341
+		/*
342 342
          * OK, so we have at least one token which needs extra examination.
343 343
          */
344
-        switch ($tokens[$nextNonSimple]['code']) {
345
-            case \T_MINUS:
346
-            case \T_PLUS:
347
-                if ($this->isNumber($phpcsFile, $start, $end, true) !== false) {
348
-                    // Int or float with sign.
349
-                    return true;
350
-                }
351
-
352
-                return false;
353
-
354
-            case \T_NAMESPACE:
355
-            case \T_PARENT:
356
-            case \T_SELF:
357
-            case \T_DOUBLE_COLON:
358
-                $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonSimple + 1), ($end + 1), true);
359
-
360
-                if ($tokens[$nextNonSimple]['code'] === \T_NAMESPACE) {
361
-                    // Allow only `namespace\...`.
362
-                    if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_NS_SEPARATOR) {
363
-                        return false;
364
-                    }
365
-                } elseif ($tokens[$nextNonSimple]['code'] === \T_PARENT
366
-                    || $tokens[$nextNonSimple]['code'] === \T_SELF
367
-                ) {
368
-                    // Allow only `parent::` and `self::`.
369
-                    if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_DOUBLE_COLON) {
370
-                        return false;
371
-                    }
372
-                } elseif ($tokens[$nextNonSimple]['code'] === \T_DOUBLE_COLON) {
373
-                    // Allow only `T_STRING::T_STRING`.
374
-                    if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_STRING) {
375
-                        return false;
376
-                    }
377
-
378
-                    $prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($nextNonSimple - 1), null, true);
379
-                    // No need to worry about parent/self, that's handled above and
380
-                    // the double colon is skipped over in that case.
381
-                    if ($prevNonEmpty === false || $tokens[$prevNonEmpty]['code'] !== \T_STRING) {
382
-                        return false;
383
-                    }
384
-                }
385
-
386
-                // Examine what comes after the namespace/parent/self/double colon, if anything.
387
-                return $this->isStaticValue($phpcsFile, $tokens, ($nextNonEmpty + 1), $end, $nestedArrays);
388
-
389
-            case \T_ARRAY:
390
-            case \T_OPEN_SHORT_ARRAY:
391
-                ++$nestedArrays;
392
-
393
-                $arrayItems = $this->getFunctionCallParameters($phpcsFile, $nextNonSimple);
394
-                if (empty($arrayItems) === false) {
395
-                    foreach ($arrayItems as $item) {
396
-                        // Check for a double arrow, but only if it's for this array item, not for a nested array.
397
-                        $doubleArrow = false;
398
-
399
-                        $maybeDoubleArrow = $phpcsFile->findNext(
400
-                            array(\T_DOUBLE_ARROW, \T_ARRAY, \T_OPEN_SHORT_ARRAY),
401
-                            $item['start'],
402
-                            ($item['end'] + 1)
403
-                        );
404
-                        if ($maybeDoubleArrow !== false && $tokens[$maybeDoubleArrow]['code'] === \T_DOUBLE_ARROW) {
405
-                            // Double arrow is for this nesting level.
406
-                            $doubleArrow = $maybeDoubleArrow;
407
-                        }
408
-
409
-                        if ($doubleArrow === false) {
410
-                            if ($this->isStaticValue($phpcsFile, $tokens, $item['start'], $item['end'], $nestedArrays) === false) {
411
-                                return false;
412
-                            }
413
-
414
-                        } else {
415
-                            // Examine array key.
416
-                            if ($this->isStaticValue($phpcsFile, $tokens, $item['start'], ($doubleArrow - 1), $nestedArrays) === false) {
417
-                                return false;
418
-                            }
419
-
420
-                            // Examine array value.
421
-                            if ($this->isStaticValue($phpcsFile, $tokens, ($doubleArrow + 1), $item['end'], $nestedArrays) === false) {
422
-                                return false;
423
-                            }
424
-                        }
425
-                    }
426
-                }
427
-
428
-                --$nestedArrays;
429
-
430
-                /*
344
+		switch ($tokens[$nextNonSimple]['code']) {
345
+			case \T_MINUS:
346
+			case \T_PLUS:
347
+				if ($this->isNumber($phpcsFile, $start, $end, true) !== false) {
348
+					// Int or float with sign.
349
+					return true;
350
+				}
351
+
352
+				return false;
353
+
354
+			case \T_NAMESPACE:
355
+			case \T_PARENT:
356
+			case \T_SELF:
357
+			case \T_DOUBLE_COLON:
358
+				$nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonSimple + 1), ($end + 1), true);
359
+
360
+				if ($tokens[$nextNonSimple]['code'] === \T_NAMESPACE) {
361
+					// Allow only `namespace\...`.
362
+					if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_NS_SEPARATOR) {
363
+						return false;
364
+					}
365
+				} elseif ($tokens[$nextNonSimple]['code'] === \T_PARENT
366
+					|| $tokens[$nextNonSimple]['code'] === \T_SELF
367
+				) {
368
+					// Allow only `parent::` and `self::`.
369
+					if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_DOUBLE_COLON) {
370
+						return false;
371
+					}
372
+				} elseif ($tokens[$nextNonSimple]['code'] === \T_DOUBLE_COLON) {
373
+					// Allow only `T_STRING::T_STRING`.
374
+					if ($nextNonEmpty === false || $tokens[$nextNonEmpty]['code'] !== \T_STRING) {
375
+						return false;
376
+					}
377
+
378
+					$prevNonEmpty = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($nextNonSimple - 1), null, true);
379
+					// No need to worry about parent/self, that's handled above and
380
+					// the double colon is skipped over in that case.
381
+					if ($prevNonEmpty === false || $tokens[$prevNonEmpty]['code'] !== \T_STRING) {
382
+						return false;
383
+					}
384
+				}
385
+
386
+				// Examine what comes after the namespace/parent/self/double colon, if anything.
387
+				return $this->isStaticValue($phpcsFile, $tokens, ($nextNonEmpty + 1), $end, $nestedArrays);
388
+
389
+			case \T_ARRAY:
390
+			case \T_OPEN_SHORT_ARRAY:
391
+				++$nestedArrays;
392
+
393
+				$arrayItems = $this->getFunctionCallParameters($phpcsFile, $nextNonSimple);
394
+				if (empty($arrayItems) === false) {
395
+					foreach ($arrayItems as $item) {
396
+						// Check for a double arrow, but only if it's for this array item, not for a nested array.
397
+						$doubleArrow = false;
398
+
399
+						$maybeDoubleArrow = $phpcsFile->findNext(
400
+							array(\T_DOUBLE_ARROW, \T_ARRAY, \T_OPEN_SHORT_ARRAY),
401
+							$item['start'],
402
+							($item['end'] + 1)
403
+						);
404
+						if ($maybeDoubleArrow !== false && $tokens[$maybeDoubleArrow]['code'] === \T_DOUBLE_ARROW) {
405
+							// Double arrow is for this nesting level.
406
+							$doubleArrow = $maybeDoubleArrow;
407
+						}
408
+
409
+						if ($doubleArrow === false) {
410
+							if ($this->isStaticValue($phpcsFile, $tokens, $item['start'], $item['end'], $nestedArrays) === false) {
411
+								return false;
412
+							}
413
+
414
+						} else {
415
+							// Examine array key.
416
+							if ($this->isStaticValue($phpcsFile, $tokens, $item['start'], ($doubleArrow - 1), $nestedArrays) === false) {
417
+								return false;
418
+							}
419
+
420
+							// Examine array value.
421
+							if ($this->isStaticValue($phpcsFile, $tokens, ($doubleArrow + 1), $item['end'], $nestedArrays) === false) {
422
+								return false;
423
+							}
424
+						}
425
+					}
426
+				}
427
+
428
+				--$nestedArrays;
429
+
430
+				/*
431 431
                  * Find the end of the array.
432 432
                  * We already know we will have a valid closer as otherwise we wouldn't have been
433 433
                  * able to get the array items.
434 434
                  */
435
-                $closer = ($nextNonSimple + 1);
436
-                if ($tokens[$nextNonSimple]['code'] === \T_OPEN_SHORT_ARRAY
437
-                    && isset($tokens[$nextNonSimple]['bracket_closer']) === true
438
-                ) {
439
-                    $closer = $tokens[$nextNonSimple]['bracket_closer'];
440
-                } else {
441
-                    $maybeOpener = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonSimple + 1), ($end + 1), true);
442
-                    if ($tokens[$maybeOpener]['code'] === \T_OPEN_PARENTHESIS) {
443
-                        $opener = $maybeOpener;
444
-                        if (isset($tokens[$opener]['parenthesis_closer']) === true) {
445
-                            $closer = $tokens[$opener]['parenthesis_closer'];
446
-                        }
447
-                    }
448
-                }
449
-
450
-                if ($closer === $end) {
451
-                    return true;
452
-                }
453
-
454
-                // Examine what comes after the array, if anything.
455
-                return $this->isStaticValue($phpcsFile, $tokens, ($closer + 1), $end, $nestedArrays);
456
-
457
-        }
458
-
459
-        // Ok, so this unsafe token was not one of the exceptions, i.e. this is a PHP 5.6+ syntax.
460
-        return false;
461
-    }
462
-
463
-
464
-    /**
465
-     * Throw an error if a scalar expression is found.
466
-     *
467
-     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
468
-     * @param int                   $stackPtr  The position of the token to link the error to.
469
-     * @param string                $type      Type of usage found.
470
-     * @param string                $content   Optional. The value for the declaration as found.
471
-     *
472
-     * @return void
473
-     */
474
-    protected function throwError(File $phpcsFile, $stackPtr, $type, $content = '')
475
-    {
476
-        $error     = static::ERROR_PHRASE;
477
-        $phrase    = '';
478
-        $errorCode = 'Found';
479
-
480
-        if (isset($this->errorPhrases[$type]) === true) {
481
-            $errorCode = $this->stringToErrorCode($type) . 'Found';
482
-            $phrase    = $this->errorPhrases[$type];
483
-        }
484
-
485
-        $data = array($phrase);
486
-
487
-        if (empty($content) === false) {
488
-            $error .= ' Found: %s';
489
-            $data[] = $content;
490
-        }
491
-
492
-        $phpcsFile->addError($error, $stackPtr, $errorCode, $data);
493
-    }
494
-
495
-
496
-    /**
497
-     * Helper function to find the end of multi variable/constant declarations.
498
-     *
499
-     * Checks whether a certain part of a declaration needs to be skipped over or
500
-     * if it is the real end of the declaration.
501
-     *
502
-     * @param array $tokens      Token stack of the current file.
503
-     * @param int   $endPtr      The token to examine as a candidate end pointer.
504
-     * @param int   $targetLevel Target nesting level.
505
-     *
506
-     * @return bool|int True if this is the real end. Int stackPtr to skip to if not.
507
-     */
508
-    private function isRealEndOfDeclaration($tokens, $endPtr, $targetLevel)
509
-    {
510
-        // Ignore anything within short array definition brackets for now.
511
-        if ($tokens[$endPtr]['code'] === \T_OPEN_SHORT_ARRAY
512
-            && (isset($tokens[$endPtr]['bracket_opener'])
513
-                && $tokens[$endPtr]['bracket_opener'] === $endPtr)
514
-            && isset($tokens[$endPtr]['bracket_closer'])
515
-        ) {
516
-            // Skip forward to the end of the short array definition.
517
-            return $tokens[$endPtr]['bracket_closer'];
518
-        }
519
-
520
-        // Skip past comma's at a lower nesting level.
521
-        if ($tokens[$endPtr]['code'] === \T_COMMA) {
522
-            // Check if a comma is at the nesting level we're targetting.
523
-            $nestingLevel = 0;
524
-            if (isset($tokens[$endPtr]['nested_parenthesis']) === true) {
525
-                $nestingLevel = \count($tokens[$endPtr]['nested_parenthesis']);
526
-            }
527
-            if ($nestingLevel > $targetLevel) {
528
-                return $endPtr;
529
-            }
530
-        }
531
-
532
-        return true;
533
-    }
435
+				$closer = ($nextNonSimple + 1);
436
+				if ($tokens[$nextNonSimple]['code'] === \T_OPEN_SHORT_ARRAY
437
+					&& isset($tokens[$nextNonSimple]['bracket_closer']) === true
438
+				) {
439
+					$closer = $tokens[$nextNonSimple]['bracket_closer'];
440
+				} else {
441
+					$maybeOpener = $phpcsFile->findNext(Tokens::$emptyTokens, ($nextNonSimple + 1), ($end + 1), true);
442
+					if ($tokens[$maybeOpener]['code'] === \T_OPEN_PARENTHESIS) {
443
+						$opener = $maybeOpener;
444
+						if (isset($tokens[$opener]['parenthesis_closer']) === true) {
445
+							$closer = $tokens[$opener]['parenthesis_closer'];
446
+						}
447
+					}
448
+				}
449
+
450
+				if ($closer === $end) {
451
+					return true;
452
+				}
453
+
454
+				// Examine what comes after the array, if anything.
455
+				return $this->isStaticValue($phpcsFile, $tokens, ($closer + 1), $end, $nestedArrays);
456
+
457
+		}
458
+
459
+		// Ok, so this unsafe token was not one of the exceptions, i.e. this is a PHP 5.6+ syntax.
460
+		return false;
461
+	}
462
+
463
+
464
+	/**
465
+	 * Throw an error if a scalar expression is found.
466
+	 *
467
+	 * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
468
+	 * @param int                   $stackPtr  The position of the token to link the error to.
469
+	 * @param string                $type      Type of usage found.
470
+	 * @param string                $content   Optional. The value for the declaration as found.
471
+	 *
472
+	 * @return void
473
+	 */
474
+	protected function throwError(File $phpcsFile, $stackPtr, $type, $content = '')
475
+	{
476
+		$error     = static::ERROR_PHRASE;
477
+		$phrase    = '';
478
+		$errorCode = 'Found';
479
+
480
+		if (isset($this->errorPhrases[$type]) === true) {
481
+			$errorCode = $this->stringToErrorCode($type) . 'Found';
482
+			$phrase    = $this->errorPhrases[$type];
483
+		}
484
+
485
+		$data = array($phrase);
486
+
487
+		if (empty($content) === false) {
488
+			$error .= ' Found: %s';
489
+			$data[] = $content;
490
+		}
491
+
492
+		$phpcsFile->addError($error, $stackPtr, $errorCode, $data);
493
+	}
494
+
495
+
496
+	/**
497
+	 * Helper function to find the end of multi variable/constant declarations.
498
+	 *
499
+	 * Checks whether a certain part of a declaration needs to be skipped over or
500
+	 * if it is the real end of the declaration.
501
+	 *
502
+	 * @param array $tokens      Token stack of the current file.
503
+	 * @param int   $endPtr      The token to examine as a candidate end pointer.
504
+	 * @param int   $targetLevel Target nesting level.
505
+	 *
506
+	 * @return bool|int True if this is the real end. Int stackPtr to skip to if not.
507
+	 */
508
+	private function isRealEndOfDeclaration($tokens, $endPtr, $targetLevel)
509
+	{
510
+		// Ignore anything within short array definition brackets for now.
511
+		if ($tokens[$endPtr]['code'] === \T_OPEN_SHORT_ARRAY
512
+			&& (isset($tokens[$endPtr]['bracket_opener'])
513
+				&& $tokens[$endPtr]['bracket_opener'] === $endPtr)
514
+			&& isset($tokens[$endPtr]['bracket_closer'])
515
+		) {
516
+			// Skip forward to the end of the short array definition.
517
+			return $tokens[$endPtr]['bracket_closer'];
518
+		}
519
+
520
+		// Skip past comma's at a lower nesting level.
521
+		if ($tokens[$endPtr]['code'] === \T_COMMA) {
522
+			// Check if a comma is at the nesting level we're targetting.
523
+			$nestingLevel = 0;
524
+			if (isset($tokens[$endPtr]['nested_parenthesis']) === true) {
525
+				$nestingLevel = \count($tokens[$endPtr]['nested_parenthesis']);
526
+			}
527
+			if ($nestingLevel > $targetLevel) {
528
+				return $endPtr;
529
+			}
530
+		}
531
+
532
+		return true;
533
+	}
534 534
 }
Please login to merge, or discard this patch.
PHPCompatibility/Sniffs/InitialValue/NewConstantArraysUsingConstSniff.php 1 patch
Indentation   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -28,51 +28,51 @@
 block discarded – undo
28 28
 class NewConstantArraysUsingConstSniff 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_CONST);
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_CONST);
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 in the
46
-     *                                         stack passed in $tokens.
47
-     *
48
-     * @return void
49
-     */
50
-    public function process(File $phpcsFile, $stackPtr)
51
-    {
52
-        if ($this->supportsBelow('5.5') !== true) {
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 in the
46
+	 *                                         stack passed in $tokens.
47
+	 *
48
+	 * @return void
49
+	 */
50
+	public function process(File $phpcsFile, $stackPtr)
51
+	{
52
+		if ($this->supportsBelow('5.5') !== true) {
53
+			return;
54
+		}
55 55
 
56
-        $tokens = $phpcsFile->getTokens();
57
-        $find   = array(
58
-            \T_ARRAY            => \T_ARRAY,
59
-            \T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY,
60
-        );
56
+		$tokens = $phpcsFile->getTokens();
57
+		$find   = array(
58
+			\T_ARRAY            => \T_ARRAY,
59
+			\T_OPEN_SHORT_ARRAY => \T_OPEN_SHORT_ARRAY,
60
+		);
61 61
 
62
-        while (($hasArray = $phpcsFile->findNext($find, ($stackPtr + 1), null, false, null, true)) !== false) {
63
-            $phpcsFile->addError(
64
-                'Constant arrays using the "const" keyword are not allowed in PHP 5.5 or earlier',
65
-                $hasArray,
66
-                'Found'
67
-            );
62
+		while (($hasArray = $phpcsFile->findNext($find, ($stackPtr + 1), null, false, null, true)) !== false) {
63
+			$phpcsFile->addError(
64
+				'Constant arrays using the "const" keyword are not allowed in PHP 5.5 or earlier',
65
+				$hasArray,
66
+				'Found'
67
+			);
68 68
 
69
-            // Skip past the content of the array.
70
-            $stackPtr = $hasArray;
71
-            if ($tokens[$hasArray]['code'] === \T_OPEN_SHORT_ARRAY && isset($tokens[$hasArray]['bracket_closer'])) {
72
-                $stackPtr = $tokens[$hasArray]['bracket_closer'];
73
-            } elseif ($tokens[$hasArray]['code'] === \T_ARRAY && isset($tokens[$hasArray]['parenthesis_closer'])) {
74
-                $stackPtr = $tokens[$hasArray]['parenthesis_closer'];
75
-            }
76
-        }
77
-    }
69
+			// Skip past the content of the array.
70
+			$stackPtr = $hasArray;
71
+			if ($tokens[$hasArray]['code'] === \T_OPEN_SHORT_ARRAY && isset($tokens[$hasArray]['bracket_closer'])) {
72
+				$stackPtr = $tokens[$hasArray]['bracket_closer'];
73
+			} elseif ($tokens[$hasArray]['code'] === \T_ARRAY && isset($tokens[$hasArray]['parenthesis_closer'])) {
74
+				$stackPtr = $tokens[$hasArray]['parenthesis_closer'];
75
+			}
76
+		}
77
+	}
78 78
 }
Please login to merge, or discard this patch.
PHPCompatibility/Sniffs/InitialValue/NewConstantArraysUsingDefineSniff.php 1 patch
Indentation   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -28,70 +28,70 @@
 block discarded – undo
28 28
 class NewConstantArraysUsingDefineSniff 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_STRING);
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_STRING);
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 in the
46
-     *                                         stack passed in $tokens.
47
-     *
48
-     * @return void
49
-     */
50
-    public function process(File $phpcsFile, $stackPtr)
51
-    {
52
-        if ($this->supportsBelow('5.6') !== true) {
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 in the
46
+	 *                                         stack passed in $tokens.
47
+	 *
48
+	 * @return void
49
+	 */
50
+	public function process(File $phpcsFile, $stackPtr)
51
+	{
52
+		if ($this->supportsBelow('5.6') !== true) {
53
+			return;
54
+		}
55 55
 
56
-        $tokens = $phpcsFile->getTokens();
56
+		$tokens = $phpcsFile->getTokens();
57 57
 
58
-        $ignore = array(
59
-            \T_DOUBLE_COLON    => true,
60
-            \T_OBJECT_OPERATOR => true,
61
-            \T_FUNCTION        => true,
62
-            \T_CONST           => true,
63
-        );
58
+		$ignore = array(
59
+			\T_DOUBLE_COLON    => true,
60
+			\T_OBJECT_OPERATOR => true,
61
+			\T_FUNCTION        => true,
62
+			\T_CONST           => true,
63
+		);
64 64
 
65
-        $prevToken = $phpcsFile->findPrevious(\T_WHITESPACE, ($stackPtr - 1), null, true);
66
-        if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
67
-            // Not a call to a PHP function.
68
-            return;
69
-        }
65
+		$prevToken = $phpcsFile->findPrevious(\T_WHITESPACE, ($stackPtr - 1), null, true);
66
+		if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
67
+			// Not a call to a PHP function.
68
+			return;
69
+		}
70 70
 
71
-        $functionLc = strtolower($tokens[$stackPtr]['content']);
72
-        if ($functionLc !== 'define') {
73
-            return;
74
-        }
71
+		$functionLc = strtolower($tokens[$stackPtr]['content']);
72
+		if ($functionLc !== 'define') {
73
+			return;
74
+		}
75 75
 
76
-        $secondParam = $this->getFunctionCallParameter($phpcsFile, $stackPtr, 2);
77
-        if (isset($secondParam['start'], $secondParam['end']) === false) {
78
-            return;
79
-        }
76
+		$secondParam = $this->getFunctionCallParameter($phpcsFile, $stackPtr, 2);
77
+		if (isset($secondParam['start'], $secondParam['end']) === false) {
78
+			return;
79
+		}
80 80
 
81
-        $targetNestingLevel = 0;
82
-        if (isset($tokens[$secondParam['start']]['nested_parenthesis'])) {
83
-            $targetNestingLevel = \count($tokens[$secondParam['start']]['nested_parenthesis']);
84
-        }
81
+		$targetNestingLevel = 0;
82
+		if (isset($tokens[$secondParam['start']]['nested_parenthesis'])) {
83
+			$targetNestingLevel = \count($tokens[$secondParam['start']]['nested_parenthesis']);
84
+		}
85 85
 
86
-        $array = $phpcsFile->findNext(array(\T_ARRAY, \T_OPEN_SHORT_ARRAY), $secondParam['start'], ($secondParam['end'] + 1));
87
-        if ($array !== false) {
88
-            if ((isset($tokens[$array]['nested_parenthesis']) === false && $targetNestingLevel === 0) || \count($tokens[$array]['nested_parenthesis']) === $targetNestingLevel) {
89
-                $phpcsFile->addError(
90
-                    'Constant arrays using define are not allowed in PHP 5.6 or earlier',
91
-                    $array,
92
-                    'Found'
93
-                );
94
-            }
95
-        }
96
-    }
86
+		$array = $phpcsFile->findNext(array(\T_ARRAY, \T_OPEN_SHORT_ARRAY), $secondParam['start'], ($secondParam['end'] + 1));
87
+		if ($array !== false) {
88
+			if ((isset($tokens[$array]['nested_parenthesis']) === false && $targetNestingLevel === 0) || \count($tokens[$array]['nested_parenthesis']) === $targetNestingLevel) {
89
+				$phpcsFile->addError(
90
+					'Constant arrays using define are not allowed in PHP 5.6 or earlier',
91
+					$array,
92
+					'Found'
93
+				);
94
+			}
95
+		}
96
+	}
97 97
 }
Please login to merge, or discard this patch.