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

Source for file ControlSignatureSniff.php

Documentation is available at ControlSignatureSniff.php

  1. <?php
  2. /**
  3.  * Verifies that control statements conform to their coding standards.
  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\ControlStructures;
  11.  
  12. use PHP_CodeSniffer\Sniffs\Sniff;
  13. use PHP_CodeSniffer\Files\File;
  14. use PHP_CodeSniffer\Util\Tokens;
  15.  
  16. class ControlSignatureSniff implements Sniff
  17. {
  18.  
  19.     /**
  20.      * A list of tokenizers this sniff supports.
  21.      *
  22.      * @var array 
  23.      */
  24.     public $supportedTokenizers = array(
  25.                                    'PHP',
  26.                                    'JS',
  27.                                   );
  28.  
  29.  
  30.     /**
  31.      * Returns an array of tokens this test wants to listen for.
  32.      *
  33.      * @return int[] 
  34.      */
  35.     public function register()
  36.     {
  37.         return array(
  38.                 T_TRY,
  39.                 T_CATCH,
  40.                 T_DO,
  41.                 T_WHILE,
  42.                 T_FOR,
  43.                 T_IF,
  44.                 T_FOREACH,
  45.                 T_ELSE,
  46.                 T_ELSEIF,
  47.                 T_SWITCH,
  48.                );
  49.  
  50.     }//end register()
  51.  
  52.  
  53.     /**
  54.      * Processes this test, when one of its tokens is encountered.
  55.      *
  56.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
  57.      * @param int                         $stackPtr  The position of the current token in the
  58.      *                                                stack passed in $tokens.
  59.      *
  60.      * @return void 
  61.      */
  62.     public function process(File $phpcsFile$stackPtr)
  63.     {
  64.         $tokens $phpcsFile->getTokens();
  65.  
  66.         if (isset($tokens[($stackPtr + 1)]=== false{
  67.             return;
  68.         }
  69.  
  70.         // Single space after the keyword.
  71.         $found = 1;
  72.         if ($tokens[($stackPtr + 1)]['code'!== T_WHITESPACE{
  73.             $found = 0;
  74.         else if ($tokens[($stackPtr + 1)]['content'!== ' '{
  75.             if (strpos($tokens[($stackPtr + 1)]['content']$phpcsFile->eolChar!== false{
  76.                 $found 'newline';
  77.             else {
  78.                 $found strlen($tokens[($stackPtr + 1)]['content']);
  79.             }
  80.         }
  81.  
  82.         if ($found !== 1{
  83.             $error 'Expected 1 space after %s keyword; %s found';
  84.             $data  = array(
  85.                       strtoupper($tokens[$stackPtr]['content']),
  86.                       $found,
  87.                      );
  88.  
  89.             $fix $phpcsFile->addFixableError($error$stackPtr'SpaceAfterKeyword'$data);
  90.             if ($fix === true{
  91.                 if ($found === 0{
  92.                     $phpcsFile->fixer->addContent($stackPtr' ');
  93.                 else {
  94.                     $phpcsFile->fixer->replaceToken(($stackPtr + 1)' ');
  95.                 }
  96.             }
  97.         }
  98.  
  99.         // Single space after closing parenthesis.
  100.         if (isset($tokens[$stackPtr]['parenthesis_closer']=== true
  101.             && isset($tokens[$stackPtr]['scope_opener']=== true
  102.         {
  103.             $closer  $tokens[$stackPtr]['parenthesis_closer'];
  104.             $opener  $tokens[$stackPtr]['scope_opener'];
  105.             $content $phpcsFile->getTokensAsString(($closer + 1)($opener $closer - 1));
  106.  
  107.             if ($content !== ' '{
  108.                 $error 'Expected 1 space after closing parenthesis; found %s';
  109.                 if ($tokens[$closer]['line'!== $tokens[$opener]['line']{
  110.                     $found 'newline';
  111.                 else if (trim($content=== ''{
  112.                     $found strlen($content);
  113.                 else {
  114.                     $found '"'.str_replace($phpcsFile->eolChar'\n'$content).'"';
  115.                 }
  116.  
  117.                 $fix $phpcsFile->addFixableError($error$closer'SpaceAfterCloseParenthesis'array($found));
  118.                 if ($fix === true{
  119.                     if ($closer === ($opener - 1)) {
  120.                         $phpcsFile->fixer->addContent($closer' ');
  121.                     else {
  122.                         $phpcsFile->fixer->beginChangeset();
  123.                         if (trim($content=== ''{
  124.                             $phpcsFile->fixer->addContent($closer' ');
  125.                             if ($found !== 0{
  126.                                 for ($i ($closer + 1)$i $opener$i++{
  127.                                     $phpcsFile->fixer->replaceToken($i'');
  128.                                 }
  129.                             }
  130.                         else {
  131.                             $phpcsFile->fixer->addContent($closer' '.$tokens[$opener]['content']);
  132.                             $phpcsFile->fixer->replaceToken($opener'');
  133.  
  134.                             if ($tokens[$opener]['line'!== $tokens[$closer]['line']{
  135.                                 $next $phpcsFile->findNext(T_WHITESPACE($opener + 1)nulltrue);
  136.                                 if ($tokens[$next]['line'!== $tokens[$opener]['line']{
  137.                                     for ($i ($opener + 1)$i $next$i++{
  138.                                         $phpcsFile->fixer->replaceToken($i'');
  139.                                     }
  140.                                 }
  141.                             }
  142.                         }
  143.  
  144.                         $phpcsFile->fixer->endChangeset();
  145.                     }//end if
  146.                 }//end if
  147.             }//end if
  148.         }//end if
  149.  
  150.         // Single newline after opening brace.
  151.         if (isset($tokens[$stackPtr]['scope_opener']=== true{
  152.             $opener $tokens[$stackPtr]['scope_opener'];
  153.             for ($next ($opener + 1)$next $phpcsFile->numTokens; $next++{
  154.                 $code $tokens[$next]['code'];
  155.  
  156.                 if ($code === T_WHITESPACE
  157.                     || ($code === T_INLINE_HTML
  158.                     && trim($tokens[$next]['content']=== '')
  159.                 {
  160.                     continue;
  161.                 }
  162.  
  163.                 // Skip all empty tokens on the same line as the opener.
  164.                 if ($tokens[$next]['line'=== $tokens[$opener]['line']
  165.                     && (isset(Tokens::$emptyTokens[$code]=== true
  166.                     || $code === T_CLOSE_TAG)
  167.                 {
  168.                     continue;
  169.                 }
  170.  
  171.                 // We found the first bit of a code, or a comment on the
  172.                 // following line.
  173.                 break;
  174.             }//end for
  175.  
  176.             if ($tokens[$next]['line'=== $tokens[$opener]['line']{
  177.                 $error 'Newline required after opening brace';
  178.                 $fix   $phpcsFile->addFixableError($error$opener'NewlineAfterOpenBrace');
  179.                 if ($fix === true{
  180.                     $phpcsFile->fixer->beginChangeset();
  181.                     for ($i ($opener + 1)$i $next$i++{
  182.                         if (trim($tokens[$i]['content']!== ''{
  183.                             break;
  184.                         }
  185.  
  186.                         // Remove whitespace.
  187.                         $phpcsFile->fixer->replaceToken($i'');
  188.                     }
  189.  
  190.                     $phpcsFile->fixer->addContent($opener$phpcsFile->eolChar);
  191.                     $phpcsFile->fixer->endChangeset();
  192.                 }
  193.             }//end if
  194.         else if ($tokens[$stackPtr]['code'=== T_WHILE{
  195.             // Zero spaces after parenthesis closer.
  196.             $closer $tokens[$stackPtr]['parenthesis_closer'];
  197.             $found  = 0;
  198.             if ($tokens[($closer + 1)]['code'=== T_WHITESPACE{
  199.                 if (strpos($tokens[($closer + 1)]['content']$phpcsFile->eolChar!== false{
  200.                     $found 'newline';
  201.                 else {
  202.                     $found strlen($tokens[($closer + 1)]['content']);
  203.                 }
  204.             }
  205.  
  206.             if ($found !== 0{
  207.                 $error 'Expected 0 spaces before semicolon; %s found';
  208.                 $data  = array($found);
  209.                 $fix   $phpcsFile->addFixableError($error$closer'SpaceBeforeSemicolon'$data);
  210.                 if ($fix === true{
  211.                     $phpcsFile->fixer->replaceToken(($closer + 1)'');
  212.                 }
  213.             }
  214.         }//end if
  215.  
  216.         // Only want to check multi-keyword structures from here on.
  217.         if ($tokens[$stackPtr]['code'=== T_DO{
  218.             if (isset($tokens[$stackPtr]['scope_closer']=== false{
  219.                 return;
  220.             }
  221.  
  222.             $closer $tokens[$stackPtr]['scope_closer'];
  223.         else if ($tokens[$stackPtr]['code'=== T_ELSE
  224.             || $tokens[$stackPtr]['code'=== T_ELSEIF
  225.             || $tokens[$stackPtr]['code'=== T_CATCH
  226.         {
  227.             if (isset($tokens[$stackPtr]['scope_opener']=== true
  228.                 && $tokens[$tokens[$stackPtr]['scope_opener']]['code'=== T_COLON
  229.             {
  230.                 // Special case for alternate syntax, where this token is actually
  231.                 // the closer for the previous block, so there is no spacing to check.
  232.                 return;
  233.             }
  234.  
  235.             $closer $phpcsFile->findPrevious(Tokens::$emptyTokens($stackPtr - 1)nulltrue);
  236.             if ($closer === false || $tokens[$closer]['code'!== T_CLOSE_CURLY_BRACKET{
  237.                 return;
  238.             }
  239.         else {
  240.             return;
  241.         }//end if
  242.  
  243.         // Single space after closing brace.
  244.         $found = 1;
  245.         if ($tokens[($closer + 1)]['code'!== T_WHITESPACE{
  246.             $found = 0;
  247.         else if ($tokens[($closer + 1)]['content'!== ' '{
  248.             if (strpos($tokens[($closer + 1)]['content']$phpcsFile->eolChar!== false{
  249.                 $found 'newline';
  250.             else {
  251.                 $found strlen($tokens[($closer + 1)]['content']);
  252.             }
  253.         }
  254.  
  255.         if ($found !== 1{
  256.             $error 'Expected 1 space after closing brace; %s found';
  257.             $data  = array($found);
  258.             $fix   $phpcsFile->addFixableError($error$closer'SpaceAfterCloseBrace'$data);
  259.             if ($fix === true{
  260.                 if ($found === 0{
  261.                     $phpcsFile->fixer->addContent($closer' ');
  262.                 else {
  263.                     $phpcsFile->fixer->replaceToken(($closer + 1)' ');
  264.                 }
  265.             }
  266.         }
  267.  
  268.     }//end process()
  269.  
  270.  
  271. }//end class

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