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

MultiLineConditionSniff::process()   F

Complexity

Conditions 42
Paths > 20000

Size

Total Lines 204
Code Lines 125

Duplication

Lines 33
Ratio 16.18 %

Importance

Changes 0
Metric Value
cc 42
eloc 125
nc 3954961
nop 2
dl 33
loc 204
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
 * PEAR_Sniffs_ControlStructures_MultiLineConditionSniff.
4
 *
5
 * PHP version 5
6
 *
7
 * @category  PHP
8
 * @package   PHP_CodeSniffer
9
 * @author    Greg Sherwood <[email protected]>
10
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
11
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
12
 * @link      http://pear.php.net/package/PHP_CodeSniffer
13
 */
14
15
/**
16
 * PEAR_Sniffs_ControlStructures_MultiLineConditionSniff.
17
 *
18
 * Ensure multi-line IF conditions are defined correctly.
19
 *
20
 * @category  PHP
21
 * @package   PHP_CodeSniffer
22
 * @author    Greg Sherwood <[email protected]>
23
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
24
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
25
 * @version   Release: @package_version@
26
 * @link      http://pear.php.net/package/PHP_CodeSniffer
27
 */
28
class PEAR_Sniffs_ControlStructures_MultiLineConditionSniff implements PHP_CodeSniffer_Sniff
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...
29
{
30
31
    /**
32
     * A list of tokenizers this sniff supports.
33
     *
34
     * @var array
35
     */
36
    public $supportedTokenizers = array(
37
                                   'PHP',
38
                                   'JS',
39
                                  );
40
41
    /**
42
     * The number of spaces code should be indented.
43
     *
44
     * @var int
45
     */
46
    public $indent = 4;
47
48
49
    /**
50
     * Returns an array of tokens this test wants to listen for.
51
     *
52
     * @return array
53
     */
54
    public function register()
55
    {
56
        return array(
57
                T_IF,
58
                T_ELSEIF,
59
               );
60
61
    }//end register()
62
63
64
    /**
65
     * Processes this test, when one of its tokens is encountered.
66
     *
67
     * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
68
     * @param int                  $stackPtr  The position of the current token
69
     *                                        in the stack passed in $tokens.
70
     *
71
     * @return void
72
     */
73
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
74
    {
75
        $tokens = $phpcsFile->getTokens();
76
77
        if (isset($tokens[$stackPtr]['parenthesis_opener']) === false) {
78
            return;
79
        }
80
81
        $openBracket    = $tokens[$stackPtr]['parenthesis_opener'];
82
        $closeBracket   = $tokens[$stackPtr]['parenthesis_closer'];
83
        $spaceAfterOpen = 0;
84
        if ($tokens[($openBracket + 1)]['code'] === T_WHITESPACE) {
85
            if (strpos($tokens[($openBracket + 1)]['content'], $phpcsFile->eolChar) !== false) {
86
                $spaceAfterOpen = 'newline';
87
            } else {
88
                $spaceAfterOpen = strlen($tokens[($openBracket + 1)]['content']);
89
            }
90
        }
91
92
        if ($spaceAfterOpen !== 0) {
93
            $error = 'First condition of a multi-line IF statement must directly follow the opening parenthesis';
94
            $fix   = $phpcsFile->addFixableError($error, ($openBracket + 1), 'SpacingAfterOpenBrace');
95
            if ($fix === true) {
96
                if ($spaceAfterOpen === 'newline') {
97
                    $phpcsFile->fixer->replaceToken(($openBracket + 1), '');
98
                } else {
99
                    $phpcsFile->fixer->replaceToken(($openBracket + 1), '');
100
                }
101
            }
102
        }
103
104
        // We need to work out how far indented the if statement
105
        // itself is, so we can work out how far to indent conditions.
106
        $statementIndent = 0;
107 View Code Duplication
        for ($i = ($stackPtr - 1); $i >= 0; $i--) {
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...
108
            if ($tokens[$i]['line'] !== $tokens[$stackPtr]['line']) {
109
                $i++;
110
                break;
111
            }
112
        }
113
114
        if ($i >= 0 && $tokens[$i]['code'] === T_WHITESPACE) {
115
            $statementIndent = strlen($tokens[$i]['content']);
116
        }
117
118
        // Each line between the parenthesis should be indented 4 spaces
119
        // and start with an operator, unless the line is inside a
120
        // function call, in which case it is ignored.
121
        $prevLine = $tokens[$openBracket]['line'];
122
        for ($i = ($openBracket + 1); $i <= $closeBracket; $i++) {
123
            if ($i === $closeBracket && $tokens[$openBracket]['line'] !== $tokens[$i]['line']) {
124
                $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($i - 1), null, true);
125
                if ($tokens[$prev]['line'] === $tokens[$i]['line']) {
126
                    // Closing bracket is on the same line as a condition.
127
                    $error = 'Closing parenthesis of a multi-line IF statement must be on a new line';
128
                    $fix   = $phpcsFile->addFixableError($error, $closeBracket, 'CloseBracketNewLine');
129
                    if ($fix === true) {
130
                        // Account for a comment at the end of the line.
131
                        $next = $phpcsFile->findNext(T_WHITESPACE, ($closeBracket + 1), null, true);
132
                        if ($tokens[$next]['code'] !== T_COMMENT) {
133
                            $phpcsFile->fixer->addNewlineBefore($closeBracket);
134
                        } else {
135
                            $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($next + 1), null, true);
136
                            $phpcsFile->fixer->beginChangeset();
137
                            $phpcsFile->fixer->replaceToken($closeBracket, '');
138
                            $phpcsFile->fixer->addContentBefore($next, ')');
0 ignored issues
show
Security Bug introduced by
It seems like $next defined by $phpcsFile->findNext(\PH... $next + 1, null, true) on line 135 can also be of type false; however, PHP_CodeSniffer_Fixer::addContentBefore() does only seem to accept integer, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
139
                            $phpcsFile->fixer->endChangeset();
140
                        }
141
                    }
142
                }
143
            }//end if
144
145
            if ($tokens[$i]['line'] !== $prevLine) {
146
                if ($tokens[$i]['line'] === $tokens[$closeBracket]['line']) {
147
                    $next = $phpcsFile->findNext(T_WHITESPACE, $i, null, true);
148
                    if ($next !== $closeBracket) {
149
                        $expectedIndent = ($statementIndent + $this->indent);
150
                    } else {
151
                        // Closing brace needs to be indented to the same level
152
                        // as the statement.
153
                        $expectedIndent = $statementIndent;
154
                    }//end if
155
                } else {
156
                    $expectedIndent = ($statementIndent + $this->indent);
157
                }//end if
158
159
                if ($tokens[$i]['code'] === T_COMMENT) {
160
                    $prevLine = $tokens[$i]['line'];
161
                    continue;
162
                }
163
164
                // We changed lines, so this should be a whitespace indent token.
165
                if ($tokens[$i]['code'] !== T_WHITESPACE) {
166
                    $foundIndent = 0;
167
                } else {
168
                    $foundIndent = strlen($tokens[$i]['content']);
169
                }
170
171 View Code Duplication
                if ($expectedIndent !== $foundIndent) {
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...
172
                    $error = 'Multi-line IF statement not indented correctly; expected %s spaces but found %s';
173
                    $data  = array(
174
                              $expectedIndent,
175
                              $foundIndent,
176
                             );
177
178
                    $fix = $phpcsFile->addFixableError($error, $i, 'Alignment', $data);
179
                    if ($fix === true) {
180
                        $spaces = str_repeat(' ', $expectedIndent);
181
                        if ($foundIndent === 0) {
182
                            $phpcsFile->fixer->addContentBefore($i, $spaces);
183
                        } else {
184
                            $phpcsFile->fixer->replaceToken($i, $spaces);
185
                        }
186
                    }
187
                }
188
189
                $next = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, $i, null, true);
190
                if ($next !== $closeBracket) {
191
                    if (isset(PHP_CodeSniffer_Tokens::$booleanOperators[$tokens[$next]['code']]) === false) {
192
                        $error = 'Each line in a multi-line IF statement must begin with a boolean operator';
193
                        $fix   = $phpcsFile->addFixableError($error, $i, 'StartWithBoolean');
194
                        if ($fix === true) {
195
                            $prev = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($i - 1), $openBracket, true);
196
                            if (isset(PHP_CodeSniffer_Tokens::$booleanOperators[$tokens[$prev]['code']]) === true) {
197
                                $phpcsFile->fixer->beginChangeset();
198
                                $phpcsFile->fixer->replaceToken($prev, '');
0 ignored issues
show
Bug introduced by
It seems like $prev defined by $phpcsFile->findPrevious... 1, $openBracket, true) on line 195 can also be of type boolean; however, PHP_CodeSniffer_Fixer::replaceToken() does only seem to accept integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
199
                                $phpcsFile->fixer->addContentBefore($next, $tokens[$prev]['content'].' ');
0 ignored issues
show
Security Bug introduced by
It seems like $next defined by $phpcsFile->findNext(\PH...Tokens, $i, null, true) on line 189 can also be of type false; however, PHP_CodeSniffer_Fixer::addContentBefore() does only seem to accept integer, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
200
                                $phpcsFile->fixer->endChangeset();
201
                            } else {
202
                                for ($x = ($prev + 1); $x < $next; $x++) {
203
                                    $phpcsFile->fixer->replaceToken($x, '');
204
                                }
205
                            }
206
                        }
207
                    }
