GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — develop ( 699b70...879176 )
by Chris
13:23
created

PHP_CodeSniffer_Tokenizers_JS::getRegexToken()   F

Complexity

Conditions 20
Paths 1803

Size

Total Lines 127
Code Lines 74

Duplication

Lines 5
Ratio 3.94 %

Importance

Changes 0
Metric Value
cc 20
eloc 74
nc 1803
nop 5
dl 5
loc 127
rs 2
c 0
b 0
f 0

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
 * Tokenizes JS code.
4
 *
5
 * PHP version 5
6
 *
7
 * @category  PHP
8
 * @package   PHP_CodeSniffer
9
 * @author    Greg Sherwood <[email protected]>
10
 * @author    Marc McIntyre <[email protected]>
11
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
12
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
13
 * @link      http://pear.php.net/package/PHP_CodeSniffer
14
 */
15
16
/**
17
 * Tokenizes JS code.
18
 *
19
 * @category  PHP
20
 * @package   PHP_CodeSniffer
21
 * @author    Greg Sherwood <[email protected]>
22
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
23
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
24
 * @version   Release: @package_version@
25
 * @link      http://pear.php.net/package/PHP_CodeSniffer
26
 */
27
class PHP_CodeSniffer_Tokenizers_JS
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
28
{
29
30
    /**
31
     * If TRUE, files that appear to be minified will not be processed.
32
     *
33
     * @var boolean
34
     */
35
    public $skipMinified = true;
36
37
    /**
38
     * A list of tokens that are allowed to open a scope.
39
     *
40
     * This array also contains information about what kind of token the scope
41
     * opener uses to open and close the scope, if the token strictly requires
42
     * an opener, if the token can share a scope closer, and who it can be shared
43
     * with. An example of a token that shares a scope closer is a CASE scope.
44
     *
45
     * @var array
46
     */
47
    public $scopeOpeners = array(
48
                            T_IF       => array(
49
                                           'start'  => array(T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET),
50
                                           'end'    => array(T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET),
51
                                           'strict' => false,
52
                                           'shared' => false,
53
                                           'with'   => array(),
54
                                          ),
55
                            T_TRY      => array(
56
                                           'start'  => array(T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET),
57
                                           'end'    => array(T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET),
58
                                           'strict' => true,
59
                                           'shared' => false,
60
                                           'with'   => array(),
61
                                          ),
62
                            T_CATCH    => array(
63
                                           'start'  => array(T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET),
64
                                           'end'    => array(T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET),
65
                                           'strict' => true,
66
                                           'shared' => false,
67
                                           'with'   => array(),
68
                                          ),
69
                            T_ELSE     => array(
70
                                           'start'  => array(T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET),
71
                                           'end'    => array(T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET),
72
                                           'strict' => false,
73
                                           'shared' => false,
74
                                           'with'   => array(),
75
                                          ),
76
                            T_FOR      => array(
77
                                           'start'  => array(T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET),
78
                                           'end'    => array(T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET),
79
                                           'strict' => false,
80
                                           'shared' => false,
81
                                           'with'   => array(),
82
                                          ),
83
                            T_FUNCTION => array(
84
                                           'start'  => array(T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET),
85
                                           'end'    => array(T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET),
86
                                           'strict' => false,
87
                                           'shared' => false,
88
                                           'with'   => array(),
89
                                          ),
90
                            T_WHILE    => array(
91
                                           'start'  => array(T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET),
92
                                           'end'    => array(T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET),
93
                                           'strict' => false,
94
                                           'shared' => false,
95
                                           'with'   => array(),
96
                                          ),
97
                            T_DO       => array(
98
                                           'start'  => array(T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET),
99
                                           'end'    => array(T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET),
100
                                           'strict' => true,
101
                                           'shared' => false,
102
                                           'with'   => array(),
103
                                          ),
104
                            T_SWITCH   => array(
105
                                           'start'  => array(T_OPEN_CURLY_BRACKET => T_OPEN_CURLY_BRACKET),
106
                                           'end'    => array(T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET),
107
                                           'strict' => true,
108
                                           'shared' => false,
109
                                           'with'   => array(),
110
                                          ),
111
                            T_CASE     => array(
112
                                           'start'  => array(T_COLON => T_COLON),
113
                                           'end'    => array(
114
                                                        T_BREAK    => T_BREAK,
115
                                                        T_RETURN   => T_RETURN,
116
                                                        T_CONTINUE => T_CONTINUE,
117
                                                        T_THROW    => T_THROW,
118
                                                       ),
119
                                           'strict' => true,
120
                                           'shared' => true,
121
                                           'with'   => array(
122
                                                        T_DEFAULT => T_DEFAULT,
123
                                                        T_CASE    => T_CASE,
124
                                                        T_SWITCH  => T_SWITCH,
125
                                                       ),
126
                                          ),
127
                            T_DEFAULT  => array(
128
                                           'start'  => array(T_COLON => T_COLON),
129
                                           'end'    => array(
130
                                                        T_BREAK    => T_BREAK,
131
                                                        T_RETURN   => T_RETURN,
132
                                                        T_CONTINUE => T_CONTINUE,
133
                                                        T_THROW    => T_THROW,
134
                                                       ),
135
                                           'strict' => true,
136
                                           'shared' => true,
137
                                           'with'   => array(
138
                                                        T_CASE   => T_CASE,
139
                                                        T_SWITCH => T_SWITCH,
140
                                                       ),
141
                                          ),
142
                           );
143
144
    /**
145
     * A list of tokens that end the scope.
146
     *
147
     * This array is just a unique collection of the end tokens
148
     * from the _scopeOpeners array. The data is duplicated here to
149
     * save time during parsing of the file.
150
     *
151
     * @var array
152
     */
153
    public $endScopeTokens = array(
154
                              T_CLOSE_CURLY_BRACKET => T_CLOSE_CURLY_BRACKET,
155
                              T_BREAK               => T_BREAK,
156
                             );
157
158
    /**
159
     * A list of special JS tokens and their types.
160
     *
161
     * @var array
162
     */
163
    protected $tokenValues = array(
164
                              'function'  => 'T_FUNCTION',
165
                              'prototype' => 'T_PROTOTYPE',
166
                              'try'       => 'T_TRY',
167
                              'catch'     => 'T_CATCH',
168
                              'return'    => 'T_RETURN',
169
                              'throw'     => 'T_THROW',
170
                              'break'     => 'T_BREAK',
171
                              'switch'    => 'T_SWITCH',
172
                              'continue'  => 'T_CONTINUE',
173
                              'if'        => 'T_IF',
174
                              'else'      => 'T_ELSE',
175
                              'do'        => 'T_DO',
176
                              'while'     => 'T_WHILE',
177
                              'for'       => 'T_FOR',
178
                              'var'       => 'T_VAR',
179
                              'case'      => 'T_CASE',
180
                              'default'   => 'T_DEFAULT',
181
                              'true'      => 'T_TRUE',
182
                              'false'     => 'T_FALSE',
183
                              'null'      => 'T_NULL',
184
                              'this'      => 'T_THIS',
185
                              'typeof'    => 'T_TYPEOF',
186
                              '('         => 'T_OPEN_PARENTHESIS',
187
                              ')'         => 'T_CLOSE_PARENTHESIS',
188
                              '{'         => 'T_OPEN_CURLY_BRACKET',
189
                              '}'         => 'T_CLOSE_CURLY_BRACKET',
190
                              '['         => 'T_OPEN_SQUARE_BRACKET',
191
                              ']'         => 'T_CLOSE_SQUARE_BRACKET',
192
                              '?'         => 'T_INLINE_THEN',
193
                              '.'         => 'T_OBJECT_OPERATOR',
194
                              '+'         => 'T_PLUS',
195
                              '-'         => 'T_MINUS',
196
                              '*'         => 'T_MULTIPLY',
197
                              '%'         => 'T_MODULUS',
198
                              '/'         => 'T_DIVIDE',
199
                              '^'         => 'T_LOGICAL_XOR',
200
                              ','         => 'T_COMMA',
201
                              ';'         => 'T_SEMICOLON',
202
                              ':'         => 'T_COLON',
203
                              '<'         => 'T_LESS_THAN',
204
                              '>'         => 'T_GREATER_THAN',
205
                              '<='        => 'T_IS_SMALLER_OR_EQUAL',
206
                              '>='        => 'T_IS_GREATER_OR_EQUAL',
207
                              '!'         => 'T_BOOLEAN_NOT',
208
                              '||'        => 'T_BOOLEAN_OR',
209
                              '&&'        => 'T_BOOLEAN_AND',
210
                              '|'         => 'T_BITWISE_OR',
211
                              '&'         => 'T_BITWISE_AND',
212
                              '!='        => 'T_IS_NOT_EQUAL',
213
                              '!=='       => 'T_IS_NOT_IDENTICAL',
214
                              '='         => 'T_EQUAL',
215
                              '=='        => 'T_IS_EQUAL',
216
                              '==='       => 'T_IS_IDENTICAL',
217
                              '-='        => 'T_MINUS_EQUAL',
218
                              '+='        => 'T_PLUS_EQUAL',
219
                              '*='        => 'T_MUL_EQUAL',
220
                              '/='        => 'T_DIV_EQUAL',
221
                              '%='        => 'T_MOD_EQUAL',
222
                              '++'        => 'T_INC',
223
                              '--'        => 'T_DEC',
224
                              '//'        => 'T_COMMENT',
225
                              '/*'        => 'T_COMMENT',
226
                              '/**'       => 'T_DOC_COMMENT',
227
                              '*/'        => 'T_COMMENT',
228
                             );
229
230
    /**
231
     * A list string delimiters.
232
     *
233
     * @var array
234
     */
235
    protected $stringTokens = array(
236
                               '\'' => '\'',
237
                               '"'  => '"',
238
                              );
239
240
    /**
241
     * A list tokens that start and end comments.
242
     *
243
     * @var array
244
     */
245
    protected $commentTokens = array(
246
                                '//'  => null,
247
                                '/*'  => '*/',
248
                                '/**' => '*/',
249
                               );
250
251
252
    /**
253
     * Creates an array of tokens when given some JS code.
254
     *
255
     * @param string $string  The string to tokenize.
256
     * @param string $eolChar The EOL character to use for splitting strings.
257
     *
258
     * @return array
259
     */
260
    public function tokenizeString($string, $eolChar='\n')
261
    {
262
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
263
            echo "\t*** START JS TOKENIZING ***".PHP_EOL;
264
        }
265
266
        $maxTokenLength = 0;
267
        foreach ($this->tokenValues as $token => $values) {
268
            if (strlen($token) > $maxTokenLength) {
269
                $maxTokenLength = strlen($token);
270
            }
271
        }
272
273
        $tokens          = array();
274
        $inString        = '';
275
        $stringChar      = null;
276
        $inComment       = '';
277
        $buffer          = '';
278
        $preStringBuffer = '';
279
        $cleanBuffer     = false;
280
281
        $commentTokenizer = new PHP_CodeSniffer_Tokenizers_Comment();
282
283
        $tokens[] = array(
284
                     'code'    => T_OPEN_TAG,
285
                     'type'    => 'T_OPEN_TAG',
286
                     'content' => '',
287
                    );
288
289
        // Convert newlines to single characters for ease of
290
        // processing. We will change them back later.
291
        $string = str_replace($eolChar, "\n", $string);
292
293
        $chars    = str_split($string);
294
        $numChars = count($chars);
295
        for ($i = 0; $i < $numChars; $i++) {
296
            $char = $chars[$i];
297
298
            if (PHP_CODESNIFFER_VERBOSITY > 1) {
299
                $content       = PHP_CodeSniffer::prepareForOutput($char);
300
                $bufferContent = PHP_CodeSniffer::prepareForOutput($buffer);
301
302
                if ($inString !== '') {
303
                    echo "\t";
304
                }
305
306
                if ($inComment !== '') {
307
                    echo "\t";
308
                }
309
310
                echo "\tProcess char $i => $content (buffer: $bufferContent)".PHP_EOL;
311
            }//end if
312
313
            if ($inString === '' && $inComment === '' && $buffer !== '') {
314
                // If the buffer only has whitespace and we are about to
315
                // add a character, store the whitespace first.
316 View Code Duplication
                if (trim($char) !== '' && trim($buffer) === '') {
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...
317
                    $tokens[] = array(
318
                                 'code'    => T_WHITESPACE,
319
                                 'type'    => 'T_WHITESPACE',
320
                                 'content' => str_replace("\n", $eolChar, $buffer),
321
                                );
322
323
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
324
                        $content = PHP_CodeSniffer::prepareForOutput($buffer);
325
                        echo "\t=> Added token T_WHITESPACE ($content)".PHP_EOL;
326
                    }
327
328
                    $buffer = '';
329
                }
330
331
                // If the buffer is not whitespace and we are about to
332
                // add a whitespace character, store the content first.
333
                if ($inString === ''
334
                    && $inComment === ''
335
                    && trim($char) === ''
336
                    && trim($buffer) !== ''
337
                ) {
338
                    $tokens[] = array(
339
                                 'code'    => T_STRING,
340
                                 'type'    => 'T_STRING',
341
                                 'content' => str_replace("\n", $eolChar, $buffer),
342
                                );
343
344
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
345
                        $content = PHP_CodeSniffer::prepareForOutput($buffer);
346
                        echo "\t=> Added token T_STRING ($content)".PHP_EOL;
347
                    }
348
349
                    $buffer = '';
350
                }
351
            }//end if
