Completed
Push — master ( 8ac4b1...9b48a3 )
by Juliette
12s
created

PHPCSHelper::findStartOfStatement()   C

Complexity

Conditions 14
Paths 19

Size

Total Lines 59

Duplication

Lines 20
Ratio 33.9 %

Importance

Changes 0
Metric Value
dl 20
loc 59
rs 6.2666
c 0
b 0
f 0
cc 14
nc 19
nop 3

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * PHPCS cross-version compatibility helper class.
4
 *
5
 * @category PHP
6
 * @package  PHPCompatibility
7
 * @author   Juliette Reinders Folmer <[email protected]>
8
 */
9
10
namespace PHPCompatibility;
11
12
use PHP_CodeSniffer_File as File;
13
use PHP_CodeSniffer_Tokens as Tokens;
14
15
/**
16
 * \PHPCompatibility\PHPCSHelper
17
 *
18
 * PHPCS cross-version compatibility helper class.
19
 *
20
 * A number of PHPCS classes were split up into several classes in PHPCS 3.x
21
 * Those classes cannot be aliased as they don't represent the same object.
22
 * This class provides helper methods for functions which were contained in
23
 * one of these classes and which are used within the PHPCompatibility library.
24
 *
25
 * @category PHP
26
 * @package  PHPCompatibility
27
 * @author   Juliette Reinders Folmer <[email protected]>
28
 */
