PHP_CodeSniffer
[ class tree: PHP_CodeSniffer ] [ index: PHP_CodeSniffer ] [ all elements ]

Source for file IncrementDecrementUsageSniff.php

Documentation is available at IncrementDecrementUsageSniff.php

  1. <?php
  2. /**
  3.  * Ensures that the ++ operators are used when possible.
  4.  *
  5.  * @author    Greg Sherwood <gsherwood@squiz.net>
  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\Squiz\Sniffs\Operators;
  11.  
  12. use PHP_CodeSniffer\Sniffs\Sniff;
  13. use PHP_CodeSniffer\Files\File;
  14. use PHP_CodeSniffer\Util\Tokens;
  15.  
  16. class IncrementDecrementUsageSniff implements Sniff
  17. {
  18.  
  19.  
  20.     /**
  21.      * Returns an array of tokens this test wants to listen for.
  22.      *
  23.      * @return array 
  24.      */
  25.     public function register()
  26.     {
  27.         return array(
  28.                 T_EQUAL,
  29.                 T_PLUS_EQUAL,
  30.                 T_MINUS_EQUAL,
  31.                 T_INC,
  32.                 T_DEC,
  33.                );
  34.  
  35.     }//end register()
  36.  
  37.  
  38.     /**
  39.      * Processes this test, when one of its tokens is encountered.
  40.      *
  41.      * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  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.         if ($tokens[$stackPtr]['code'=== T_INC || $tokens[$stackPtr]['code'=== T_DEC{
  52.             $this->processIncDec($phpcsFile$stackPtr);
  53.         else {
  54.             $this->processAssignment($phpcsFile$stackPtr);
  55.         }
  56.  
  57.     }//end process()
  58.  
  59.  
  60.     /**
  61.      * Checks to ensure increment and decrement operators are not confusing.
  62.      *
  63.      * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  64.      * @param int                  $stackPtr  The position of the current token
  65.      *                                         in the stack passed in $tokens.
  66.      *
  67.      * @return void 
  68.      */
  69.     protected function processIncDec($phpcsFile$stackPtr)
  70.     {
  71.         $tokens $phpcsFile->getTokens();
  72.  
  73.         // Work out where the variable is so we know where to
  74.         // start looking for other operators.
  75.         if ($tokens[($stackPtr - 1)]['code'=== T_VARIABLE{
  76.             $start ($stackPtr + 1);
  77.         else {
  78.             $start ($stackPtr + 2);
  79.         }
  80.  
  81.         $next $phpcsFile->findNext(Tokens::$emptyTokens$startnulltrue);
  82.         if ($next === false{
  83.             return;
  84.         }
  85.  
  86.         if (isset(Tokens::$arithmeticTokens[$tokens[$next]['code']]=== true{
  87.             $error 'Increment and decrement operators cannot be used in an arithmetic operation';
  88.             $phpcsFile->addError($error$stackPtr'NotAllowed');
  89.             return;
  90.         }
  91.  
  92.         $prev $phpcsFile->findPrevious(Tokens::$emptyTokens($start - 3)nulltrue);
  93.         if ($prev === false{
  94.             return;
  95.         }
  96.  
  97.         // Check if this is in a string concat.
  98.         if ($tokens[$next]['code'=== T_STRING_CONCAT || $tokens[$prev]['code'=== T_STRING_CONCAT{
  99.             $error 'Increment and decrement operators must be bracketed when used in string concatenation';
  100.             $phpcsFile->addError($error$stackPtr'NoBrackets');
  101.         }
  102.  
  103.     }//end processIncDec()
  104.  
  105.  
  106.     /**
  107.      * Checks to ensure increment and decrement operators are used.
  108.      *
  109.      * @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
  110.      * @param int                  $stackPtr  The position of the current token
  111.      *                                         in the stack passed in $tokens.
  112.      *
  113.      * @return void 
  114.      */
  115.     protected function processAssignment($phpcsFile$stackPtr)
  116.     {
  117.         $tokens $phpcsFile->getTokens();
  118.  
  119.         $assignedVar $phpcsFile->findPrevious(T_WHITESPACE($stackPtr - 1)nulltrue);
  120.         // Not an assignment, return.
  121.         if ($tokens[$assignedVar]['code'!== T_VARIABLE{
  122.             return;
  123.         }
  124.  
  125.         $statementEnd $phpcsFile->findNext(array(T_SEMICOLONT_CLOSE_PARENTHESIST_CLOSE_SQUARE_BRACKETT_CLOSE_CURLY_BRACKET)$stackPtr);
  126.  
  127.         // If there is anything other than variables, numbers, spaces or operators we need to return.
  128.         $noiseTokens $phpcsFile->findNext(array(T_LNUMBERT_VARIABLET_WHITESPACET_PLUST_MINUST_OPEN_PARENTHESIS)($stackPtr + 1)$statementEndtrue);
  129.  
  130.         if ($noiseTokens !== false{
  131.             return;
  132.         }
  133.  
  134.         // If we are already using += or -=, we need to ignore
  135.         // the statement if a variable is being used.
  136.         if ($tokens[$stackPtr]['code'!== T_EQUAL{
  137.             $nextVar $phpcsFile->findNext(T_VARIABLE($stackPtr + 1)$statementEnd);
  138.             if ($nextVar !== false{
  139.                 return;
  140.             }
  141.         }
  142.  
  143.         if ($tokens[$stackPtr]['code'=== T_EQUAL{
  144.             $nextVar          ($stackPtr + 1);
  145.             $previousVariable ($stackPtr + 1);
  146.             $variableCount    = 0;
  147.             while (($nextVar $phpcsFile->findNext(T_VARIABLE($nextVar + 1)$statementEnd)) !== false{
  148.                 $previousVariable $nextVar;
  149.                 $variableCount++;
  150.             }
  151.  
  152.             if ($variableCount !== 1{
  153.                 return;
  154.             }
  155.  
  156.             $nextVar $previousVariable;
  157.             if ($tokens[$nextVar]['content'!== $tokens[$assignedVar]['content']{
  158.                 return;
  159.             }
  160.         }
  161.  
  162.         // We have only one variable, and it's the same as what is being assigned,
  163.         // so we need to check what is being added or subtracted.
  164.         $nextNumber     ($stackPtr + 1);
  165.         $previousNumber ($stackPtr + 1);
  166.         $numberCount    = 0;
  167.         while (($nextNumber $phpcsFile->findNext(array(T_LNUMBER)($nextNumber + 1)$statementEndfalse)) !== false{
  168.             $previousNumber $nextNumber;
  169.             $numberCount++;
  170.         }
  171.  
  172.         if ($numberCount !== 1{
  173.             return;
  174.         }
  175.  
  176.         $nextNumber $previousNumber;
  177.         if ($tokens[$nextNumber]['content'=== '1'{
  178.             if ($tokens[$stackPtr]['code'=== T_EQUAL{
  179.                 $opToken $phpcsFile->findNext(array(T_PLUST_MINUS)($nextVar + 1)$statementEnd);
  180.                 if ($opToken === false{
  181.                     // Operator was before the variable, like:
  182.                     // $var = 1 + $var;
  183.                     // So we ignore it.
  184.                     return;
  185.                 }
  186.  
  187.                 $operator $tokens[$opToken]['content'];
  188.             else {
  189.                 $operator substr($tokens[$stackPtr]['content']01);
  190.             }
  191.  
  192.             // If we are adding or subtracting negative value, the operator
  193.             // needs to be reversed.
  194.             if ($tokens[$stackPtr]['code'!== T_EQUAL{
  195.                 $negative $phpcsFile->findPrevious(T_MINUS($nextNumber - 1)$stackPtr);
  196.                 if ($negative !== false{
  197.                     if ($operator === '+'{
  198.                         $operator '-';
  199.                     else {
  200.                         $operator '+';
  201.                     }
  202.                 }
  203.             }
  204.  
  205.             $expected $tokens[$assignedVar]['content'].$operator.$operator;
  206.             $found    $phpcsFile->getTokensAsString($assignedVar($statementEnd $assignedVar + 1));
  207.  
  208.             if ($operator === '+'{
  209.                 $error 'Increment';
  210.             else {
  211.                 $error 'Decrement';
  212.             }
  213.  
  214.             $error .= " operators should be used where possible; found \"$found\" but expected \"$expected\"";
  215.             $phpcsFile->addError($error$stackPtr'Found');
  216.         }//end if
  217.  
  218.     }//end processAssignment()
  219.  
  220.  
  221. }//end class

Documentation generated on Mon, 11 Mar 2019 14:53:30 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.