352
353
            // Process strings.
354
            if ($inComment === '' && isset($this->stringTokens[$char]) === true) {
355
                if ($inString === $char) {
356
                    // This could be the end of the string, but make sure it
357
                    // is not escaped first.
358
                    $escapes = 0;
359
                    for ($x = ($i - 1); $x >= 0; $x--) {
360
                        if ($chars[$x] !== '\\') {
361
                            break;
362
                        }
363
364
                        $escapes++;
365
                    }
366
367
                    if ($escapes === 0 || ($escapes % 2) === 0) {
368
                        // There is an even number escape chars,
369
                        // so this is not escaped, it is the end of the string.
370
                        $tokens[] = array(
371
                                     'code'    => T_CONSTANT_ENCAPSED_STRING,
372
                                     'type'    => 'T_CONSTANT_ENCAPSED_STRING',
373
                                     'content' => str_replace("\n", $eolChar, $buffer).$char,
374
                                    );
375
376
                        if (PHP_CODESNIFFER_VERBOSITY > 1) {
377
                            echo "\t\t* found end of string *".PHP_EOL;
378
                            $content = PHP_CodeSniffer::prepareForOutput($buffer.$char);
379
                            echo "\t=> Added token T_CONSTANT_ENCAPSED_STRING ($content)".PHP_EOL;
380
                        }
381
382
                        $buffer          = '';
383
                        $preStringBuffer = '';
384
                        $inString        = '';
385
                        $stringChar      = null;
386
                        continue;
387
                    }//end if
388
                } else if ($inString === '') {
389
                    $inString        = $char;
390
                    $stringChar      = $i;
391
                    $preStringBuffer = $buffer;
392
393
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
394
                        echo "\t\t* looking for string closer *".PHP_EOL;
395
                    }
396
                }//end if