29
class PHPCSHelper
30
{
31
32
    /**
33
     * Get the PHPCS version number.
34
     *
35
     * @return string
36
     */
37
    public static function getVersion()
38
    {
39
        if (defined('\PHP_CodeSniffer\Config::VERSION')) {
40
            // PHPCS 3.x.
41
            return \PHP_CodeSniffer\Config::VERSION;
42
        } else {
43
            // PHPCS 2.x.
44
            return \PHP_CodeSniffer::VERSION;
45
        }
46
    }
47
48
49
    /**
50
     * Pass config data to PHPCS.
51
     *
52
     * PHPCS cross-version compatibility helper.
53
     *
54
     * @param string      $key   The name of the config value.
55
     * @param string|null $value The value to set. If null, the config entry
56
     *                           is deleted, reverting it to the default value.
57
     * @param boolean     $temp  Set this config data temporarily for this script run.
58
     *                           This will not write the config data to the config file.
59
     *
60
     * @return void
61
     */
62
    public static function setConfigData($key, $value, $temp = false)
63
    {
64
        if (method_exists('\PHP_CodeSniffer\Config', 'setConfigData')) {
65
            // PHPCS 3.x.
66
            \PHP_CodeSniffer\Config::setConfigData($key, $value, $temp);
67
        } else {
68
            // PHPCS 2.x.
69
            \PHP_CodeSniffer::setConfigData($key, $value, $temp);
70
        }
71
    }
72
73
74
    /**
75
     * Get the value of a single PHPCS config key.
76
     *
77
     * @param string $key The name of the config value.
78
     *
79
     * @return string|null
80
     */
81
    public static function getConfigData($key)
82
    {
83
        if (method_exists('\PHP_CodeSniffer\Config', 'getConfigData')) {
84
            // PHPCS 3.x.
85
            return \PHP_CodeSniffer\Config::getConfigData($key);
86
        } else {
87
            // PHPCS 2.x.
88
            return \PHP_CodeSniffer::getConfigData($key);
89
        }
90
    }
91
92
93
    /**
94
     * Get the value of a single PHPCS config key.
95
     *
96
     * This config key can be set in the `CodeSniffer.conf` file, on the
97
     * command-line or in a ruleset.
98
     *
99
     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
100
     * @param string                $key       The name of the config value.
101
     *
102
     * @return string|null
103
     */
104
    public static function getCommandLineData($phpcsFile, $key)
105
    {
106
        if (class_exists('\PHP_CodeSniffer\Config')) {
107
            // PHPCS 3.x.
108
            $config = $phpcsFile->config;
1 ignored issue
show
Bug introduced by
The property config does not seem to exist in PHP_CodeSniffer_File.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
109
            if (isset($config->{$key})) {
110
                return $config->{$key};
111
            }
112
        } else {
113
            // PHPCS 2.x.
114
            $config = $phpcsFile->phpcs->cli->getCommandLineValues();
1 ignored issue
show
Bug introduced by
The property phpcs does not seem to exist in PHP_CodeSniffer_File.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
115
            if (isset($config[$key])) {
116
                return $config[$key];
117
            }
118
        }
119
120
        return null;
121
    }
122
123
124
    /**
125
     * Returns the position of the first non-whitespace token in a statement.
126
     *
127
     * {@internal Duplicate of same method as contained in the `\PHP_CodeSniffer_File`
128
     * class and introduced in PHPCS 2.1.0 and improved in PHPCS 2.7.1.
129
     *
130
     * Once the minimum supported PHPCS version for this standard goes beyond
131
     * that, this method can be removed and calls to it replaced with
132
     * `$phpcsFile->findStartOfStatement($start, $ignore)` calls.
133
     *
134
     * Last synced with PHPCS version: PHPCS 3.3.2 at commit 6ad28354c04b364c3c71a34e4a18b629cc3b231e}}
135
     *
136
     * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
137
     * @param int                   $start     The position to start searching from in the token stack.
138
     * @param int|array             $ignore    Token types that should not be considered stop points.
139
     *
140
     * @return int
141
     */
142
    public static function findStartOfStatement(File $phpcsFile, $start, $ignore = null)
143
    {
144
        if (version_compare(self::getVersion(), '2.7.1', '>=') === true) {
145
            return $phpcsFile->findStartOfStatement($start, $ignore);
146
        }
147
148
        $tokens    = $phpcsFile->getTokens();
149
        $endTokens = Tokens::$blockOpeners;
150
151
        $endTokens[T_COLON]            = true;
152
        $endTokens[T_COMMA]            = true;
153
        $endTokens[T_DOUBLE_ARROW]     = true;
154
        $endTokens[T_SEMICOLON]        = true;
155
        $endTokens[T_OPEN_TAG]         = true;
156
        $endTokens[T_CLOSE_TAG]        = true;
157
        $endTokens[T_OPEN_SHORT_ARRAY] = true;
158
159 View Code Duplication
        if ($ignore !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
160
            $ignore = (array) $ignore;
161
            foreach ($ignore as $code) {
162
                if (isset($endTokens[$code]) === true) {
163
                    unset($endTokens[$code]);
164
                }
165
            }
166
        }
167
168
        $lastNotEmpty = $start;
169
170
        for ($i = $start; $i >= 0; $i--) {
171
            if (isset($endTokens[$tokens[$i]['code']]) === true) {
172
                // Found the end of the previous statement.
173
                return $lastNotEmpty;
174
            }
175
176
            if (isset($tokens[$i]['scope_opener']) === true
177
                && $i === $tokens[$i]['scope_closer']
178
            ) {
179
                // Found the end of the previous scope block.
180
                return $lastNotEmpty;
181
            }
182
183
            // Skip nested statements.
184 View Code Duplication
            if (isset($tokens[$i]['bracket_opener']) === true
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
185
                && $i === $tokens[$i]['bracket_closer']
186
            ) {
187
                $i = $tokens[$i]['bracket_opener'];
188
            } elseif (isset($tokens[$i]['parenthesis_opener']) === true
189
                && $i === $tokens[$i]['parenthesis_closer']
190
            ) {
191
                $i = $tokens[$i]['parenthesis_opener'];
192
            }
193
194 View Code Duplication
            if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]) === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
195
                $lastNotEmpty = $i;
196
            }
197
        }//end for
198
199
        return 0;
200
    }
201
202
203
    /**
204
     * Returns the position of the last non-whitespace token in a statement.
205
     *
206
     * {@internal Duplicate of same method as contained in the `\PHP_CodeSniffer_File`
207
     * class and introduced in PHPCS 2.1.0 and improved in PHPCS 2.7.1 and 3.3.0.
208
     *
209
     * Once the minimum supported PHPCS version for this standard goes beyond
210
     * that, this method can be removed and calls to it replaced with
211
     * `$phpcsFile->findEndOfStatement($start, $ignore)` calls.
212
     *
213
     * Last synced with PHPCS version: PHPCS 3.3.0-alpha at commit f5d899dcb5c534a1c3cca34668624517856ba823}}
214
     *
215
     * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
216
     * @param int                   $start     The position to start searching from in the token stack.
217
     * @param int|array             $ignore    Token types that should not be considered stop points.
218
     *
219
     * @return int
220
     */