208
                }//end if
209
210
                $prevLine = $tokens[$i]['line'];
211
            }//end if
212
213 View Code Duplication
            if ($tokens[$i]['code'] === T_STRING) {
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...
214
                $next = $phpcsFile->findNext(T_WHITESPACE, ($i + 1), null, true);
215
                if ($tokens[$next]['code'] === T_OPEN_PARENTHESIS) {
216
                    // This is a function call, so skip to the end as they
217
                    // have their own indentation rules.
218
                    $i        = $tokens[$next]['parenthesis_closer'];
219
                    $prevLine = $tokens[$i]['line'];
220
                    continue;
221
                }
222
            }
223
        }//end for
224
225
        // From here on, we are checking the spacing of the opening and closing
226
        // braces. If this IF statement does not use braces, we end here.
227
        if (isset($tokens[$stackPtr]['scope_opener']) === false) {
228
            return;
229
        }
230
231
        // The opening brace needs to be one space away from the closing parenthesis.
232
        $openBrace = $tokens[$stackPtr]['scope_opener'];
233
        $next      = $phpcsFile->findNext(T_WHITESPACE, ($closeBracket + 1), $openBrace, true);
234
        if ($next !== false) {
235
            // Probably comments in between tokens, so don't check.
236
            return;
237
        }
