Seditio Source
Root |
./othercms/croogo-4.0.7/vendor/squizlabs/php_codesniffer/src/Standards/Squiz/Sniffs/Operators/ComparisonOperatorUsageSniff.php
<?php
/**
 * A Sniff to enforce the use of IDENTICAL type operators rather than EQUAL operators.
 *
 * @author    Greg Sherwood <gsherwood@squiz.net>
 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
 * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
 */

namespace PHP_CodeSniffer\Standards\Squiz\Sniffs\Operators;

use
PHP_CodeSniffer\Files\File;
use
PHP_CodeSniffer\Sniffs\Sniff;
use
PHP_CodeSniffer\Util\Tokens;

class
ComparisonOperatorUsageSniff implements Sniff
{

   
/**
     * A list of tokenizers this sniff supports.
     *
     * @var array
     */
   
public $supportedTokenizers = [
       
'PHP',
       
'JS',
    ];

   
/**
     * A list of valid comparison operators.
     *
     * @var array
     */
   
private static $validOps = [
       
T_IS_IDENTICAL        => true,
       
T_IS_NOT_IDENTICAL    => true,
       
T_LESS_THAN           => true,
       
T_GREATER_THAN        => true,
       
T_IS_GREATER_OR_EQUAL => true,
       
T_IS_SMALLER_OR_EQUAL => true,
       
T_INSTANCEOF          => true,
    ];

   
/**
     * A list of invalid operators with their alternatives.
     *
     * @var array<int, string>
     */
   
private static $invalidOps = [
       
'PHP' => [
           
T_IS_EQUAL     => '===',
           
T_IS_NOT_EQUAL => '!==',
           
T_BOOLEAN_NOT  => '=== FALSE',
        ],
       
'JS'  => [
           
T_IS_EQUAL     => '===',
           
T_IS_NOT_EQUAL => '!==',
        ],
    ];


   
/**
     * Registers the token types that this sniff wishes to listen to.
     *
     * @return array
     */
   
public function register()
    {
        return [
           
T_IF,
           
T_ELSEIF,
           
T_INLINE_THEN,
           
T_WHILE,
           
T_FOR,
        ];

    }
//end register()


    /**
     * Process the tokens that this sniff is listening for.
     *
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where the token was found.
     * @param int                         $stackPtr  The position in the stack where the token
     *                                               was found.
     *
     * @return void
     */
   
public function process(File $phpcsFile, $stackPtr)
    {
       
$tokens    = $phpcsFile->getTokens();
       
$tokenizer = $phpcsFile->tokenizerType;

        if (
$tokens[$stackPtr]['code'] === T_INLINE_THEN) {
           
$end = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($stackPtr - 1), null, true);
            if (
$tokens[$end]['code'] !== T_CLOSE_PARENTHESIS) {
               
// This inline IF statement does not have its condition
                // bracketed, so we need to guess where it starts.
               
for ($i = ($end - 1); $i >= 0; $i--) {
                    if (
$tokens[$i]['code'] === T_SEMICOLON) {
                       
// Stop here as we assume it is the end
                        // of the previous statement.
                       
break;
                    } else if (
$tokens[$i]['code'] === T_OPEN_TAG) {
                       
// Stop here as this is the start of the file.
                       
break;
                    } else if (
$tokens[$i]['code'] === T_CLOSE_CURLY_BRACKET) {
                       
// Stop if this is the closing brace of
                        // a code block.
                       
if (isset($tokens[$i]['scope_opener']) === true) {
                            break;
                        }
                    } else if (
$tokens[$i]['code'] === T_OPEN_CURLY_BRACKET) {
                       
// Stop if this is the opening brace of
                        // a code block.
                       
if (isset($tokens[$i]['scope_closer']) === true) {
                            break;
                        }
                    } else if (
$tokens[$i]['code'] === T_OPEN_PARENTHESIS) {
                       
// Stop if this is the start of a pair of
                        // parentheses that surrounds the inline
                        // IF statement.
                       
if (isset($tokens[$i]['parenthesis_closer']) === true
                           
&& $tokens[$i]['parenthesis_closer'] >= $stackPtr
                       
) {
                            break;
                        }
                    }
//end if
               
}//end for

               
$start = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true);
            } else {
                if (isset(
$tokens[$end]['parenthesis_opener']) === false) {
                    return;
                }

               
$start = $tokens[$end]['parenthesis_opener'];
            }
//end if
       
} else if ($tokens[$stackPtr]['code'] === T_FOR) {
            if (isset(
$tokens[$stackPtr]['parenthesis_opener']) === false) {
                return;
            }

           
$openingBracket = $tokens[$stackPtr]['parenthesis_opener'];
           
$closingBracket = $tokens[$stackPtr]['parenthesis_closer'];

           
$start = $phpcsFile->findNext(T_SEMICOLON, $openingBracket, $closingBracket);
           
$end   = $phpcsFile->findNext(T_SEMICOLON, ($start + 1), $closingBracket);
            if (
$start === false || $end === false) {
                return;
            }
        } else {
            if (isset(
$tokens[$stackPtr]['parenthesis_opener']) === false) {
                return;
            }

           
$start = $tokens[$stackPtr]['parenthesis_opener'];
           
$end   = $tokens[$stackPtr]['parenthesis_closer'];
        }