221
    public static function findEndOfStatement(\PHP_CodeSniffer_File $phpcsFile, $start, $ignore = null)
222
    {
223
        if (version_compare(self::getVersion(), '3.3.0', '>=') === true) {
224
            return $phpcsFile->findEndOfStatement($start, $ignore);
225
        }
226
227
        $tokens    = $phpcsFile->getTokens();
228
        $endTokens = array(
229
            T_COLON                => true,
230
            T_COMMA                => true,
231
            T_DOUBLE_ARROW         => true,
232
            T_SEMICOLON            => true,
233
            T_CLOSE_PARENTHESIS    => true,
234
            T_CLOSE_SQUARE_BRACKET => true,
235
            T_CLOSE_CURLY_BRACKET  => true,
236
            T_CLOSE_SHORT_ARRAY    => true,
237
            T_OPEN_TAG             => true,
238
            T_CLOSE_TAG            => true,
239
        );
240
241 View Code Duplication
        if ($ignore !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
242
            $ignore = (array) $ignore;
243
            foreach ($ignore as $code) {
244
                if (isset($endTokens[$code]) === true) {
245
                    unset($endTokens[$code]);
246
                }
247
            }
248
        }
249
250
        $lastNotEmpty = $start;
251
252
        for ($i = $start; $i < $phpcsFile->numTokens; $i++) {
1 ignored issue
show
Bug introduced by
The property numTokens does not seem to exist in PHP_CodeSniffer_File.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
253
            if ($i !== $start && isset($endTokens[$tokens[$i]['code']]) === true) {
254
                // Found the end of the statement.
255
                if ($tokens[$i]['code'] === T_CLOSE_PARENTHESIS
256
                    || $tokens[$i]['code'] === T_CLOSE_SQUARE_BRACKET
257
                    || $tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET
258
                    || $tokens[$i]['code'] === T_CLOSE_SHORT_ARRAY
259
                    || $tokens[$i]['code'] === T_OPEN_TAG
260
                    || $tokens[$i]['code'] === T_CLOSE_TAG
261
                ) {
262
                    return $lastNotEmpty;
263
                }
264
265
                return $i;
266
            }
267
268
            // Skip nested statements.
269
            if (isset($tokens[$i]['scope_closer']) === true
270
                && ($i === $tokens[$i]['scope_opener']
271
                || $i === $tokens[$i]['scope_condition'])
272
            ) {
273
                if ($i === $start && isset(Tokens::$scopeOpeners[$tokens[$i]['code']]) === true) {
274
                    return $tokens[$i]['scope_closer'];
275
                }
276
277
                $i = $tokens[$i]['scope_closer'];
278
            } elseif (isset($tokens[$i]['bracket_closer']) === true
279
                && $i === $tokens[$i]['bracket_opener']
280
            ) {
281
                $i = $tokens[$i]['bracket_closer'];
282
            } elseif (isset($tokens[$i]['parenthesis_closer']) === true
283
                && $i === $tokens[$i]['parenthesis_opener']
284
            ) {
285
                $i = $tokens[$i]['parenthesis_closer'];
286
            }
287
288 View Code Duplication
            if (isset(\PHP_CodeSniffer_Tokens::$emptyTokens[$tokens[$i]['code']]) === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
289
                $lastNotEmpty = $i;
290
            }
291
        }//end for
292
293
        return ($phpcsFile->numTokens - 1);
294
    }
295
296
297
    /**
298
     * Returns the name of the class that the specified class extends
299
     * (works for classes, anonymous classes and interfaces).
300
     *
301
     * Returns FALSE on error or if there is no extended class name.
302
     *
303
     * {@internal Duplicate of same method as contained in the `\PHP_CodeSniffer_File`
304
     * class, but with some improvements which have been introduced in
305
     * PHPCS 2.8.0.
306
     * {@link https://github.com/squizlabs/PHP_CodeSniffer/commit/0011d448119d4c568e3ac1f825ae78815bf2cc34}.
307
     *
308
     * Once the minimum supported PHPCS version for this standard goes beyond
309
     * that, this method can be removed and calls to it replaced with
310
     * `$phpcsFile->findExtendedClassName($stackPtr)` calls.
311
     *
312
     * Last synced with PHPCS version: PHPCS 3.1.0-alpha at commit a9efcc9b0703f3f9f4a900623d4e97128a6aafc6}}
313
     *
314
     * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
315
     * @param int                   $stackPtr  The position of the class token in the stack.
316
     *
317
     * @return string|false
318
     */
