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

Source for file FunctionSpacingSniff.php

Documentation is available at FunctionSpacingSniff.php

  1. <?php
  2. /**
  3.  * Checks the separation between methods in a class or interface.
  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\WhiteSpace;
  11.  
  12. use PHP_CodeSniffer\Sniffs\Sniff;
  13. use PHP_CodeSniffer\Files\File;
  14.  
  15. class FunctionSpacingSniff implements Sniff
  16. {
  17.  
  18.     /**
  19.      * The number of blank lines between functions.
  20.      *
  21.      * @var integer 
  22.      */
  23.     public $spacing = 2;
  24.  
  25.  
  26.     /**
  27.      * Returns an array of tokens this test wants to listen for.
  28.      *
  29.      * @return array 
  30.      */
  31.     public function register()
  32.     {
  33.         return array(T_FUNCTION);
  34.  
  35.     }//end register()
  36.  
  37.  
  38.     /**
  39.      * Processes this sniff when one of its tokens is encountered.
  40.      *
  41.      * @param \PHP_CodeSniffer\Files\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.         $this->spacing = (int) $this->spacing;
  51.  
  52.         /*
  53.             Check the number of blank lines
  54.             after the function.
  55.         */
  56.  
  57.         if (isset($tokens[$stackPtr]['scope_closer']=== false{
  58.             // Must be an interface method, so the closer is the semicolon.
  59.             $closer $phpcsFile->findNext(T_SEMICOLON$stackPtr);
  60.         else {
  61.             $closer $tokens[$stackPtr]['scope_closer'];
  62.         }
  63.  
  64.         // Allow for comments on the same line as the closer.
  65.         for ($nextLineToken ($closer + 1)$nextLineToken $phpcsFile->numTokens; $nextLineToken++{
  66.             if ($tokens[$nextLineToken]['line'!== $tokens[$closer]['line']{
  67.                 break;
  68.             }
  69.         }
  70.  
  71.         $foundLines = 0;
  72.         if ($nextLineToken === ($phpcsFile->numTokens - 1)) {
  73.             // We are at the end of the file.
  74.             // Don't check spacing after the function because this
  75.             // should be done by an EOF sniff.
  76.             $foundLines $this->spacing;
  77.         else {
  78.             $nextContent $phpcsFile->findNext(T_WHITESPACE$nextLineTokennulltrue);
  79.             if ($nextContent === false{
  80.                 // We are at the end of the file.
  81.                 // Don't check spacing after the function because this
  82.                 // should be done by an EOF sniff.
  83.                 $foundLines $this->spacing;
  84.             else {
  85.                 $foundLines += ($tokens[$nextContent]['line'$tokens[$nextLineToken]['line']);
  86.             }
  87.         }
  88.  
  89.         if ($foundLines !== $this->spacing{
  90.             $error 'Expected %s blank line';
  91.             if ($this->spacing !== 1{
  92.                 $error .= 's';
  93.             }
  94.  
  95.             $error .= ' after function; %s found';
  96.             $data   = array(
  97.                        $this->spacing,
  98.                        $foundLines,
  99.                       );
  100.  
  101.             $fix $phpcsFile->addFixableError($error$closer'After'$data);
  102.             if ($fix === true{
  103.                 $phpcsFile->fixer->beginChangeset();
  104.                 for ($i $nextLineToken$i <= $nextContent$i++{
  105.                     if ($tokens[$i]['line'=== $tokens[$nextContent]['line']{
  106.                         $phpcsFile->fixer->addContentBefore($istr_repeat($phpcsFile->eolChar$this->spacing));
  107.                         break;
  108.                     }
  109.  
  110.                     $phpcsFile->fixer->replaceToken($i'');
  111.                 }
  112.  
  113.                 $phpcsFile->fixer->endChangeset();
  114.             }//end if
  115.         }//end if
  116.  
  117.         /*
  118.             Check the number of blank lines
  119.             before the function.
  120.         */
  121.  
  122.         $prevLineToken = null;
  123.         for ($i $stackPtr$i > 0; $i--{
  124.             if (strpos($tokens[$i]['content']$phpcsFile->eolChar=== false{
  125.                 continue;
  126.             else {
  127.                 $prevLineToken $i;
  128.                 break;
  129.             }
  130.         }
  131.  
  132.         if (is_null($prevLineToken=== true{
  133.             // Never found the previous line, which means
  134.             // there are 0 blank lines before the function.
  135.             $foundLines  = 0;
  136.             $prevContent = 0;
  137.         else {
  138.             $currentLine $tokens[$stackPtr]['line'];
  139.  
  140.             $prevContent $phpcsFile->findPrevious(T_WHITESPACE$prevLineTokennulltrue);
  141.             if ($tokens[$prevContent]['code'=== T_COMMENT{
  142.                 // Ignore comments as they can have different spacing rules, and this
  143.                 // isn't a proper function comment anyway.
  144.                 return;
  145.             }
  146.  
  147.             if ($tokens[$prevContent]['code'=== T_DOC_COMMENT_CLOSE_TAG
  148.                 && $tokens[$prevContent]['line'=== ($currentLine - 1)
  149.             {
  150.                 // Account for function comments.
  151.                 $prevContent $phpcsFile->findPrevious(T_WHITESPACE($tokens[$prevContent]['comment_opener'- 1)nulltrue);
  152.             }
  153.  
  154.             // Before we throw an error, check that we are not throwing an error
  155.             // for another function. We don't want to error for no blank lines after
  156.             // the previous function and no blank lines before this one as well.
  157.             $prevLine   ($tokens[$prevContent]['line'- 1);
  158.             $i          ($stackPtr - 1);
  159.             $foundLines = 0;
  160.             while ($currentLine !== $prevLine && $currentLine > 1 && $i > 0{
  161.                 if (isset($tokens[$i]['scope_condition']=== true{
  162.                     $scopeCondition $tokens[$i]['scope_condition'];
  163.                     if ($tokens[$scopeCondition]['code'=== T_FUNCTION{
  164.                         // Found a previous function.
  165.                         return;
  166.                     }
  167.                 else if ($tokens[$i]['code'=== T_FUNCTION{
  168.                     // Found another interface function.
  169.                     return;
  170.                 }
  171.  
  172.                 $currentLine $tokens[$i]['line'];
  173.                 if ($currentLine === $prevLine{
  174.                     break;
  175.                 }
  176.  
  177.                 if ($tokens[($i - 1)]['line'$currentLine && $tokens[($i + 1)]['line'$currentLine{
  178.                     // This token is on a line by itself. If it is whitespace, the line is empty.
  179.                     if ($tokens[$i]['code'=== T_WHITESPACE{
  180.                         $foundLines++;
  181.                     }
  182.                 }
  183.  
  184.                 $i--;
  185.             }//end while
  186.         }//end if
  187.  
  188.         if ($foundLines !== $this->spacing{
  189.             $error 'Expected %s blank line';
  190.             if ($this->spacing !== 1{
  191.                 $error .= 's';
  192.             }
  193.  
  194.             $error .= ' before function; %s found';
  195.             $data   = array(
  196.                        $this->spacing,
  197.                        $foundLines,
  198.                       );
  199.  
  200.             $fix $phpcsFile->addFixableError($error$stackPtr'Before'$data);
  201.             if ($fix === true{
  202.                 if ($prevContent === 0{
  203.                     $nextSpace = 0;
  204.                 else {
  205.                     $nextSpace $phpcsFile->findNext(T_WHITESPACE($prevContent + 1)$stackPtr);
  206.                     if ($nextSpace === false{
  207.                         $nextSpace ($stackPtr - 1);
  208.                     }
  209.                 }
  210.  
  211.                 if ($foundLines $this->spacing{
  212.                     $padding str_repeat($phpcsFile->eolChar($this->spacing $foundLines));
  213.                     $phpcsFile->fixer->addContent($nextSpace$padding);
  214.                 else {
  215.                     $nextContent $phpcsFile->findNext(T_WHITESPACE($nextSpace + 1)nulltrue);
  216.                     $phpcsFile->fixer->beginChangeset();
  217.                     for ($i $nextSpace$i ($nextContent - 1)$i++{
  218.                         $phpcsFile->fixer->replaceToken($i'');
  219.                     }
  220.  
  221.                     $phpcsFile->fixer->replaceToken($istr_repeat($phpcsFile->eolChar$this->spacing));
  222.                     $phpcsFile->fixer->endChangeset();
  223.                 }
  224.             }//end if
  225.         }//end if
  226.  
  227.     }//end process()
  228.  
  229.  
  230. }//end class

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