Completed
Push — development ( 29b82e...e01cc9 )
by Ashutosh
10:05
created

ObjectOperatorIndentSniff::process()   F

Complexity

Conditions 25
Paths 5426

Size

Total Lines 126
Code Lines 74

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 74
dl 0
loc 126
rs 0
c 0
b 0
f 0
cc 25
nc 5426
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
 * Checks that object operators are indented correctly.
4
 *
5
 * @author    Greg Sherwood <[email protected]>
6
 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
7
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
8
 */
9
10
namespace PHP_CodeSniffer\Standards\PEAR\Sniffs\WhiteSpace;
11
12
use PHP_CodeSniffer\Sniffs\Sniff;
13
use PHP_CodeSniffer\Files\File;
14
15
class ObjectOperatorIndentSniff implements Sniff
16
{
17
18
    /**
19
     * The number of spaces code should be indented.
20
     *
21
     * @var integer
22
     */
23
    public $indent = 4;
24
25
26
    /**
27
     * Returns an array of tokens this test wants to listen for.
28
     *
29
     * @return int[]
30
     */
31
    public function register()
32
    {
33
        return [T_OBJECT_OPERATOR];
34
35
    }//end register()
36
37
38
    /**
39
     * Processes this test, when one of its tokens is encountered.
40
     *
41
     * @param \PHP_CodeSniffer\Files\File $phpcsFile All the tokens found in the document.
42
     * @param int                         $stackPtr  The position of the current token
43
     *                                               in the stack passed in $tokens.
44
     *
45
     * @return void
46
     */
47
    public function process(File $phpcsFile, $stackPtr)
48
    {
49
        $tokens = $phpcsFile->getTokens();
50
51
        // Make sure this is the first object operator in a chain of them.
52
        $varToken = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true);
53
        if ($varToken === false || $tokens[$varToken]['code'] !== T_VARIABLE) {
54
            return;
55
        }
56
57
        // Make sure this is a chained call.
58
        $next = $phpcsFile->findNext(
59
            T_OBJECT_OPERATOR,
60
            ($stackPtr + 1),
61
            null,
62
            false,
63
            null,
64
            true
65
        );
66
67
        if ($next === false) {
68
            // Not a chained call.
69
            return;
70
        }
71
72
        // Determine correct indent.
73
        for ($i = ($varToken - 1); $i >= 0; $i--) {
74
            if ($tokens[$i]['line'] !== $tokens[$varToken]['line']) {
75
                $i++;
76
                break;
77
            }
78
        }
79
80
        $requiredIndent = 0;
81
        if ($i >= 0 && $tokens[$i]['code'] === T_WHITESPACE) {
82
            $requiredIndent = strlen($tokens[$i]['content']);
83
        }
84
85
        $requiredIndent += $this->indent;
86
87
        // Determine the scope of the original object operator.
88
        $origBrackets = null;
89
        if (isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
90
            $origBrackets = $tokens[$stackPtr]['nested_parenthesis'];
91
        }
92
93
        $origConditions = null;
94
        if (isset($tokens[$stackPtr]['conditions']) === true) {
95
            $origConditions = $tokens[$stackPtr]['conditions'];
96
        }
97
98
        // Check indentation of each object operator in the chain.
99
        // If the first object operator is on a different line than
100
        // the variable, make sure we check its indentation too.
101
        if ($tokens[$stackPtr]['line'] > $tokens[$varToken]['line']) {
102
            $next = $stackPtr;
103
        }
104
105
        while ($next !== false) {
106
            // Make sure it is in the same scope, otherwise don't check indent.
107
            $brackets = null;
108
            if (isset($tokens[$next]['nested_parenthesis']) === true) {
109
                $brackets = $tokens[$next]['nested_parenthesis'];
110
            }
111
112
            $conditions = null;
113
            if (isset($tokens[$next]['conditions']) === true) {
114
                $conditions = $tokens[$next]['conditions'];
115
            }
116
117
            if ($origBrackets === $brackets && $origConditions === $conditions) {
118
                // Make sure it starts a line, otherwise dont check indent.
119
                $prev   = $phpcsFile->findPrevious(T_WHITESPACE, ($next - 1), $stackPtr, true);
120
                $indent = $tokens[($next - 1)];
121
                if ($tokens[$prev]['line'] !== $tokens[$next]['line']
122
                    && $indent['code'] === T_WHITESPACE
123
                ) {
124
                    if ($indent['line'] === $tokens[$next]['line']) {
125
                        $foundIndent = strlen($indent['content']);
126
                    } else {
127
                        $foundIndent = 0;
128
                    }
129
130
                    if ($foundIndent !== $requiredIndent) {
131
                        $error = 'Object operator not indented correctly; expected %s spaces but found %s';
132
                        $data  = [
133
                            $requiredIndent,
134
                            $foundIndent,
135
                        ];
136
137
                        $fix = $phpcsFile->addFixableError($error, $next, 'Incorrect', $data);
138
                        if ($fix === true) {
139
                            $spaces = str_repeat(' ', $requiredIndent);
140
                            if ($foundIndent === 0) {
141
                                $phpcsFile->fixer->addContentBefore($next, $spaces);
142
                            } else {
143
                                $phpcsFile->fixer->replaceToken(($next - 1), $spaces);
144
                            }
145
                        }
146
                    }
147
                }//end if
148
149
                // It cant be the last thing on the line either.
150
                $content = $phpcsFile->findNext(T_WHITESPACE, ($next + 1), null, true);
151
                if ($tokens[$content]['line'] !== $tokens[$next]['line']) {
152
                    $error = 'Object operator must be at the start of the line, not the end';
153
                    $fix   = $phpcsFile->addFixableError($error, $next, 'StartOfLine');
154
                    if ($fix === true) {
155
                        $phpcsFile->fixer->beginChangeset();
156
                        for ($x = ($next + 1); $x < $content; $x++) {
157
                            $phpcsFile->fixer->replaceToken($x, '');
158
                        }
159
160
                        $phpcsFile->fixer->addNewlineBefore($next);
161
                        $phpcsFile->fixer->endChangeset();
162
                    }
163
                }
164
            }//end if
165
166
            $next = $phpcsFile->findNext(
167
                T_OBJECT_OPERATOR,
168
                ($next + 1),
169
                null,
170
                false,
171
                null,
172
                true
173
            );
174
        }//end while
175
176
    }//end process()
177
178
179
}//end class
180