PageRenderTime 8ms CodeModel.GetById 1ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/php/pear/PHP/CodeSniffer/Standards/Squiz/Sniffs/Operators/ComparisonOperatorUsageSniff.php

https://gitlab.com/trang1104/portable_project
PHP | 209 lines | 100 code | 21 blank | 88 comment | 24 complexity | 0ee1856791b6fb773fef77170408ab50 MD5 | raw file
  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-2011 Squiz Pty Ltd (ABN 77 084 670 600)
 12 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence 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-2011 Squiz Pty Ltd (ABN 77 084 670 600)
 45 * @license   http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
 46 * @version   Release: 1.3.3
 47 * @link      http://pear.php.net/package/PHP_CodeSniffer
 48 */
 49class 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_INLINE_THEN,
105               );
106
107    }//end register()
108
109
110    /**
111     * Process the tokens that this sniff is listening for.
112     *
113     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
114     * @param int                  $stackPtr  The position in the stack where the token
115     *                                        was found.
116     *
117     * @return void
118     */
119    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
120    {
121        $tokens    = $phpcsFile->getTokens();
122        $tokenizer = $phpcsFile->tokenizerType;
123
124        if ($tokens[$stackPtr]['code'] === T_INLINE_THEN) {
125            $end = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 1), null, true);
126            if ($tokens[$end]['code'] !== T_CLOSE_PARENTHESIS) {
127                // This inline IF statement does not have its condition
128                // bracketed, so we need to guess where it starts.
129                for ($i = ($end - 1); $i >= 0; $i--) {
130                    if ($tokens[$i]['code'] === T_SEMICOLON) {
131                        // Stop here as we assume it is the end
132                        // of the previous statement.
133                        break;
134                    } else if ($tokens[$i]['code'] === T_OPEN_TAG) {
135                        // Stop here as this is the start of the file.
136                        break;
137                    } else if ($tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET) {
138                        // Stop if this is the closing brace of
139                        // a code block.
140                        if (isset($tokens[$i]['scope_opener']) === true) {
141                            break;
142                        }
143                    } else if ($tokens[$i]['code'] === T_OPEN_CURLY_BRACKET) {
144                        // Stop if this is the opening brace of
145                        // a code block.
146                        if (isset($tokens[$i]['scope_closer']) === true) {
147                            break;
148                        }
149                    }
150                }//end for
151
152                $start = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($i + 1), null, true);
153            } else {
154                $start = $tokens[$end]['parenthesis_opener'];
155            }
156        } else {
157            $start = $tokens[$stackPtr]['parenthesis_opener'];
158            $end   = $tokens[$stackPtr]['parenthesis_closer'];
159        }
160
161        $requiredOps = 0;
162        $foundOps    = 0;
163
164        for ($i = $start; $i <= $end; $i++) {
165            $type = $tokens[$i]['code'];
166            if (in_array($type, array_keys(self::$_invalidOps[$tokenizer])) === true) {
167                $error = 'Operator %s prohibited; use %s instead';
168                $data  = array(
169                          $tokens[$i]['content'],
170                          self::$_invalidOps[$tokenizer][$type],
171                         );
172                $phpcsFile->addError($error, $i, 'NotAllowed', $data);
173                $foundOps++;
174            } else if (in_array($type, self::$_validOps) === true) {
175                $foundOps++;
176            }
177
178            if ($phpcsFile->tokenizerType !== 'JS') {
179                if ($tokens[$i]['code'] === T_BOOLEAN_AND || $tokens[$i]['code'] === T_BOOLEAN_OR) {
180                    $requiredOps++;
181
182                    // If we get to here and we have not found the right number of
183                    // comparison operators, then we must have had an implicit
184                    // true operation ie. if ($a) instead of the required
185                    // if ($a === true), so let's add an error.
186                    if ($requiredOps !== $foundOps) {
187                        $error = 'Implicit true comparisons prohibited; use === TRUE instead';
188                        $phpcsFile->addError($error, $stackPtr, 'ImplicitTrue');
189                        $foundOps++;
190                    }
191                }
192            }//end if
193        }//end for
194
195        $requiredOps++;
196
197        if ($phpcsFile->tokenizerType !== 'JS') {
198            if ($foundOps < $requiredOps) {
199                $error = 'Implicit true comparisons prohibited; use === TRUE instead';
200                $phpcsFile->addError($error, $stackPtr, 'ImplicitTrue');
201            }
202        }
203
204    }//end process()
205
206
207}//end class
208
209?>