~ubuntu-branches/ubuntu/vivid/php-codesniffer/vivid

« back to all changes in this revision

Viewing changes to PHP_CodeSniffer-1.5.4/CodeSniffer/Standards/Squiz/Sniffs/Operators/ComparisonOperatorUsageSniff.php

  • Committer: Package Import Robot
  • Author(s): David Prévot, Greg Sherwood, Alexey, Emily, David Prévot
  • Date: 2014-09-26 13:44:35 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20140926134435-wvjq16miqq4d60y0
Tags: 1.5.5-1
[ Greg Sherwood ]
* Improved closure support in Generic ScopeIndentSniff
* Improved indented PHP tag support in Generic ScopeIndentSniff
* Standards can now be located within hidden directories
 (further fix for bug #20323)
* Fixed bug #20373 : Inline comment sniff tab handling way
* Fixed bug #20378 : Report appended to existing file if no errors
  found in run
* Fixed bug #20381 : Invalid "Comment closer must be on a new line"
* PHP tokenizer no longer converts class/function names to special
  tokens types
* Fixed bug #20386 : Squiz.Commenting.ClassComment.SpacingBefore
  thrown if first block comment
* Squiz and PEAR FunctionCommentSnif now support _()
* PEAR ValidFunctionNameSniff no longer throws an error for _()
* Fixed bug #248 : FunctionCommentSniff expects ampersand on param name
* Fixed bug #248 in Squiz sniff as well
* Fixed bug #265 : False positives with type hints in ForbiddenFunctionsSniff
* Prepare for 1.5.5 release

[ Alexey ]
* Allowed single undersored methods and functions

[ Emily ]
* Added var_dump to discouraged functions sniff

[ David Prévot ]
* Revert "Add XS-Testsuite still needed for ci.d.n"
* Add self to uploaders
* Bump standards version to 3.9.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
/**
3
 
 * A Sniff to enforce the use of IDENTICAL type operators rather than EQUAL operators.
4
 
 *
5
 
 * PHP version 5
6
 
 *
7
 
 * @category  PHP
8
 
 * @package   PHP_CodeSniffer
9
 
 * @author    Greg Sherwood <gsherwood@squiz.net>
10
 
 * @author    Marc McIntyre <mmcintyre@squiz.net>
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
 
 * A Sniff to enforce the use of IDENTICAL type operators rather than EQUAL operators.
18
 
 *
19
 
 * The use of === true is enforced over implicit true statements,
20
 
 * for example:
21
 
 *
22
 
 * <code>
23
 
 * if ($a)
24
 
 * {
25
 
 *     ...
26
 
 * }
27
 
 * </code>
28
 
 *
29
 
 * should be:
30
 
 *
31
 
 * <code>
32
 
 * if ($a === true)
33
 
 * {
34
 
 *     ...
35
 
 * }
36
 
 * </code>
37
 
 *
38
 
 * It also enforces the use of === false over ! operators.
39
 
 *
40
 
 * @category  PHP
41
 
 * @package   PHP_CodeSniffer
42
 
 * @author    Greg Sherwood <gsherwood@squiz.net>
43
 
 * @author    Marc McIntyre <mmcintyre@squiz.net>
44
 
 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
45
 
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
46
 
 * @version   Release: 1.5.4
47
 
 * @link      http://pear.php.net/package/PHP_CodeSniffer
48
 
 */
49
 
class Squiz_Sniffs_Operators_ComparisonOperatorUsageSniff implements PHP_CodeSniffer_Sniff
50
 
{
51
 
 
52
 
    /**
53
 
     * A list of tokenizers this sniff supports.
54
 
     *
55
 
     * @var array
56
 
     */
57
 
    public $supportedTokenizers = array(
58
 
                                   'PHP',
59
 
                                   'JS',
60
 
                                  );
61
 
 
62
 
    /**
63
 
     * A list of valid comparison operators.
64
 
     *
65
 
     * @var array
66
 
     */
67
 
    private static $_validOps = array(
68
 
                                 T_IS_IDENTICAL,
69
 
                                 T_IS_NOT_IDENTICAL,
70
 
                                 T_LESS_THAN,
71
 
                                 T_GREATER_THAN,
72
 
                                 T_IS_GREATER_OR_EQUAL,
73
 
                                 T_IS_SMALLER_OR_EQUAL,
74
 
                                 T_INSTANCEOF,
75
 
                                );
76
 
 
77
 
    /**
78
 
     * A list of invalid operators with their alternatives.
79
 
     *
80
 
     * @var array(int => string)
81
 
     */
82
 
    private static $_invalidOps = array(
83
 
                                   'PHP' => array(
84
 
                                             T_IS_EQUAL     => '===',
85
 
                                             T_IS_NOT_EQUAL => '!==',
86
 
                                             T_BOOLEAN_NOT  => '=== FALSE',
87
 
                                            ),
88
 
                                   'JS'  => array(
89
 
                                             T_IS_EQUAL     => '===',
90
 
                                             T_IS_NOT_EQUAL => '!==',
91
 
                                            ),
92
 
                                  );
93
 
 
94
 
 
95
 
    /**
96
 
     * Registers the token types that this sniff wishes to listen to.
97
 
     *
98
 
     * @return array
99
 
     */
100
 
    public function register()
101
 
    {
102
 
        return array(
103
 
                T_IF,
104
 
                T_ELSEIF,
105
 
                T_INLINE_THEN,
106
 
               );
107
 
 
108
 
    }//end register()
109
 
 
110
 
 
111
 
    /**
112
 
     * Process the tokens that this sniff is listening for.
113
 
     *
114
 
     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
115
 
     * @param int                  $stackPtr  The position in the stack where the token
116
 
     *                                        was found.
117
 
     *
118
 
     * @return void
119
 
     */
120
 
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
121
 
    {
122
 
        $tokens    = $phpcsFile->getTokens();
123
 
        $tokenizer = $phpcsFile->tokenizerType;
124
 
 
125
 
        if ($tokens[$stackPtr]['code'] === T_INLINE_THEN) {
126
 
            $end = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 1), null, true);
127
 
            if ($tokens[$end]['code'] !== T_CLOSE_PARENTHESIS) {
128
 
                // This inline IF statement does not have its condition
129
 
                // bracketed, so we need to guess where it starts.
130
 
                for ($i = ($end - 1); $i >= 0; $i--) {
131
 
                    if ($tokens[$i]['code'] === T_SEMICOLON) {
132
 
                        // Stop here as we assume it is the end
133
 
                        // of the previous statement.
134
 
                        break;
135
 
                    } else if ($tokens[$i]['code'] === T_OPEN_TAG) {
136
 
                        // Stop here as this is the start of the file.
137
 
                        break;
138
 
                    } else if ($tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET) {
139
 
                        // Stop if this is the closing brace of
140
 
                        // a code block.
141
 
                        if (isset($tokens[$i]['scope_opener']) === true) {
142
 
                            break;
143
 
                        }
144
 
                    } else if ($tokens[$i]['code'] === T_OPEN_CURLY_BRACKET) {
145
 
                        // Stop if this is the opening brace of
146
 
                        // a code block.
147
 
                        if (isset($tokens[$i]['scope_closer']) === true) {
148
 
                            break;
149
 
                        }
150
 
                    }
151
 
                }//end for
152
 
 
153
 
                $start = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($i + 1), null, true);
154
 
            } else {
155
 
                $start = $tokens[$end]['parenthesis_opener'];
156
 
            }
157
 
        } else {
158
 
            $start = $tokens[$stackPtr]['parenthesis_opener'];
159
 
            $end   = $tokens[$stackPtr]['parenthesis_closer'];
160
 
        }