238
239
        if ($tokens[$openBrace]['line'] > $tokens[$closeBracket]['line']) {
240
            $length = -1;
241
        } else if ($openBrace === ($closeBracket + 1)) {
242
            $length = 0;
243
        } else if ($openBrace === ($closeBracket + 2)
244
            && $tokens[($closeBracket + 1)]['code'] === T_WHITESPACE
245
        ) {
246
            $length = strlen($tokens[($closeBracket + 1)]['content']);
247
        } else {
248
            // Confused, so don't check.
249
            $length = 1;
250
        }
251
252
        if ($length === 1) {
253
            return;
254
        }
255
256
        $data = array($length);
257
        $code = 'SpaceBeforeOpenBrace';
258
259
        $error = 'There must be a single space between the closing parenthesis and the opening brace of a multi-line IF statement; found ';
260
        if ($length === -1) {
261
            $error .= 'newline';
262
            $code   = 'NewlineBeforeOpenBrace';
263
        } else {
264
            $error .= '%s spaces';
265
        }
266
267
        $fix = $phpcsFile->addFixableError($error, ($closeBracket + 1), $code, $data);
268
        if ($fix === true) {
269
            if ($length === 0) {
270
                $phpcsFile->fixer->addContent($closeBracket, ' ');
271
            } else {
272
                $phpcsFile->fixer->replaceToken(($closeBracket + 1), ' ');
273
            }
274
        }
275
276
    }//end process()
277
278
279
}//end class
280