//end if

       
$requiredOps   = 0;
       
$foundOps      = 0;
       
$foundBooleans = 0;

       
$lastNonEmpty = $start;

        for (
$i = $start; $i <= $end; $i++) {
           
$type = $tokens[$i]['code'];
            if (isset(
self::$invalidOps[$tokenizer][$type]) === true) {
               
$error = 'Operator %s prohibited; use %s instead';
               
$data  = [
                   
$tokens[$i]['content'],
                   
self::$invalidOps[$tokenizer][$type],
                ];
               
$phpcsFile->addError($error, $i, 'NotAllowed', $data);
               
$foundOps++;
            } else if (isset(
self::$validOps[$type]) === true) {
               
$foundOps++;
            }

            if (
$type === T_OPEN_PARENTHESIS
               
&& isset($tokens[$i]['parenthesis_closer']) === true
               
&& isset(Tokens::$functionNameTokens[$tokens[$lastNonEmpty]['code']]) === true
           
) {
               
$i            = $tokens[$i]['parenthesis_closer'];
               
$lastNonEmpty = $i;
                continue;
            }

            if (
$tokens[$i]['code'] === T_TRUE || $tokens[$i]['code'] === T_FALSE) {
               
$foundBooleans++;
            }

            if (
$phpcsFile->tokenizerType !== 'JS'
               
&& ($tokens[$i]['code'] === T_BOOLEAN_AND
               
|| $tokens[$i]['code'] === T_BOOLEAN_OR)
            ) {
               
$requiredOps++;

               
// When the instanceof operator is used with another operator
                // like ===, you can get more ops than are required.
               
if ($foundOps > $requiredOps) {
                   
$foundOps = $requiredOps;
                }

               
// If we get to here and we have not found the right number of
                // comparison operators, then we must have had an implicit
                // true operation i.e., if ($a) instead of the required
                // if ($a === true), so let's add an error.
               
if ($requiredOps !== $foundOps) {
                   
$error = 'Implicit true comparisons prohibited; use === TRUE instead';
                   
$phpcsFile->addError($error, $stackPtr, 'ImplicitTrue');
                   
$foundOps++;
                }
            }

            if (isset(
Tokens::$emptyTokens[$type]) === false) {
               
$lastNonEmpty = $i;
            }
        }
//end for

       
$requiredOps++;

        if (
$phpcsFile->tokenizerType !== 'JS'
           
&& $foundOps < $requiredOps
           
&& ($requiredOps !== $foundBooleans)
        ) {
           
$error = 'Implicit true comparisons prohibited; use === TRUE instead';
           
$phpcsFile->addError($error, $stackPtr, 'ImplicitTrue');
        }

    }
//end process()


}//end class