397
            }//end if
398
399
            if ($inString !== '' && $char === "\n") {
400
                // Unless this newline character is escaped, the string did not
401
                // end before the end of the line, which means it probably
402
                // wasn't a string at all (maybe a regex).
403
                if ($chars[($i - 1)] !== '\\') {
404
                    $i      = $stringChar;
405
                    $buffer = $preStringBuffer;
406
                    $preStringBuffer = '';
407
                    $inString        = '';
408
                    $stringChar      = null;
409
                    $char            = $chars[$i];
410
411
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
412
                        echo "\t\t* found newline before end of string, bailing *".PHP_EOL;
413
                    }
414
                }
415
            }
416
417
            $buffer .= $char;
418
419
            // We don't look for special tokens inside strings,
420
            // so if we are in a string, we can continue here now
421
            // that the current char is in the buffer.
422
            if ($inString !== '') {
423
                continue;
424
            }
425
426
            // Special case for T_DIVIDE which can actually be
427
            // the start of a regular expression.
428
            if ($buffer === $char && $char === '/' && $chars[($i + 1)] !== '*') {
429
                $regex = $this->getRegexToken(
430
                    $i,
431
                    $string,
432
                    $chars,
0 ignored issues
show
Documentation introduced by
$chars is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
433
                    $tokens,
0 ignored issues
show
Documentation introduced by
$tokens is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
434
                    $eolChar
435
                );
436
437
                if ($regex !== null) {
438
                    $tokens[] = array(
439
                                 'code'    => T_REGULAR_EXPRESSION,
440
                                 'type'    => 'T_REGULAR_EXPRESSION',
441
                                 'content' => $regex['content'],
442
                                );
443
444
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
445
                        $content = PHP_CodeSniffer::prepareForOutput($regex['content']);
446
                        echo "\t=> Added token T_REGULAR_EXPRESSION ($content)".PHP_EOL;
447
                    }
448
449
                    $i           = $regex['end'];
450
                    $buffer      = '';
451
                    $cleanBuffer = false;
452
                    continue;
453
                }//end if
