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

Source for file DisallowMultipleAssignmentsSniff.php

Documentation is available at DisallowMultipleAssignmentsSniff.php

  1. <?php
  2. /**
  3.  * Ensures there is only one assignment on a line, and that it is the first thing on the line.
  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\PHP;
  11.  
  12. use PHP_CodeSniffer\Sniffs\Sniff;
  13. use PHP_CodeSniffer\Files\File;
  14. use PHP_CodeSniffer\Util\Tokens;
  15.  
  16. class DisallowMultipleAssignmentsSniff 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(T_EQUAL);
  28.  
  29.     }//end register()
  30.  
  31.  
  32.     /**
  33.      * Processes this test, when one of its tokens is encountered.
  34.      *
  35.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
  36.      * @param int                         $stackPtr  The position of the current token in the
  37.      *                                                stack passed in $tokens.
  38.      *
  39.      * @return void 
  40.      */
  41.     public function process(File $phpcsFile$stackPtr)
  42.     {
  43.         $tokens $phpcsFile->getTokens();
  44.  
  45.         // Ignore default value assignments in function definitions.
  46.         $function $phpcsFile->findPrevious(array(T_FUNCTIONT_CLOSURE)($stackPtr - 1)nullfalsenulltrue);
  47.         if ($function !== false{
  48.             $opener $tokens[$function]['parenthesis_opener'];
  49.             $closer $tokens[$function]['parenthesis_closer'];
  50.             if ($opener $stackPtr && $closer $stackPtr{
  51.                 return;
  52.             }
  53.         }
  54.  
  55.         /*
  56.             The general rule is:
  57.             Find an equal sign and go backwards along the line. If you hit an
  58.             end bracket, skip to the opening bracket. When you find a variable,
  59.             stop. That variable must be the first non-empty token on the line
  60.             or in the statement. If not, throw an error.
  61.         */
  62.  
  63.         for ($varToken ($stackPtr - 1)$varToken >= 0; $varToken--{
  64.             // Skip brackets.
  65.             if (isset($tokens[$varToken]['parenthesis_opener']=== true && $tokens[$varToken]['parenthesis_opener'$varToken{
  66.                 $varToken $tokens[$varToken]['parenthesis_opener'];
  67.                 continue;
  68.             }
  69.  
  70.             if (isset($tokens[$varToken]['bracket_opener']=== true{
  71.                 $varToken $tokens[$varToken]['bracket_opener'];
  72.                 continue;
  73.             }
  74.  
  75.             if ($tokens[$varToken]['code'=== T_SEMICOLON{
  76.                 // We've reached the next statement, so we
  77.                 // didn't find a variable.
  78.                 return;
  79.             }
  80.  
  81.             if ($tokens[$varToken]['code'=== T_VARIABLE{
  82.                 // We found our variable.
  83.                 break;
  84.             }
  85.         }//end for
  86.  
  87.         if ($varToken <= 0{
  88.             // Didn't find a variable.
  89.             return;
  90.         }
  91.  
  92.         // Deal with this type of variable: self::$var by setting the var
  93.         // token to be "self" rather than "$var".
  94.         if ($tokens[($varToken - 1)]['code'=== T_DOUBLE_COLON{
  95.             $varToken ($varToken - 2);
  96.         }
  97.  
  98.         // Deal with this type of variable: $obj->$var by setting the var
  99.         // token to be "$obj" rather than "$var".
  100.         if ($tokens[($varToken - 1)]['code'=== T_OBJECT_OPERATOR{
  101.             $varToken ($varToken - 2);
  102.         }
  103.  
  104.         // Deal with this type of variable: $$var by setting the var
  105.         // token to be "$" rather than "$var".
  106.         if ($tokens[($varToken - 1)]['content'=== '$'{
  107.             $varToken--;
  108.         }
  109.  
  110.         // Ignore member var definitions.
  111.         $prev $phpcsFile->findPrevious(T_WHITESPACE($varToken - 1)nulltrue);
  112.         if (isset(Tokens::$scopeModifiers[$tokens[$prev]['code']]=== true
  113.             || $tokens[$prev]['code'=== T_VAR
  114.         {
  115.             return;
  116.         }
  117.  
  118.         if ($tokens[$prev]['code'=== T_STATIC{
  119.             return;
  120.         }
  121.  
  122.         // Make sure this variable is the first thing in the statement.
  123.         $varLine  $tokens[$varToken]['line'];
  124.         $prevLine = 0;
  125.         for ($i ($varToken - 1)$i >= 0; $i--{
  126.             if ($tokens[$i]['code'=== T_SEMICOLON{
  127.                 // We reached the end of the statement.
  128.                 return;
  129.             }
  130.  
  131.             if ($tokens[$i]['code'=== T_INLINE_THEN{
  132.                 // We reached the end of the inline THEN statement.
  133.                 return;
  134.             }
  135.  
  136.             if ($tokens[$i]['code'=== T_INLINE_ELSE{
  137.                 // We reached the end of the inline ELSE statement.
  138.                 return;
  139.             }
  140.  
  141.             if ($tokens[$i]['code'=== T_OPEN_TAG{
  142.                 // We reached the end of the code block.
  143.                 return;
  144.             }
  145.  
  146.             if (isset(Tokens::$emptyTokens[$tokens[$i]['code']]=== false{
  147.                 $prevLine $tokens[$i]['line'];
  148.                 break;
  149.             }
  150.         }//end for
  151.  
  152.         // Ignore the first part of FOR loops as we are allowed to
  153.         // assign variables there even though the variable is not the
  154.         // first thing on the line. Also ignore WHILE loops.
  155.         if ($tokens[$i]['code'=== T_OPEN_PARENTHESIS && isset($tokens[$i]['parenthesis_owner']=== true{
  156.             $owner $tokens[$i]['parenthesis_owner'];
  157.             if ($tokens[$owner]['code'=== T_FOR || $tokens[$owner]['code'=== T_WHILE{
  158.                 return;
  159.             }
  160.         }
  161.  
  162.         if ($prevLine === $varLine{
  163.             $error 'Assignments must be the first block of code on a line';
  164.             $phpcsFile->addError($error$stackPtr'Found');
  165.         }
  166.  
  167.     }//end process()
  168.  
  169.  
  170. }//end class

Documentation generated on Mon, 11 Mar 2019 15:27:23 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.