161
 
 
162
 
        $requiredOps = 0;
163
 
        $foundOps    = 0;
164
 
 
165
 
        for ($i = $start; $i <= $end; $i++) {
166
 
            $type = $tokens[$i]['code'];
167
 
            if (in_array($type, array_keys(self::$_invalidOps[$tokenizer])) === true) {
168
 
                $error = 'Operator %s prohibited; use %s instead';
169
 
                $data  = array(
170
 
                          $tokens[$i]['content'],
171
 
                          self::$_invalidOps[$tokenizer][$type],
172
 
                         );
173
 
                $phpcsFile->addError($error, $i, 'NotAllowed', $data);
174
 
                $foundOps++;
175
 
            } else if (in_array($type, self::$_validOps) === true) {
176
 
                $foundOps++;
177
 
            }
178
 
 
179
 
            if ($phpcsFile->tokenizerType !== 'JS') {
180
 
                if ($tokens[$i]['code'] === T_BOOLEAN_AND || $tokens[$i]['code'] === T_BOOLEAN_OR) {
181
 
                    $requiredOps++;
182
 
 
183
 
                    // When the instanceof operator is used with another operator
184
 
                    // like ===, you can get more ops than are required.
185
 
                    if ($foundOps > $requiredOps) {
186
 
                        $foundOps = $requiredOps;
187
 
                    }
188
 
 
189
 
                    // If we get to here and we have not found the right number of
190
 
                    // comparison operators, then we must have had an implicit
191
 
                    // true operation ie. if ($a) instead of the required
192
 
                    // if ($a === true), so let's add an error.
193
 
                    if ($requiredOps !== $foundOps) {
194
 
                        $error = 'Implicit true comparisons prohibited; use === TRUE instead';
195
 
                        $phpcsFile->addError($error, $stackPtr, 'ImplicitTrue');
196
 
                        $foundOps++;
197
 
                    }
198
 
                }
199
 
            }//end if
200
 
        }//end for
201
 
 
202
 
        $requiredOps++;
203
 
 
204
 
        if ($phpcsFile->tokenizerType !== 'JS') {
205
 
            if ($foundOps < $requiredOps) {
206
 
                $error = 'Implicit true comparisons prohibited; use === TRUE instead';
207
 
                $phpcsFile->addError($error, $stackPtr, 'ImplicitTrue');
208
 
            }
209
 
        }
210
 
 
211
 
    }//end process()
212
 
 
213
 
 
214
 
}//end class
215
 
 
216
 
?>