454
            }//end if
455
456
            // Check for known tokens, but ignore tokens found that are not at
457
            // the end of a string, like FOR and this.FORmat.
458
            if (isset($this->tokenValues[strtolower($buffer)]) === true
459
                && (preg_match('|[a-zA-z0-9_]|', $char) === 0
460
                || isset($chars[($i + 1)]) === false
461
                || preg_match('|[a-zA-z0-9_]|', $chars[($i + 1)]) === 0)
462
            ) {
463
                $matchedToken    = false;
464
                $lookAheadLength = ($maxTokenLength - strlen($buffer));
465
466
                if ($lookAheadLength > 0) {
467
                    // The buffer contains a token type, but we need
468
                    // to look ahead at the next chars to see if this is
469
                    // actually part of a larger token. For example,
470
                    // FOR and FOREACH.
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
471
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
472
                        echo "\t\t* buffer possibly contains token, looking ahead $lookAheadLength chars *".PHP_EOL;
473
                    }
474
475
                    $charBuffer = $buffer;
476
                    for ($x = 1; $x <= $lookAheadLength; $x++) {
477
                        if (isset($chars[($i + $x)]) === false) {
478
                            break;
479
                        }
480
481
                        $charBuffer .= $chars[($i + $x)];
482
483
                        if (PHP_CODESNIFFER_VERBOSITY > 1) {
484
                            $content = PHP_CodeSniffer::prepareForOutput($charBuffer);
485
                            echo "\t\t=> Looking ahead $x chars => $content".PHP_EOL;
486
                        }
487
488
                        if (isset($this->tokenValues[strtolower($charBuffer)]) === true) {
489
                            // We've found something larger that matches
490
                            // so we can ignore this char. Except for 1 very specific
491
                            // case where a comment like /**/ needs to tokenize as
492
                            // T_COMMENT and not T_DOC_COMMENT.
493
                            $oldType = $this->tokenValues[strtolower($buffer)];
494
                            $newType = $this->tokenValues[strtolower($charBuffer)];
495
                            if ($oldType === 'T_COMMENT'
496
                                && $newType === 'T_DOC_COMMENT'
497
                                && $chars[($i + $x + 1)] === '/'
498
                            ) {
499
                                if (PHP_CODESNIFFER_VERBOSITY > 1) {
500
                                    echo "\t\t* look ahead ignored T_DOC_COMMENT, continuing *".PHP_EOL;
501
                                }
502
                            } else {
503
                                if (PHP_CODESNIFFER_VERBOSITY > 1) {
504
                                    echo "\t\t* look ahead found more specific token ($newType), ignoring $i *".PHP_EOL;
505
                                }
506
507
                                $matchedToken = true;
508
                                break;
509
                            }
510
                        }//end if
511
                    }//end for
512
                }//end if
513
514
                if ($matchedToken === false) {
515
                    if (PHP_CODESNIFFER_VERBOSITY > 1 && $lookAheadLength > 0) {
516
                        echo "\t\t* look ahead found nothing *".PHP_EOL;
517
                    }
518
519
                    $value = $this->tokenValues[strtolower($buffer)];
520
521
                    if ($value === 'T_FUNCTION' && $buffer !== 'function') {
522
                        // The function keyword needs to be all lowercase or else
523
                        // it is just a function called "Function".
524
                        $value = 'T_STRING';
525
                    }
526
527
                    $tokens[] = array(
528
                                 'code'    => constant($value),
529
                                 'type'    => $value,
530
                                 'content' => $buffer,
531
                                );
532
533
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
534
                        $content = PHP_CodeSniffer::prepareForOutput($buffer);
535
                        echo "\t=> Added token $value ($content)".PHP_EOL;
536
                    }
537
538
                    $cleanBuffer = true;
539
                }//end if
540
            } else if (isset($this->tokenValues[strtolower($char)]) === true) {
541
                // No matter what token we end up using, we don't
542
                // need the content in the buffer any more because we have
543
                // found a valid token.
544
                $newContent = substr(str_replace("\n", $eolChar, $buffer), 0, -1);
545
                if ($newContent !== '') {
546
                    $tokens[] = array(
547
                                 'code'    => T_STRING,
548
                                 'type'    => 'T_STRING',
549
                                 'content' => $newContent,
550
                                );
551
552
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
553
                        $content = PHP_CodeSniffer::prepareForOutput(substr($buffer, 0, -1));
554
                        echo "\t=> Added token T_STRING ($content)".PHP_EOL;
555
                    }
556
                }
557
558
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
559
                    echo "\t\t* char is token, looking ahead ".($maxTokenLength - 1).' chars *'.PHP_EOL;
560
                }
561
562
                // The char is a token type, but we need to look ahead at the
563
                // next chars to see if this is actually part of a larger token.
564
                // For example, = and ===.
565
                $charBuffer   = $char;
566
                $matchedToken = false;
567
                for ($x = 1; $x <= $maxTokenLength; $x++) {
568
                    if (isset($chars[($i + $x)]) === false) {
569
                        break;
570
                    }
571
572
                    $charBuffer .= $chars[($i + $x)];
573
574
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
575
                        $content = PHP_CodeSniffer::prepareForOutput($charBuffer);
576
                        echo "\t\t=> Looking ahead $x chars => $content".PHP_EOL;
577
                    }
578
579
                    if (isset($this->tokenValues[strtolower($charBuffer)]) === true) {
580
                        // We've found something larger that matches
581
                        // so we can ignore this char.
582
                        if (PHP_CODESNIFFER_VERBOSITY > 1) {
583
                            $type = $this->tokenValues[strtolower($charBuffer)];
584
                            echo "\t\t* look ahead found more specific token ($type), ignoring $i *".PHP_EOL;
585
                        }
586
587
                        $matchedToken = true;
588
                        break;
589
                    }