319
    public static function findExtendedClassName(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
320
    {
321
        if (version_compare(self::getVersion(), '3.1.0', '>=') === true) {
322
            return $phpcsFile->findExtendedClassName($stackPtr);
323
        }
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 View Code Duplication
        if ($tokens[$stackPtr]['code'] !== T_CLASS
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
333
            && $tokens[$stackPtr]['type'] !== 'T_ANON_CLASS'
334
            && $tokens[$stackPtr]['type'] !== 'T_INTERFACE'
335
        ) {
336
            return false;
337
        }
338
339
        if (isset($tokens[$stackPtr]['scope_closer']) === false) {
340
            return false;
341
        }
342
343
        $classCloserIndex = $tokens[$stackPtr]['scope_closer'];
344
        $extendsIndex     = $phpcsFile->findNext(T_EXTENDS, $stackPtr, $classCloserIndex);
345
        if ($extendsIndex === false) {
346
            return false;
347
        }
348
349
        $find = array(
350
            T_NS_SEPARATOR,
351
            T_STRING,
352
            T_WHITESPACE,
353
        );
354
355
        $end  = $phpcsFile->findNext($find, ($extendsIndex + 1), $classCloserIndex, true);
356
        $name = $phpcsFile->getTokensAsString(($extendsIndex + 1), ($end - $extendsIndex - 1));
357
        $name = trim($name);
358
359
        if ($name === '') {
360
            return false;
361
        }
362
363
        return $name;
364
    }
365
366
367
    /**
368
     * Returns the name(s) of the interface(s) that the specified class implements.
369
     *
370
     * Returns FALSE on error or if there are no implemented interface names.
371
     *
372
     * {@internal Duplicate of same method as introduced in PHPCS 2.7.
373
     * This method also includes an improvement we use which was only introduced
374
     * in PHPCS 2.8.0, so only defer to upstream for higher versions.
375
     * Once the minimum supported PHPCS version for this sniff library goes beyond
376
     * that, this method can be removed and calls to it replaced with
377
     * `$phpcsFile->findImplementedInterfaceNames($stackPtr)` calls.}}
378
     *
379
     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
380
     * @param int                   $stackPtr  The position of the class token.
381
     *
382
     * @return array|false
383
     */
384
    public static function findImplementedInterfaceNames(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
385
    {
386
        if (version_compare(self::getVersion(), '2.7.1', '>') === true) {
387
            return $phpcsFile->findImplementedInterfaceNames($stackPtr);
388
        }
389
390
        $tokens = $phpcsFile->getTokens();
391
392
        // Check for the existence of the token.
393
        if (isset($tokens[$stackPtr]) === false) {
394
            return false;
395
        }
396
397
        if ($tokens[$stackPtr]['code'] !== T_CLASS
398
            && $tokens[$stackPtr]['type'] !== 'T_ANON_CLASS'
399
        ) {
400
            return false;
401
        }
402
403
        if (isset($tokens[$stackPtr]['scope_closer']) === false) {
404
            return false;
405
        }
406
407
        $classOpenerIndex = $tokens[$stackPtr]['scope_opener'];
408
        $implementsIndex  = $phpcsFile->findNext(T_IMPLEMENTS, $stackPtr, $classOpenerIndex);
409
        if ($implementsIndex === false) {
410
            return false;
411
        }
412
413
        $find = array(
414
            T_NS_SEPARATOR,
415
            T_STRING,
416
            T_WHITESPACE,
417
            T_COMMA,
418
        );
419
420
        $end  = $phpcsFile->findNext($find, ($implementsIndex + 1), ($classOpenerIndex + 1), true);
421
        $name = $phpcsFile->getTokensAsString(($implementsIndex + 1), ($end - $implementsIndex - 1));
422
        $name = trim($name);
423
424
        if ($name === '') {
425
            return false;
426
        } else {
427
            $names = explode(',', $name);
428
            $names = array_map('trim', $names);
429
            return $names;
430
        }
431
    }
432
433
434
    /**
435
     * Returns the method parameters for the specified function token.
436
     *
437
     * Each parameter is in the following format:
438
     *
439
     * <code>
440
     *   0 => array(
441
     *         'name'              => '$var',  // The variable name.
442
     *         'token'             => integer, // The stack pointer to the variable name.
443
     *         'content'           => string,  // The full content of the variable definition.
444
     *         'pass_by_reference' => boolean, // Is the variable passed by reference?
445
     *         'variable_length'   => boolean, // Is the param of variable length through use of `...` ?
446
     *         'type_hint'         => string,  // The type hint for the variable.
447
     *         'type_hint_token'   => integer, // The stack pointer to the type hint
448
     *                                         // or false if there is no type hint.
449
     *         'nullable_type'     => boolean, // Is the variable using a nullable type?
450
     *        )
451
     * </code>
452
     *
453
     * Parameters with default values have an additional array index of
454
     * 'default' with the value of the default as a string.
455
     *
456
     * {@internal Duplicate of same method as contained in the `\PHP_CodeSniffer_File`
457
     * class.
458
     *
459
     * Last synced with PHPCS version: PHPCS 3.3.0-alpha at commit 53a28408d345044c0360c2c1b4a2aaebf4a3b8c9}}
460
     *
461
     * @param \PHP_CodeSniffer_File $phpcsFile Instance of phpcsFile.
462
     * @param int                   $stackPtr  The position in the stack of the
463
     *                                         function token to acquire the
464
     *                                         parameters for.
465
     *
466
     * @return array|false
467
     * @throws \PHP_CodeSniffer_Exception If the specified $stackPtr is not of
468
     *                                    type T_FUNCTION or T_CLOSURE.
469
     */
470
    public static function getMethodParameters(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
471
    {
472
        if (version_compare(self::getVersion(), '3.3.0', '>=') === true) {
473
            return $phpcsFile->getMethodParameters($stackPtr);
474
        }
475
476
        $tokens = $phpcsFile->getTokens();
477
478
        // Check for the existence of the token.
479
        if (isset($tokens[$stackPtr]) === false) {
480
            return false;
481
        }
482
483 View Code Duplication
        if ($tokens[$stackPtr]['code'] !== T_FUNCTION
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
484
            && $tokens[$stackPtr]['code'] !== T_CLOSURE
485
        ) {
486
            throw new \PHP_CodeSniffer_Exception('$stackPtr must be of type T_FUNCTION or T_CLOSURE');
487
        }
488
489
        $opener = $tokens[$stackPtr]['parenthesis_opener'];
490
        $closer = $tokens[$stackPtr]['parenthesis_closer'];
491
492
        $vars            = array();
493
        $currVar         = null;
494
        $paramStart      = ($opener + 1);
495
        $defaultStart    = null;
496
        $paramCount      = 0;
497
        $passByReference = false;
498
        $variableLength  = false;
499
        $typeHint        = '';
500
        $typeHintToken   = false;
501
        $nullableType    = false;
502
503
        for ($i = $paramStart; $i <= $closer; $i++) {
504
            // Check to see if this token has a parenthesis or bracket opener. If it does
505
            // it's likely to be an array which might have arguments in it. This
506
            // could cause problems in our parsing below, so lets just skip to the
507
            // end of it.
508 View Code Duplication
            if (isset($tokens[$i]['parenthesis_opener']) === true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
509
                // Don't do this if it's the close parenthesis for the method.
510
                if ($i !== $tokens[$i]['parenthesis_closer']) {
511
                    $i = ($tokens[$i]['parenthesis_closer'] + 1);
512
                }
513
            }
514
515 View Code Duplication
            if (isset($tokens[$i]['bracket_opener']) === true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
516
                // Don't do this if it's the close parenthesis for the method.
517
                if ($i !== $tokens[$i]['bracket_closer']) {
518
                    $i = ($tokens[$i]['bracket_closer'] + 1);
519
                }
520
            }
521
522
            switch ($tokens[$i]['type']) {
523
                case 'T_BITWISE_AND':
524
                    if ($defaultStart === null) {
525
                        $passByReference = true;
526
                    }
527
                    break;
528
                case 'T_VARIABLE':
529
                    $currVar = $i;
530
                    break;
531
                case 'T_ELLIPSIS':
532
                    $variableLength = true;
533
                    break;
534
                case 'T_ARRAY_HINT': // Pre-PHPCS 3.3.0.
535
                case 'T_CALLABLE':
536
                    if ($typeHintToken === false) {
537
                        $typeHintToken = $i;
538
                    }
539
540
                    $typeHint .= $tokens[$i]['content'];
541
                    break;
542
                case 'T_SELF':
543
                case 'T_PARENT':
544 View Code Duplication
                case 'T_STATIC':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
545
                    // Self and parent are valid, static invalid, but was probably intended as type hint.
546
                    if (isset($defaultStart) === false) {
547
                        if ($typeHintToken === false) {
548
                            $typeHintToken = $i;
549
                        }
550
551
                        $typeHint .= $tokens[$i]['content'];
552
                    }
553
                    break;
554
                case 'T_STRING':
555
                    // This is a string, so it may be a type hint, but it could
556
                    // also be a constant used as a default value.
557
                    $prevComma = false;
558 View Code Duplication
                    for ($t = $i; $t >= $opener; $t--) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
559
                        if ($tokens[$t]['code'] === T_COMMA) {
560
                            $prevComma = $t;
561
                            break;
562
                        }
563
                    }
564
565
                    if ($prevComma !== false) {
566
                        $nextEquals = false;
567 View Code Duplication
                        for ($t = $prevComma; $t < $i; $t++) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
568
                            if ($tokens[$t]['code'] === T_EQUAL) {
569
                                $nextEquals = $t;
570
                                break;
571
                            }
572
                        }
573
574
                        if ($nextEquals !== false) {
575
                            break;
576
                        }
577
                    }
578
579
                    if ($defaultStart === null) {
580
                        if ($typeHintToken === false) {
581
                            $typeHintToken = $i;
582
                        }
583
584
                        $typeHint .= $tokens[$i]['content'];
585
                    }
586
                    break;
587 View Code Duplication
                case 'T_NS_SEPARATOR':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
588
                    // Part of a type hint or default value.
589
                    if ($defaultStart === null) {
590
                        if ($typeHintToken === false) {
591
                            $typeHintToken = $i;
592
                        }
593
594
                        $typeHint .= $tokens[$i]['content'];
595
                    }
596
                    break;
597
                case 'T_NULLABLE':
598
                case 'T_INLINE_THEN': // Pre-PHPCS 2.8.0.
599
                    if ($defaultStart === null) {
600
                        $nullableType = true;
601
                        $typeHint    .= $tokens[$i]['content'];
602
                    }
603
                    break;
604
                case 'T_CLOSE_PARENTHESIS':
605
                case 'T_COMMA':
606
                    // If it's null, then there must be no parameters for this
607
                    // method.
608
                    if ($currVar === null) {
609
                        break;
610
                    }
611
612
                    $vars[$paramCount]            = array();
613
                    $vars[$paramCount]['token']   = $currVar;
614
                    $vars[$paramCount]['name']    = $tokens[$currVar]['content'];
615
                    $vars[$paramCount]['content'] = trim($phpcsFile->getTokensAsString($paramStart, ($i - $paramStart)));
616
617
                    if ($defaultStart !== null) {
618
                        $vars[$paramCount]['default'] = trim(
619
                            $phpcsFile->getTokensAsString(
620
                                $defaultStart,
621
                                ($i - $defaultStart)
622
                            )
623
                        );
624
                    }
625
626
                    $vars[$paramCount]['pass_by_reference'] = $passByReference;
627
                    $vars[$paramCount]['variable_length']   = $variableLength;
628
                    $vars[$paramCount]['type_hint']         = $typeHint;
629
                    $vars[$paramCount]['type_hint_token']   = $typeHintToken;
630
                    $vars[$paramCount]['nullable_type']     = $nullableType;
631
632
                    // Reset the vars, as we are about to process the next parameter.
633
                    $defaultStart    = null;
634
                    $paramStart      = ($i + 1);
635
                    $passByReference = false;
636
                    $variableLength  = false;
637
                    $typeHint        = '';
638
                    $typeHintToken   = false;
639
                    $nullableType    = false;
640
641
                    $paramCount++;
642
                    break;
643
                case 'T_EQUAL':
644
                    $defaultStart = ($i + 1);
645
                    break;
646
            }//end switch
647
        }//end for
648
649
        return $vars;
650
    }
651
}
652