Completed
Push — master ( bf9073...71c660 )
by Wim
08:47 queued 06:47
created

NewClassMemberAccessSniff::process()   C

Complexity

Conditions 13
Paths 9

Size

Total Lines 66
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 66
rs 5.8968
c 0
b 0
f 0
cc 13
eloc 39
nc 9
nop 2

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
 * \PHPCompatibility\Sniffs\PHP\NewClassMemberAccessSniff.
4
 *
5
 * PHP version 5.4
6
 * PHP version 7.0
7
 *
8
 * @category PHP
9
 * @package  PHPCompatibility
10
 * @author   Juliette Reinders Folmer <[email protected]>
11
 */
12
13
namespace PHPCompatibility\Sniffs\PHP;
14
15
use PHPCompatibility\Sniff;
16
17
/**
18
 * \PHPCompatibility\Sniffs\PHP\NewClassMemberAccessSniff.
19
 *
20
 * PHP 5.4: Class member access on instantiation has been added, e.g. (new Foo)->bar().
21
 * PHP 7.0: Class member access on cloning has been added, e.g. (clone $foo)->bar().
22
 *
23
 * PHP version 5.4
24
 * PHP version 7.0
25
 *
26
 * @category PHP
27
 * @package  PHPCompatibility
28
 * @author   Juliette Reinders Folmer <[email protected]>
29
 */
30
class NewClassMemberAccessSniff extends Sniff
31
{
32
33
    /**
34
     * Returns an array of tokens this test wants to listen for.
35
     *
36
     * @return array
37
     */
38
    public function register()
39
    {
40
        return array(
41
            T_NEW,
42
            T_CLONE,
43
        );
44
    }
45
46
    /**
47
     * Processes this test, when one of its tokens is encountered.
48
     *
49
     * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
50
     * @param int                   $stackPtr  The position of the current token in the
51
     *                                         stack passed in $tokens.
52
     *
53
     * @return void
54
     */
55
    public function process(\PHP_CodeSniffer_File $phpcsFile, $stackPtr)
56
    {
57
        $tokens = $phpcsFile->getTokens();
58
59
        if ($tokens[$stackPtr]['code'] === T_NEW && $this->supportsBelow('5.3') !== true) {
60
            return;
61
        } elseif ($tokens[$stackPtr]['code'] === T_CLONE && $this->supportsBelow('5.6') !== true) {
62
            return;
63
        }
64
65
        if (isset($tokens[$stackPtr]['nested_parenthesis']) === false) {
66
            // The `new className/clone $a` has to be in parentheses, without is not supported.
67
            return;
68
        }
69
70
        $parenthesisCloser = end($tokens[$stackPtr]['nested_parenthesis']);
71
        $parenthesisOpener = key($tokens[$stackPtr]['nested_parenthesis']);
72
73
        if (isset($tokens[$parenthesisOpener]['parenthesis_owner']) === true) {
74
            // If there is an owner, these parentheses are for a different purpose.
75
            return;
76
        }
77
78
        $prevBeforeParenthesis = $phpcsFile->findPrevious(
79
            \PHP_CodeSniffer_Tokens::$emptyTokens,
80
            ($parenthesisOpener - 1),
81
            null,
82
            true
83
        );
84
        if ($prevBeforeParenthesis !== false && $tokens[$prevBeforeParenthesis]['code'] === T_STRING) {
85
            // This is most likely a function call with the new/cloned object as a parameter.
86
            return;
87
        }
88
89
        $nextAfterParenthesis = $phpcsFile->findNext(
90
            \PHP_CodeSniffer_Tokens::$emptyTokens,
91
            ($parenthesisCloser + 1),
92
            null,
93
            true
94
        );
95
        if ($nextAfterParenthesis === false) {
96
            // Live coding.
97
            return;
98
        }
99
100
        if ($tokens[$nextAfterParenthesis]['code'] !== T_OBJECT_OPERATOR
101
            && $tokens[$nextAfterParenthesis]['code'] !== T_OPEN_SQUARE_BRACKET
102
        ) {
103
            return;
104
        }
105
106
        $data      = array('instantiation', '5.3');
107
        $errorCode = 'OnNewFound';
108
109
        if ($tokens[$stackPtr]['code'] === T_CLONE) {
110
            $data      = array('cloning', '5.6');
111
            $errorCode = 'OnCloneFound';
112
        }
113
114
        $phpcsFile->addError(
115
            'Class member access on object %s was not supported in PHP %s or earlier',
116
            $parenthesisCloser,
117
            $errorCode,
118
            $data
119
        );
120
    }
121
}
122