590
                }//end for
591
592
                if ($matchedToken === false) {
593
                    $value    = $this->tokenValues[strtolower($char)];
594
                    $tokens[] = array(
595
                                 'code'    => constant($value),
596
                                 'type'    => $value,
597
                                 'content' => $char,
598
                                );
599
600
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
601
                        echo "\t\t* look ahead found nothing *".PHP_EOL;
602
                        $content = PHP_CodeSniffer::prepareForOutput($char);
603
                        echo "\t=> Added token $value ($content)".PHP_EOL;
604
                    }
605
606
                    $cleanBuffer = true;
607
                } else {
608
                    $buffer = $char;
609
                }//end if
610
            }//end if
611
612
            // Keep track of content inside comments.
613
            if ($inComment === ''
614
                && array_key_exists($buffer, $this->commentTokens) === true
615
            ) {
616
                // This is not really a comment if the content
617
                // looks like \// (i.e., it is escaped).
618
                if (isset($chars[($i - 2)]) === true && $chars[($i - 2)] === '\\') {
619
                    $lastToken   = array_pop($tokens);
620
                    $lastContent = $lastToken['content'];
621 View Code Duplication
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
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...
622
                        $value   = $this->tokenValues[strtolower($lastContent)];
623
                        $content = PHP_CodeSniffer::prepareForOutput($lastContent);
624
                        echo "\t=> Removed token $value ($content)".PHP_EOL;
625
                    }
626
627
                    $lastChars    = str_split($lastContent);
628
                    $lastNumChars = count($lastChars);
629
                    for ($x = 0; $x < $lastNumChars; $x++) {
630
                        $lastChar = $lastChars[$x];
631
                        $value    = $this->tokenValues[strtolower($lastChar)];
632
                        $tokens[] = array(
633
                                     'code'    => constant($value),
634
                                     'type'    => $value,
635
                                     'content' => $lastChar,
636
                                    );
637
638
                        if (PHP_CODESNIFFER_VERBOSITY > 1) {
639
                            $content = PHP_CodeSniffer::prepareForOutput($lastChar);
640
                            echo "\t=> Added token $value ($content)".PHP_EOL;
641
                        }
642
                    }
643
                } else {
644
                    // We have started a comment.
645
                    $inComment = $buffer;
646
647
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
648
                        echo "\t\t* looking for end of comment *".PHP_EOL;
649
                    }
650
                }//end if
651
            } else if ($inComment !== '') {
652
                if ($this->commentTokens[$inComment] === null) {
653
                    // Comment ends at the next newline.
654
                    if (strpos($buffer, "\n") !== false) {
655
                        $inComment = '';
656
                    }
657
                } else {
658
                    if ($this->commentTokens[$inComment] === $buffer) {
659
                        $inComment = '';
660
                    }
661
                }
662
663
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
664
                    if ($inComment === '') {
665
                        echo "\t\t* found end of comment *".PHP_EOL;
666
                    }
667
                }
668
669 View Code Duplication
                if ($inComment === '' && $cleanBuffer === 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...
670
                    $tokens[] = array(
671
                                 'code'    => T_STRING,
672
                                 'type'    => 'T_STRING',
673
                                 'content' => str_replace("\n", $eolChar, $buffer),
674
                                );
675
676
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
677
                        $content = PHP_CodeSniffer::prepareForOutput($buffer);
678
                        echo "\t=> Added token T_STRING ($content)".PHP_EOL;
679
                    }
680
681
                    $buffer = '';
682
                }
683
            }//end if
684
685
            if ($cleanBuffer === true) {
686
                $buffer      = '';
687
                $cleanBuffer = false;
688
            }
689
        }//end for
690
691
        if (empty($buffer) === false) {
692
            // Buffer contains whitespace from the end of the file.
693
            $tokens[] = array(
694
                         'code'    => T_WHITESPACE,
695
                         'type'    => 'T_WHITESPACE',
696
                         'content' => str_replace("\n", $eolChar, $buffer),
697
                        );
698
699
            if (PHP_CODESNIFFER_VERBOSITY > 1) {
700
                $content = PHP_CodeSniffer::prepareForOutput($buffer);
701
                echo "\t=> Added token T_WHITESPACE ($content)".PHP_EOL;
702
            }
703
        }
704
705
        $tokens[] = array(
706
                     'code'    => T_CLOSE_TAG,
707
                     'type'    => 'T_CLOSE_TAG',
708
                     'content' => '',
709
                    );
710
711
        /*
712
            Now that we have done some basic tokenizing, we need to
713
            modify the tokens to join some together and split some apart
714
            so they match what the PHP tokenizer does.
715
        */
716
717
        $finalTokens = array();
718
        $newStackPtr = 0;
719
        $numTokens   = count($tokens);
