Completed
Push — master ( ea568b...27f42e )
by Wim
06:01
created

NewClassesSniff::process()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 30
Code Lines 19

Duplication

Lines 30
Ratio 100 %

Importance

Changes 0
Metric Value
dl 30
loc 30
rs 8.439
c 0
b 0
f 0
cc 6
eloc 19
nc 7
nop 2
1
<?php
2
/**
3
 * \PHPCompatibility\Sniffs\PHP\NewClassesSniff.
4
 *
5
 * @category  PHP
6
 * @package   PHPCompatibility
7
 * @author    Wim Godden <[email protected]>
8
 * @copyright 2013 Cu.be Solutions bvba
9
 */
10
11
namespace PHPCompatibility\Sniffs\PHP;
12
13
use PHPCompatibility\AbstractNewFeatureSniff;
14
15
/**
16
 * \PHPCompatibility\Sniffs\PHP\NewClassesSniff.
17
 *
18
 * @category  PHP
19
 * @package   PHPCompatibility
20
 * @author    Wim Godden <[email protected]>
21
 * @copyright 2013 Cu.be Solutions bvba
22
 */
23
class NewClassesSniff extends AbstractNewFeatureSniff
24
{
25
26
    /**
27
     * A list of new classes, not present in older versions.
28
     *
29
     * The array lists : version number with false (not present) or true (present).
30
     * If's sufficient to list the first version where the class appears.
31
     *
32
     * @var array(string => array(string => bool))
33
     */
34
    protected $newClasses = array(
35
        'ArrayObject' => array(
36
            '4.4' => false,
37
            '5.0' => true,
38
        ),
39
        'ArrayIterator' => array(
40
            '4.4' => false,
41
            '5.0' => true,
42
        ),
43
        'CachingIterator' => array(
44
            '4.4' => false,
45
            '5.0' => true,
46
        ),
47
        'DirectoryIterator' => array(
48
            '4.4' => false,
49
            '5.0' => true,
50
        ),
51
        'RecursiveDirectoryIterator' => array(
52
            '4.4' => false,
53
            '5.0' => true,
54
        ),
55
        'RecursiveIteratorIterator' => array(
56
            '4.4' => false,
57
            '5.0' => true,
58
        ),
59
        'php_user_filter' => array(
60
            '4.4' => false,
61
            '5.0' => true,
62
        ),
63
        'tidy' => array(
64
            '4.4' => false,
65
            '5.0' => true,
66
        ),
67
68
        'SimpleXMLElement' => array(
69
            '5.0.0' => false,
70
            '5.0.1' => true,
71
        ),
72
        'tidyNode' => array(
73
            '5.0.0' => false,
74
            '5.0.1' => true,
75
        ),
76
77
        'libXMLError' => array(
78
            '5.0' => false,
79
            '5.1' => true,
80
        ),
81
        'PDO' => array(
82
            '5.0' => false,
83
            '5.1' => true,
84
        ),
85
        'PDOStatement' => array(
86
            '5.0' => false,
87
            '5.1' => true,
88
        ),
89
        'AppendIterator' => array(
90
            '5.0' => false,
91
            '5.1' => true,
92
        ),
93
        'EmptyIterator' => array(
94
            '5.0' => false,
95
            '5.1' => true,
96
        ),
97
        'FilterIterator' => array(
98
            '5.0' => false,
99
            '5.1' => true,
100
        ),
101
        'InfiniteIterator' => array(
102
            '5.0' => false,
103
            '5.1' => true,
104
        ),
105
        'IteratorIterator' => array(
106
            '5.0' => false,
107
            '5.1' => true,
108
        ),
109
        'LimitIterator' => array(
110
            '5.0' => false,
111
            '5.1' => true,
112
        ),
113
        'NoRewindIterator' => array(
114
            '5.0' => false,
115
            '5.1' => true,
116
        ),
117
        'ParentIterator' => array(
118
            '5.0' => false,
119
            '5.1' => true,
120
        ),
121
        'RecursiveArrayIterator' => array(
122
            '5.0' => false,
123
            '5.1' => true,
124
        ),
125
        'RecursiveCachingIterator' => array(
126
            '5.0' => false,
127
            '5.1' => true,
128
        ),
129
        'RecursiveFilterIterator' => array(
130
            '5.0' => false,
131
            '5.1' => true,
132
        ),
133
        'SimpleXMLIterator' => array(
134
            '5.0' => false,
135
            '5.1' => true,
136
        ),
137
        'SplFileObject' => array(
138
            '5.0' => false,
139
            '5.1' => true,
140
        ),
141
        'XMLReader' => array(
142
            '5.0' => false,
143
            '5.1' => true,
144
        ),
145
146
        'SplFileInfo' => array(
147
            '5.1.1' => false,
148
            '5.1.2' => true,
149
        ),
150
        'SplTempFileObject' => array(
151
            '5.1.1' => false,
152
            '5.1.2' => true,
153
        ),
154
        'XMLWriter' => array(
155
            '5.1.1' => false,
156
            '5.1.2' => true,
157
        ),
158
159
        'DateTime' => array(
160
            '5.1' => false,
161
            '5.2' => true,
162
        ),
163
        'DateTimeZone' => array(
164
            '5.1' => false,
165
            '5.2' => true,
166
        ),
167
        'RegexIterator' => array(
168
            '5.1' => false,
169
            '5.2' => true,
170
        ),
171
        'RecursiveRegexIterator' => array(
172
            '5.1' => false,
173
            '5.2' => true,
174
        ),
175
        'ReflectionFunctionAbstract' => array(
176
            '5.1' => false,
177
            '5.2' => true,
178
        ),
179
        'ZipArchive' => array(
180
            '5.1' => false,
181
            '5.2' => true,
182
        ),
183
184
        'Closure' => array(
185
            '5.2' => false,
186
            '5.3' => true,
187
        ),
188
        'DateInterval' => array(
189
            '5.2' => false,
190
            '5.3' => true,
191
        ),
192
        'DatePeriod' => array(
193
            '5.2' => false,
194
            '5.3' => true,
195
        ),
196
        'finfo' => array(
197
            '5.2' => false,
198
            '5.3' => true,
199
        ),
200
        'Collator' => array(
201
            '5.2' => false,
202
            '5.3' => true,
203
        ),
204
        'NumberFormatter' => array(
205
            '5.2' => false,
206
            '5.3' => true,
207
        ),
208
        'Locale' => array(
209
            '5.2' => false,
210
            '5.3' => true,
211
        ),
212
        'Normalizer' => array(
213
            '5.2' => false,
214
            '5.3' => true,
215
        ),
216
        'MessageFormatter' => array(
217
            '5.2' => false,
218
            '5.3' => true,
219
        ),
220
        'IntlDateFormatter' => array(
221
            '5.2' => false,
222
            '5.3' => true,
223
        ),
224
        'Phar' => array(
225
            '5.2' => false,
226
            '5.3' => true,
227
        ),
228
        'PharData' => array(
229
            '5.2' => false,
230
            '5.3' => true,
231
        ),
232
        'PharFileInfo' => array(
233
            '5.2' => false,
234
            '5.3' => true,
235
        ),
236
        'FilesystemIterator' => array(
237
            '5.2' => false,
238
            '5.3' => true,
239
        ),
240
        'GlobIterator' => array(
241
            '5.2' => false,
242
            '5.3' => true,
243
        ),
244
        'MultipleIterator' => array(
245
            '5.2' => false,
246
            '5.3' => true,
247
        ),
248
        'RecursiveTreeIterator' => array(
249
            '5.2' => false,
250
            '5.3' => true,
251
        ),
252
        'SplDoublyLinkedList' => array(
253
            '5.2' => false,
254
            '5.3' => true,
255
        ),
256
        'SplFixedArray' => array(
257
            '5.2' => false,
258
            '5.3' => true,
259
        ),
260
        'SplHeap' => array(
261
            '5.2' => false,
262
            '5.3' => true,
263
        ),
264
        'SplMaxHeap' => array(
265
            '5.2' => false,
266
            '5.3' => true,
267
        ),
268
        'SplMinHeap' => array(
269
            '5.2' => false,
270
            '5.3' => true,
271
        ),
272
        'SplObjectStorage' => array(
273
            '5.2' => false,
274
            '5.3' => true,
275
        ),
276
        'SplPriorityQueue' => array(
277
            '5.2' => false,
278
            '5.3' => true,
279
        ),
280
        'SplQueue' => array(
281
            '5.2' => false,
282
            '5.3' => true,
283
        ),
284
        'SplStack' => array(
285
            '5.2' => false,
286
            '5.3' => true,
287
        ),
288
289
        'ResourceBundle' => array(
290
            '5.3.1' => false,
291
            '5.3.2' => true,
292
        ),
293
294
        'CallbackFilterIterator' => array(
295
            '5.3' => false,
296
            '5.4' => true,
297
        ),
298
        'RecursiveCallbackFilterIterator' => array(
299
            '5.3' => false,
300
            '5.4' => true,
301
        ),
302
        'ReflectionZendExtension' => array(
303
            '5.3' => false,
304
            '5.4' => true,
305
        ),
306
        'SessionHandler' => array(
307
            '5.3' => false,
308
            '5.4' => true,
309
        ),
310
        'SNMP' => array(
311
            '5.3' => false,
312
            '5.4' => true,
313
        ),
314
        'Transliterator' => array(
315
            '5.3' => false,
316
            '5.4' => true,
317
        ),
318
        'Spoofchecker' => array(
319
            '5.3' => false,
320
            '5.4' => true,
321
        ),
322
323
        'Generator' => array(
324
            '5.4' => false,
325
            '5.5' => true,
326
        ),
327
        'CURLFile' => array(
328
            '5.4' => false,
329
            '5.5' => true,
330
        ),
331
        'DateTimeImmutable' => array(
332
            '5.4' => false,
333
            '5.5' => true,
334
        ),
335
        'IntlCalendar' => array(
336
            '5.4' => false,
337
            '5.5' => true,
338
        ),
339
        'IntlGregorianCalendar' => array(
340
            '5.4' => false,
341
            '5.5' => true,
342
        ),
343
        'IntlTimeZone' => array(
344
            '5.4' => false,
345
            '5.5' => true,
346
        ),
347
        'IntlBreakIterator' => array(
348
            '5.4' => false,
349
            '5.5' => true,
350
        ),
351
        'IntlRuleBasedBreakIterator' => array(
352
            '5.4' => false,
353
            '5.5' => true,
354
        ),
355
        'IntlCodePointBreakIterator' => array(
356
            '5.4' => false,
357
            '5.5' => true,
358
        ),
359
        'UConverter' => array(
360
            '5.4' => false,
361
            '5.5' => true,
362
        ),
363
364
        'GMP' => array(
365
            '5.5' => false,
366
            '5.6' => true,
367
        ),
368
369
        'IntlChar' => array(
370
            '5.6' => false,
371
            '7.0' => true,
372
        ),
373
        'ReflectionType' => array(
374
            '5.6' => false,
375
            '7.0' => true,
376
        ),
377
        'ReflectionGenerator' => array(
378
            '5.6' => false,
379
            '7.0' => true,
380
        ),
381
382
        'ReflectionClassConstant' => array(
383
            '7.0' => false,
384
            '7.1' => true,
385
        ),
386
387
    );
388
389
    /**
390
     * A list of new Exception classes, not present in older versions.
391
     *
392
     * The array lists : version number with false (not present) or true (present).
393
     * If's sufficient to list the first version where the class appears.
394
     *
395
     * {@internal Classes listed here do not need to be added to the $newClasses
396
     *            property as well.
397
     *            This list is automatically added to the $newClasses property
398
     *            in the `register()` method.}}
399
     *
400
     * @var array(string => array(string => bool))
401
     */
402
    protected $newExceptions = array(
403
        'Exception' => array(
404
            // According to the docs introduced in PHP 5.1, but this appears to be.
405
            // an error.  Class was introduced with try/catch keywords in PHP 5.0.
406
            '4.4' => false,
407
            '5.0' => true,
408
        ),
409
        'ErrorException' => array(
410
            '5.0' => false,
411
            '5.1' => true,
412
        ),
413
        'BadFunctionCallException' => array(
414
            '5.0' => false,
415
            '5.1' => true,
416
        ),
417
        'BadMethodCallException' => array(
418
            '5.0' => false,
419
            '5.1' => true,
420
        ),
421
        'DomainException' => array(
422
            '5.0' => false,
423
            '5.1' => true,
424
        ),
425
        'InvalidArgumentException' => array(
426
            '5.0' => false,
427
            '5.1' => true,
428
        ),
429
        'LengthException' => array(
430
            '5.0' => false,
431
            '5.1' => true,
432
        ),
433
        'LogicException' => array(
434
            '5.0' => false,
435
            '5.1' => true,
436
        ),
437
        'OutOfBoundsException' => array(
438
            '5.0' => false,
439
            '5.1' => true,
440
        ),
441
        'OutOfRangeException' => array(
442
            '5.0' => false,
443
            '5.1' => true,
444
        ),
445
        'OverflowException' => array(
446
            '5.0' => false,
447
            '5.1' => true,
448
        ),
449
        'RangeException' => array(
450
            '5.0' => false,
451
            '5.1' => true,
452
        ),
453
        'RuntimeException' => array(
454
            '5.0' => false,
455
            '5.1' => true,
456
        ),
457
        'UnderflowException' => array(
458
            '5.0' => false,
459
            '5.1' => true,
460
        ),
461
        'UnexpectedValueException' => array(
462
            '5.0' => false,
463
            '5.1' => true,
464
        ),
465
        'DOMException' => array(
466
            '4.4' => false,
467
            '5.0' => true,
468
        ),
469
        'mysqli_sql_exception' => array(
470
            '4.4' => false,
471
            '5.0' => true,
472
        ),
473
        'PDOException' => array(
474
            '5.0' => false,
475
            '5.1' => true,
476
        ),
477
        'ReflectionException' => array(
478
            '4.4' => false,
479
            '5.0' => true,
480
        ),
481
        'SoapFault' => array(
482
            '4.4' => false,
483
            '5.0' => true,
484
        ),
485
486
        'PharException' => array(
487
            '5.2' => false,
488
            '5.3' => true,
489
        ),
490
491
        'SNMPException' => array(
492
            '5.3' => false,
493
            '5.4' => true,
494
        ),
495
496
        'IntlException' => array(
497
            '5.5.0' => false,
498
            '5.5.1' => true,
499
        ),
500
501
        'Error' => array(
502
            '5.6' => false,
503
            '7.0' => true,
504
        ),
505
        'ArithmeticError' => array(
506
            '5.6' => false,
507
            '7.0' => true,
508
        ),
509
        'AssertionError' => array(
510
            '5.6' => false,
511
            '7.0' => true,
512
        ),
513
        'DivisionByZeroError' => array(
514
            '5.6' => false,
515
            '7.0' => true,
516
        ),
517
        'ParseError' => array(
518
            '5.6' => false,
519
            '7.0' => true,
520
        ),
521
        'TypeError' => array(
522
            '5.6' => false,
523
            '7.0' => true,
524
        ),
525
        'UI\Exception\InvalidArgumentException' => array(
526
            '5.6' => false,
527
            '7.0' => true,
528
        ),
529
        'UI\Exception\RuntimeException' => array(
530
            '5.6' => false,
531
            '7.0' => true,
532
        ),
533
534
        'ArgumentCountError' => array(
535
            '7.0' => false,
536
            '7.1' => true,
537
        ),
538
    );
539
540
541
    /**
542
     * Returns an array of tokens this test wants to listen for.
543
     *
544
     * @return array
545
     */
546
    public function register()
547
    {
548
        // Handle case-insensitivity of class names.
549
        $this->newClasses = $this->arrayKeysToLowercase($this->newClasses);
550
        $this->newExceptions = $this->arrayKeysToLowercase($this->newExceptions);
551
552
        // Add the Exception classes to the Classes list.
553
        $this->newClasses = array_merge($this->newClasses, $this->newExceptions);
554
555
        $targets = array(
556
            T_NEW,
557
            T_CLASS,
558
            T_DOUBLE_COLON,
559
            T_FUNCTION,
560
            T_CLOSURE,
561
            T_CATCH,
562
        );
563
564
        if (defined('T_ANON_CLASS')) {
565
            $targets[] = constant('T_ANON_CLASS');
566
        }
567
568
        if (defined('T_RETURN_TYPE')) {
569
            $targets[] = constant('T_RETURN_TYPE');
570
        }
571
572
        return $targets;
573
574
    }//end register()
575
576
577
    /**
578
     * Processes this test, when one of its tokens is encountered.
579
     *
580
     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
581
     * @param int                   $stackPtr  The position of the current token in
582
     *                                         the stack passed in $tokens.
583
     *
584
     * @return void
585
     */
586 View Code Duplication
    public function process(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
587
    {
588
        $tokens = $phpcsFile->getTokens();
589
590
        switch ($tokens[$stackPtr]['type']) {
591
            case 'T_FUNCTION':
592
            case 'T_CLOSURE':
593
                $this->processFunctionToken($phpcsFile, $stackPtr);
594
595
                // Deal with older PHPCS version which don't recognize return type hints.
596
                $returnTypeHint = $this->getReturnTypeHintToken($phpcsFile, $stackPtr);
597
                if ($returnTypeHint !== false) {
598
                    $this->processReturnTypeToken($phpcsFile, $returnTypeHint);
599
                }
600
                break;
601
602
            case 'T_CATCH':
603
                $this->processCatchToken($phpcsFile, $stackPtr);
604
                break;
605
606
            case 'T_RETURN_TYPE':
607
                $this->processReturnTypeToken($phpcsFile, $stackPtr);
608
                break;
609
610
            default:
611
                $this->processSingularToken($phpcsFile, $stackPtr);
612
                break;
613
        }
614
615
    }//end process()
616
617
618
    /**
619
     * Processes this test for when a token resulting in a singular class name is encountered.
620
     *
621
     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
622
     * @param int                   $stackPtr  The position of the current token in
623
     *                                         the stack passed in $tokens.
624
     *
625
     * @return void
626
     */
627
    private function processSingularToken(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
628
    {
629
        $tokens      = $phpcsFile->getTokens();
630
        $FQClassName = '';
631
632
        if ($tokens[$stackPtr]['type'] === 'T_NEW') {
633
            $FQClassName = $this->getFQClassNameFromNewToken($phpcsFile, $stackPtr);
634
635
        } elseif ($tokens[$stackPtr]['type'] === 'T_CLASS' || $tokens[$stackPtr]['type'] === 'T_ANON_CLASS') {
636
            $FQClassName = $this->getFQExtendedClassName($phpcsFile, $stackPtr);
637
638
        } elseif ($tokens[$stackPtr]['type'] === 'T_DOUBLE_COLON') {
639
            $FQClassName = $this->getFQClassNameFromDoubleColonToken($phpcsFile, $stackPtr);
640
        }
641
642
        if ($FQClassName === '') {
643
            return;
644
        }
645
646
        $className   = substr($FQClassName, 1); // Remove global namespace indicator.
647
        $classNameLc = strtolower($className);
648
649
        if (isset($this->newClasses[$classNameLc]) === false) {
650
            return;
651
        }
652
653
        $itemInfo = array(
654
            'name'   => $className,
655
            'nameLc' => $classNameLc,
656
        );
657
        $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
658
659
    }//end processSingularToken()
660
661
662
    /**
663
     * Processes this test for when a function token is encountered.
664
     *
665
     * - Detect new classes when used as a type hint.
666
     *
667
     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
668
     * @param int                   $stackPtr  The position of the current token in
669
     *                                         the stack passed in $tokens.
670
     *
671
     * @return void
672
     */
673 View Code Duplication
    private function processFunctionToken(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
674
    {
675
        // Retrieve typehints stripped of global NS indicator and/or nullable indicator.
676
        $typeHints = $this->getTypeHintsFromFunctionDeclaration($phpcsFile, $stackPtr);
677
        if (empty($typeHints) || is_array($typeHints) === false) {
678
            return;
679
        }
680
681
        foreach ($typeHints as $hint) {
682
683
            $typeHintLc = strtolower($hint);
684
685
            if (isset($this->newClasses[$typeHintLc]) === true) {
686
                $itemInfo = array(
687
                    'name'   => $hint,
688
                    'nameLc' => $typeHintLc,
689
                );
690
                $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
691
            }
692
        }
693
    }
694
695
696
    /**
697
     * Processes this test for when a catch token is encountered.
698
     *
699
     * - Detect exceptions when used in a catch statement.
700
     *
701
     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
702
     * @param int                   $stackPtr  The position of the current token in
703
     *                                         the stack passed in $tokens.
704
     *
705
     * @return void
706
     */
707
    private function processCatchToken(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
708
    {
709
        $tokens = $phpcsFile->getTokens();
710
711
        // Bow out during live coding.
712
        if (isset($tokens[$stackPtr]['parenthesis_opener'], $tokens[$stackPtr]['parenthesis_closer']) === false) {
713
            return;
714
        }
715
716
        $opener = $tokens[$stackPtr]['parenthesis_opener'];
717
        $closer = ($tokens[$stackPtr]['parenthesis_closer'] + 1);
718
        $name   = '';
719
        $listen = array(
720
            // Parts of a (namespaced) class name.
721
            T_STRING              => true,
722
            T_NS_SEPARATOR        => true,
723
            // End/split tokens.
724
            T_VARIABLE            => false,
725
            T_BITWISE_OR          => false,
726
            T_CLOSE_CURLY_BRACKET => false, // Shouldn't be needed as we expect a var before this.
727
        );
728
729
        for ($i = ($opener + 1); $i < $closer; $i++) {
730
            if (isset($listen[$tokens[$i]['code']]) === false) {
731
                continue;
732
            }
733
734
            if ($listen[$tokens[$i]['code']] === true) {
735
                $name .= $tokens[$i]['content'];
736
                continue;
737
            } else {
738
                if (empty($name) === true) {
739
                    // Weird, we should have a name by the time we encounter a variable or |.
740
                    // So this may be the closer.
741
                    continue;
742
                }
743
744
                $name   = ltrim($name, '\\');
745
                $nameLC = strtolower($name);
746
747
                if (isset($this->newExceptions[$nameLC]) === true) {
748
                    $itemInfo = array(
749
                        'name'   => $name,
750
                        'nameLc' => $nameLC,
751
                    );
752
                    $this->handleFeature($phpcsFile, $i, $itemInfo);
753
                }
754
755
                // Reset for a potential multi-catch.
756
                $name = '';
757
            }
758
        }
759
    }
760
761
762
    /**
763
     * Processes this test for when a return type token is encountered.
764
     *
765
     * - Detect new classes when used as a return type declaration.
766
     *
767
     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
768
     * @param int                   $stackPtr  The position of the current token in
769
     *                                         the stack passed in $tokens.
770
     *
771
     * @return void
772
     */
773 View Code Duplication
    private function processReturnTypeToken(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
774
    {
775
        $returnTypeHint   = $this->getReturnTypeHintName($phpcsFile, $stackPtr);
776
        $returnTypeHint   = ltrim($returnTypeHint, '\\');
777
        $returnTypeHintLc = strtolower($returnTypeHint);
778
779
        if (isset($this->newClasses[$returnTypeHintLc]) === false) {
780
            return;
781
        }
782
783
        // Still here ? Then this is a return type declaration using a new class.
784
        $itemInfo = array(
785
            'name'   => $returnTypeHint,
786
            'nameLc' => $returnTypeHintLc,
787
        );
788
        $this->handleFeature($phpcsFile, $stackPtr, $itemInfo);
789
    }
790
791
792
    /**
793
     * Get the relevant sub-array for a specific item from a multi-dimensional array.
794
     *
795
     * @param array $itemInfo Base information about the item.
796
     *
797
     * @return array Version and other information about the item.
798
     */
799
    public function getItemArray(array $itemInfo)
800
    {
801
        return $this->newClasses[$itemInfo['nameLc']];
802
    }
803
804
805
    /**
806
     * Get the error message template for this sniff.
807
     *
808
     * @return string
809
     */
810
    protected function getErrorMsgTemplate()
811
    {
812
        return 'The built-in class '.parent::getErrorMsgTemplate();
813
    }
814
815
816
}//end class
817