720
        for ($stackPtr = 0; $stackPtr < $numTokens; $stackPtr++) {
721
            $token = $tokens[$stackPtr];
722
723
            /*
724
                Look for comments and join the tokens together.
725
            */
726
727
            if ($token['code'] === T_COMMENT || $token['code'] === T_DOC_COMMENT) {
728
                $newContent   = '';
729
                $tokenContent = $token['content'];
730
                $endContent   = $this->commentTokens[$tokenContent];
731
                while ($tokenContent !== $endContent) {
732
                    if ($endContent === null
733
                        && strpos($tokenContent, $eolChar) !== false
734
                    ) {
735
                        // A null end token means the comment ends at the end of
736
                        // the line so we look for newlines and split the token.
737
                        $tokens[$stackPtr]['content'] = substr(
738
                            $tokenContent,
739
                            (strpos($tokenContent, $eolChar) + strlen($eolChar))
740
                        );
741
742
                        $tokenContent = substr(
743
                            $tokenContent,
744
                            0,
745
                            (strpos($tokenContent, $eolChar) + strlen($eolChar))
746
                        );
747
748
                        // If the substr failed, skip the token as the content
749
                        // will now be blank.
750
                        if ($tokens[$stackPtr]['content'] !== false
751
                            && $tokens[$stackPtr]['content'] !== ''
752
                        ) {
753
                            $stackPtr--;
754
                        }
755
756
                        break;
757
                    }//end if
758
759
                    $stackPtr++;
760
                    $newContent .= $tokenContent;
761
                    if (isset($tokens[$stackPtr]) === false) {
762
                        break;
763
                    }
764
765
                    $tokenContent = $tokens[$stackPtr]['content'];
766
                }//end while
767
768
                if ($token['code'] === T_DOC_COMMENT) {
769
                    $commentTokens = $commentTokenizer->tokenizeString($newContent.$tokenContent, $eolChar, $newStackPtr);
770
                    foreach ($commentTokens as $commentToken) {
771
                        $finalTokens[$newStackPtr] = $commentToken;
772
                        $newStackPtr++;
773
                    }
774
775
                    continue;
776
                } else {
777
                    // Save the new content in the current token so
778
                    // the code below can chop it up on newlines.
779
                    $token['content'] = $newContent.$tokenContent;
780
                }
781
            }//end if
782
783
            /*
784
                If this token has newlines in its content, split each line up
785
                and create a new token for each line. We do this so it's easier
786
                to ascertain where errors occur on a line.
787
                Note that $token[1] is the token's content.
788
            */
789
790
            if (strpos($token['content'], $eolChar) !== false) {
791
                $tokenLines = explode($eolChar, $token['content']);
792
                $numLines   = count($tokenLines);
793
794
                for ($i = 0; $i < $numLines; $i++) {
795
                    $newToken['content'] = $tokenLines[$i];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$newToken was never initialized. Although not strictly required by PHP, it is generally a good practice to add $newToken = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
796 View Code Duplication
                    if ($i === ($numLines - 1)) {
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...
797
                        if ($tokenLines[$i] === '') {
798
                            break;
799
                        }
800
                    } else {
801
                        $newToken['content'] .= $eolChar;
0 ignored issues
show
Bug introduced by
The variable $newToken does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
802
                    }
803
804
                    $newToken['type']          = $token['type'];
805
                    $newToken['code']          = $token['code'];
806
                    $finalTokens[$newStackPtr] = $newToken;
807
                    $newStackPtr++;
808
                }
809
            } else {
810
                $finalTokens[$newStackPtr] = $token;
811
                $newStackPtr++;
812
            }//end if
813
814
            // Convert numbers, including decimals.
815
            if ($token['code'] === T_STRING
816
                || $token['code'] === T_OBJECT_OPERATOR
817
            ) {
818
                $newContent  = '';
819
                $oldStackPtr = $stackPtr;
820
                while (preg_match('|^[0-9\.]+$|', $tokens[$stackPtr]['content']) !== 0) {
821
                    $newContent .= $tokens[$stackPtr]['content'];
822
                    $stackPtr++;
823
                }
824
825
                if ($newContent !== '' && $newContent !== '.') {
826
                    $finalTokens[($newStackPtr - 1)]['content'] = $newContent;
827
                    if (ctype_digit($newContent) === true) {
828
                        $finalTokens[($newStackPtr - 1)]['code'] = constant('T_LNUMBER');
829
                        $finalTokens[($newStackPtr - 1)]['type'] = 'T_LNUMBER';
830
                    } else {
831
                        $finalTokens[($newStackPtr - 1)]['code'] = constant('T_DNUMBER');
832
                        $finalTokens[($newStackPtr - 1)]['type'] = 'T_DNUMBER';
833
                    }
834
835
                    $stackPtr--;
836
                    continue;
837
                } else {
838
                    $stackPtr = $oldStackPtr;
839
                }
840
            }//end if
841
842
            // Convert the token after an object operator into a string, in most cases.
843
            if ($token['code'] === T_OBJECT_OPERATOR) {
844
                for ($i = ($stackPtr + 1); $i < $numTokens; $i++) {
845
                    if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$tokens[$i]['code']]) === true) {
846
                        continue;
847
                    }
848
849
                    if ($tokens[$i]['code'] !== T_PROTOTYPE
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison !== seems to always evaluate to true as the types of $tokens[$i]['code'] (integer) and T_PROTOTYPE (string) can never be identical. Maybe you want to use a loose comparison != instead?
Loading history...
850
                        && $tokens[$i]['code'] !== T_LNUMBER
851
                        && $tokens[$i]['code'] !== T_DNUMBER
852
                    ) {
853
                        $tokens[$i]['code'] = T_STRING;
854
                        $tokens[$i]['type'] = 'T_STRING';
855
                    }
856
857
                    break;
858
                }
859
            }
860
        }//end for
861
862
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
863
            echo "\t*** END TOKENIZING ***".PHP_EOL;
864
        }
865
866
        return $finalTokens;
867
868
    }//end tokenizeString()
869
870
871
    /**
872
     * Tokenizes a regular expression if one is found.
873
     *
874
     * If a regular expression is not found, NULL is returned.
875
     *
876
     * @param string $char    The index of the possible regex start character.
877
     * @param string $string  The complete content of the string being tokenized.
878
     * @param string $chars   An array of characters being tokenized.
879
     * @param string $tokens  The current array of tokens found in the string.
880
     * @param string $eolChar The EOL character to use for splitting strings.
881
     *
882
     * @return void
883
     */
884
    public function getRegexToken($char, $string, $chars, $tokens, $eolChar)
885
    {
886
        $beforeTokens = array(
887
                         T_EQUAL               => true,
888
                         T_IS_NOT_EQUAL        => true,
889
                         T_IS_IDENTICAL        => true,
890
                         T_IS_NOT_IDENTICAL    => true,
891
                         T_OPEN_PARENTHESIS    => true,
892
                         T_OPEN_SQUARE_BRACKET => true,
893
                         T_RETURN              => true,
894
                         T_BOOLEAN_OR          => true,
895
                         T_BOOLEAN_AND         => true,
896
                         T_BITWISE_OR          => true,
897
                         T_BITWISE_AND         => true,
898
                         T_COMMA               => true,
899
                         T_COLON               => true,
900
                         T_TYPEOF              => true,
901
                         T_INLINE_THEN         => true,
902
                         T_INLINE_ELSE         => true,
903
                        );
904
905
        $afterTokens = array(
906
                        ','      => true,
907
                        ')'      => true,
908
                        ']'      => true,
909
                        ';'      => true,
910
                        ' '      => true,
911
                        '.'      => true,
912
                        ':'      => true,
913
                        $eolChar => true,
914
                       );
915
916
        // Find the last non-whitespace token that was added
917
        // to the tokens array.
918
        $numTokens = count($tokens);
919 View Code Duplication
        for ($prev = ($numTokens - 1); $prev >= 0; $prev--) {
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...
920
            if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$tokens[$prev]['code']]) === false) {
921
                break;
922
            }
923
        }
924
925
        if (isset($beforeTokens[$tokens[$prev]['code']]) === false) {
926
            return null;
927
        }
928
929
        // This is probably a regular expression, so look for the end of it.
930
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
931
            echo "\t* token possibly starts a regular expression *".PHP_EOL;
932
        }
933
934
        $numChars = count($chars);
935
        for ($next = ($char + 1); $next < $numChars; $next++) {
936
            if ($chars[$next] === '/') {
937
                // Just make sure this is not escaped first.
938
                if ($chars[($next - 1)] !== '\\') {
939
                    // In the simple form: /.../ so we found the end.
940
                    break;
941
                } else if ($chars[($next - 2)] === '\\') {
942
                    // In the form: /...\\/ so we found the end.
943
                    break;
944
                }
945
            } else {
946
                $possibleEolChar = substr($string, $next, strlen($eolChar));
947
                if ($possibleEolChar === $eolChar) {
948
                    // This is the last token on the line and regular
949
                    // expressions need to be defined on a single line,
950
                    // so this is not a regular expression.
951
                    break;
952
                }
953
            }
954
        }
955
956
        if ($chars[$next] !== '/') {
957
            if (PHP_CODESNIFFER_VERBOSITY > 1) {
958
                echo "\t* could not find end of regular expression *".PHP_EOL;
959
            }
960
961
            return null;
962
        }
963
964
        while (preg_match('|[a-zA-Z]|', $chars[($next + 1)]) !== 0) {
965
            // The token directly after the end of the regex can
966
            // be modifiers like global and case insensitive
967
            // (.e.g, /pattern/gi).
968
            $next++;
969
        }
970
971
        $regexEnd = $next;
972
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
973
            echo "\t* found end of regular expression at token $regexEnd *".PHP_EOL;
974
        }
975
976
        for ($next = ($next + 1); $next < $numChars; $next++) {
977
            if ($chars[$next] !== ' ') {
978
                break;
979
            } else {
980
                $possibleEolChar = substr($string, $next, strlen($eolChar));
981
                if ($possibleEolChar === $eolChar) {
982
                    // This is the last token on the line.
983
                    break;
984
                }
985
            }
986
        }
987
988
        if (isset($afterTokens[$chars[$next]]) === false) {
989
            if (PHP_CODESNIFFER_VERBOSITY > 1) {
990
                echo "\t* tokens after regular expression do not look correct *".PHP_EOL;
991
            }
992
993
            return null;
994
        }
995
996
        // This is a regular expression, so join all the tokens together.
997
        $content = '';
998
        for ($x = $char; $x <= $regexEnd; $x++) {
999
            $content .= $chars[$x];
1000
        }
1001
1002
        $token = array(
1003
                  'start'   => $char,
1004
                  'end'     => $regexEnd,
1005
                  'content' => $content,
1006
                 );
1007
1008
        return $token;
1009
1010
    }//end getRegexToken()
1011
1012
1013
    /**
1014
     * Performs additional processing after main tokenizing.
1015
     *
1016
     * This additional processing looks for properties, closures, labels and objects.
1017
     *
1018
     * @param array  $tokens  The array of tokens to process.
1019
     * @param string $eolChar The EOL character to use for splitting strings.
1020
     *
1021
     * @return void
1022
     */
1023
    public function processAdditional(&$tokens, $eolChar)
0 ignored issues
show
Unused Code introduced by
The parameter $eolChar is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1024
    {
1025
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
1026
            echo "\t*** START ADDITIONAL JS PROCESSING ***".PHP_EOL;
1027
        }
1028
1029
        $numTokens  = count($tokens);
1030
        $classStack = array();
1031
1032
        for ($i = 0; $i < $numTokens; $i++) {
1033 View Code Duplication
            if (PHP_CODESNIFFER_VERBOSITY > 1) {
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...
1034
                $type    = $tokens[$i]['type'];
1035
                $content = PHP_CodeSniffer::prepareForOutput($tokens[$i]['content']);
1036
1037
                echo str_repeat("\t", count($classStack));
1038
                echo "\tProcess token $i: $type => $content".PHP_EOL;
1039
            }
1040
1041
            // Looking for functions that are actually closures.
1042
            if ($tokens[$i]['code'] === T_FUNCTION && isset($tokens[$i]['scope_opener']) === true) {
1043 View Code Duplication
                for ($x = ($i + 1); $x < $numTokens; $x++) {
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...
1044
                    if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$tokens[$x]['code']]) === false) {
1045
                        break;
1046
                    }
1047
                }
1048
1049
                if ($tokens[$x]['code'] === T_OPEN_PARENTHESIS) {
1050
                    $tokens[$i]['code'] = T_CLOSURE;
1051
                    $tokens[$i]['type'] = 'T_CLOSURE';
1052
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
1053
                        $line = $tokens[$i]['line'];
1054
                        echo str_repeat("\t", count($classStack));
1055
                        echo "\t* token $i on line $line changed from T_FUNCTION to T_CLOSURE".PHP_EOL;
1056
                    }
1057
1058
                    for ($x = ($tokens[$i]['scope_opener'] + 1); $x < $tokens[$i]['scope_closer']; $x++) {
1059
                        if (isset($tokens[$x]['conditions'][$i]) === false) {
1060
                            continue;
1061
                        }
1062
1063
                        $tokens[$x]['conditions'][$i] = T_CLOSURE;
1064
                        if (PHP_CODESNIFFER_VERBOSITY > 1) {
1065
                            $type = $tokens[$x]['type'];
1066
                            echo str_repeat("\t", count($classStack));
1067
                            echo "\t\t* cleaned $x ($type) *".PHP_EOL;
1068
                        }
1069
                    }
1070
                }//end if
1071
1072
                continue;
1073
            } else if ($tokens[$i]['code'] === T_OPEN_CURLY_BRACKET
1074
                && isset($tokens[$i]['scope_condition']) === false
1075
            ) {
1076
                $classStack[] = $i;
1077
1078
                $closer = $tokens[$i]['bracket_closer'];
1079
                $tokens[$i]['code']      = T_OBJECT;
1080
                $tokens[$i]['type']      = 'T_OBJECT';
1081
                $tokens[$closer]['code'] = T_CLOSE_OBJECT;
1082
                $tokens[$closer]['type'] = 'T_CLOSE_OBJECT';
1083
1084 View Code Duplication
                if (PHP_CODESNIFFER_VERBOSITY > 1) {
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...
1085
                    echo str_repeat("\t", count($classStack));
1086
                    echo "\t* token $i converted from T_OPEN_CURLY_BRACKET to T_OBJECT *".PHP_EOL;
1087
                    echo str_repeat("\t", count($classStack));
1088
                    echo "\t* token $closer converted from T_CLOSE_CURLY_BRACKET to T_CLOSE_OBJECT *".PHP_EOL;
1089
                }
1090
1091
                for ($x = ($i + 1); $x < $closer; $x++) {
1092
                    $tokens[$x]['conditions'][$i] = T_OBJECT;
1093
                    ksort($tokens[$x]['conditions'], SORT_NUMERIC);
1094
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
1095
                        $type = $tokens[$x]['type'];
1096
                        echo str_repeat("\t", count($classStack));
1097
                        echo "\t\t* added T_OBJECT condition to $x ($type) *".PHP_EOL;
1098
                    }
1099
                }
1100
            } else if ($tokens[$i]['code'] === T_CLOSE_OBJECT) {
1101
                $opener = array_pop($classStack);
0 ignored issues
show
Unused Code introduced by
$opener is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1102
            } else if ($tokens[$i]['code'] === T_COLON) {
1103
                // If it is a scope opener, it belongs to a
1104
                // DEFAULT or CASE statement.
1105
                if (isset($tokens[$i]['scope_condition']) === true) {
1106
                    continue;
1107
                }
1108
1109
                // Make sure this is not part of an inline IF statement.
1110
                for ($x = ($i - 1); $x >= 0; $x--) {
1111
                    if ($tokens[$x]['code'] === T_INLINE_THEN) {
1112
                        $tokens[$i]['code'] = T_INLINE_ELSE;
1113
                        $tokens[$i]['type'] = 'T_INLINE_ELSE';
1114
1115
                        if (PHP_CODESNIFFER_VERBOSITY > 1) {
1116
                            echo str_repeat("\t", count($classStack));
1117
                            echo "\t* token $i converted from T_COLON to T_INLINE_THEN *".PHP_EOL;
1118
                        }
1119
1120
                        continue(2);
1121
                    } else if ($tokens[$x]['line'] < $tokens[$i]['line']) {
1122
                        break;
1123
                    }
1124
                }
1125
1126
                // The string to the left of the colon is either a property or label.
1127 View Code Duplication
                for ($label = ($i - 1); $label >= 0; $label--) {
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...
1128
                    if (isset(PHP_CodeSniffer_Tokens::$emptyTokens[$tokens[$label]['code']]) === false) {
1129
                        break;
1130
                    }
1131
                }
1132
1133
                if ($tokens[$label]['code'] !== T_STRING
1134
                    && $tokens[$label]['code'] !== T_CONSTANT_ENCAPSED_STRING
1135
                ) {
1136
                    continue;
1137
                }
1138
1139
                if (empty($classStack) === false) {
1140
                    $tokens[$label]['code'] = T_PROPERTY;
1141
                    $tokens[$label]['type'] = 'T_PROPERTY';
1142
1143
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
1144
                        echo str_repeat("\t", count($classStack));
1145
                        echo "\t* token $label converted from T_STRING to T_PROPERTY *".PHP_EOL;
1146
                    }
1147 View Code Duplication
                } else {
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...
1148
                    $tokens[$label]['code'] = T_LABEL;
1149
                    $tokens[$label]['type'] = 'T_LABEL';
1150
1151
                    if (PHP_CODESNIFFER_VERBOSITY > 1) {
1152
                        echo str_repeat("\t", count($classStack));
1153
                        echo "\t* token $label converted from T_STRING to T_LABEL *".PHP_EOL;
1154
                    }
1155
                }//end if
1156
            }//end if
1157
        }//end for
1158
1159
        if (PHP_CODESNIFFER_VERBOSITY > 1) {
1160
            echo "\t*** END ADDITIONAL JS PROCESSING ***".PHP_EOL;
1161
        }
1162
1163
    }//end processAdditional()
1164
1165
1166
}//end class
1167