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

Source for file FunctionDeclarationArgumentSpacingSniff.php

Documentation is available at FunctionDeclarationArgumentSpacingSniff.php

  1. <?php
  2. /**
  3.  * Checks that arguments in function declarations are spaced correctly.
  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\Functions;
  11.  
  12. use PHP_CodeSniffer\Sniffs\Sniff;
  13. use PHP_CodeSniffer\Files\File;
  14.  
  15. class FunctionDeclarationArgumentSpacingSniff implements Sniff
  16. {
  17.  
  18.     /**
  19.      * How many spaces should surround the equals signs.
  20.      *
  21.      * @var integer 
  22.      */
  23.     public $equalsSpacing = 0;
  24.  
  25.     /**
  26.      * How many spaces should follow the opening bracket.
  27.      *
  28.      * @var integer 
  29.      */
  30.     public $requiredSpacesAfterOpen = 0;
  31.  
  32.     /**
  33.      * How many spaces should precede the closing bracket.
  34.      *
  35.      * @var integer 
  36.      */
  37.     public $requiredSpacesBeforeClose = 0;
  38.  
  39.  
  40.     /**
  41.      * Returns an array of tokens this test wants to listen for.
  42.      *
  43.      * @return array 
  44.      */
  45.     public function register()
  46.     {
  47.         return array(
  48.                 T_FUNCTION,
  49.                 T_CLOSURE,
  50.                );
  51.  
  52.     }//end register()
  53.  
  54.  
  55.     /**
  56.      * Processes this test, when one of its tokens is encountered.
  57.      *
  58.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
  59.      * @param int                         $stackPtr  The position of the current token in the
  60.      *                                                stack passed in $tokens.
  61.      *
  62.      * @return void 
  63.      */
  64.     public function process(File $phpcsFile$stackPtr)
  65.     {
  66.         $tokens $phpcsFile->getTokens();
  67.  
  68.         if (isset($tokens[$stackPtr]['parenthesis_opener']=== false
  69.             || isset($tokens[$stackPtr]['parenthesis_closer']=== false
  70.             || $tokens[$stackPtr]['parenthesis_opener'=== null
  71.             || $tokens[$stackPtr]['parenthesis_closer'=== null
  72.         {
  73.             return;
  74.         }
  75.  
  76.         $this->equalsSpacing           = (int) $this->equalsSpacing;
  77.         $this->requiredSpacesAfterOpen = (int) $this->requiredSpacesAfterOpen;
  78.         $this->requiredSpacesBeforeClose = (int) $this->requiredSpacesBeforeClose;
  79.  
  80.         $openBracket $tokens[$stackPtr]['parenthesis_opener'];
  81.         $this->processBracket($phpcsFile$openBracket);
  82.  
  83.         if ($tokens[$stackPtr]['code'=== T_CLOSURE{
  84.             $use $phpcsFile->findNext(T_USE($tokens[$openBracket]['parenthesis_closer'+ 1)$tokens[$stackPtr]['scope_opener']);
  85.             if ($use !== false{
  86.                 $openBracket $phpcsFile->findNext(T_OPEN_PARENTHESIS($use + 1)null);
  87.                 $this->processBracket($phpcsFile$openBracket);
  88.             }
  89.         }
  90.  
  91.     }//end process()
  92.  
  93.  
  94.     /**
  95.      * Processes the contents of a single set of brackets.
  96.      *
  97.      * @param \PHP_CodeSniffer\Files\File $phpcsFile   The file being scanned.
  98.      * @param int                         $openBracket The position of the open bracket
  99.      *                                                  in the stack passed in $tokens.
  100.      *
  101.      * @return void 
  102.      */
  103.     public function processBracket($phpcsFile$openBracket)
  104.     {
  105.         $tokens       $phpcsFile->getTokens();
  106.         $closeBracket $tokens[$openBracket]['parenthesis_closer'];
  107.         $multiLine    ($tokens[$openBracket]['line'!== $tokens[$closeBracket]['line']);
  108.  
  109.         $nextParam $openBracket;
  110.         $params    = array();
  111.         while (($nextParam $phpcsFile->findNext(T_VARIABLE($nextParam + 1)$closeBracket)) !== false{
  112.             $nextToken $phpcsFile->findNext(T_WHITESPACE($nextParam + 1)($closeBracket + 1)true);
  113.             if ($nextToken === false{
  114.                 break;
  115.             }
  116.  
  117.             $nextCode $tokens[$nextToken]['code'];
  118.  
  119.             if ($nextCode === T_EQUAL{
  120.                 // Check parameter default spacing.
  121.                 $spacesBefore = 0;
  122.                 if (($nextToken $nextParam> 1{
  123.                     $spacesBefore strlen($tokens[($nextParam + 1)]['content']);
  124.                 }
  125.  
  126.                 if ($spacesBefore !== $this->equalsSpacing{
  127.                     $error 'Incorrect spacing between argument "%s" and equals sign; expected '.$this->equalsSpacing.' but found %s';
  128.                     $data  = array(
  129.                               $tokens[$nextParam]['content'],
  130.                               $spacesBefore,
  131.                              );
  132.  
  133.                     $fix $phpcsFile->addFixableError($error$nextToken'SpaceBeforeEquals'$data);
  134.                     if ($fix === true{
  135.                         $padding str_repeat(' '$this->equalsSpacing);
  136.                         if ($spacesBefore === 0{
  137.                             $phpcsFile->fixer->addContentBefore($nextToken$padding);
  138.                         else {
  139.                             $phpcsFile->fixer->replaceToken(($nextToken - 1)$padding);
  140.                         }
  141.                     }
  142.                 }//end if
  143.  
  144.                 $spacesAfter = 0;
  145.                 if ($tokens[($nextToken + 1)]['code'=== T_WHITESPACE{
  146.                     $spacesAfter strlen($tokens[($nextToken + 1)]['content']);
  147.                 }
  148.  
  149.                 if ($spacesAfter !== $this->equalsSpacing{
  150.                     $error 'Incorrect spacing between default value and equals sign for argument "%s"; expected '.$this->equalsSpacing.' but found %s';
  151.                     $data  = array(
  152.                               $tokens[$nextParam]['content'],
  153.                               $spacesAfter,
  154.                              );
  155.  
  156.                     $fix $phpcsFile->addFixableError($error$nextToken'SpaceAfterDefault'$data);
  157.                     if ($fix === true{
  158.                         $padding str_repeat(' '$this->equalsSpacing);
  159.                         if ($spacesAfter === 0{
  160.                             $phpcsFile->fixer->addContent($nextToken$padding);
  161.                         else {
  162.                             $phpcsFile->fixer->replaceToken(($nextToken + 1)$padding);
  163.                         }
  164.                     }
  165.                 }//end if
  166.             }//end if
  167.  
  168.             // Find and check the comma (if there is one).
  169.             $nextComma $phpcsFile->findNext(T_COMMA($nextParam + 1)$closeBracket);
  170.             if ($nextComma !== false{
  171.                 // Comma found.
  172.                 if ($tokens[($nextComma - 1)]['code'=== T_WHITESPACE{
  173.                     $error 'Expected 0 spaces between argument "%s" and comma; %s found';
  174.                     $data  = array(
  175.                               $tokens[$nextParam]['content'],
  176.                               strlen($tokens[($nextComma - 1)]['content']),
  177.                              );
  178.  
  179.                     $fix $phpcsFile->addFixableError($error$nextToken'SpaceBeforeComma'$data);
  180.                     if ($fix === true{
  181.                         $phpcsFile->fixer->replaceToken(($nextComma - 1)'');
  182.                     }
  183.                 }
  184.             }
  185.  
  186.             $checkToken ($nextParam - 1);
  187.             $prev       $phpcsFile->findPrevious(T_WHITESPACE$checkTokennulltrue);
  188.             if ($tokens[$prev]['code'=== T_ELLIPSIS{
  189.                 $checkToken ($prev - 1);
  190.             }
  191.  
  192.             // Take references into account when expecting the
  193.             // location of whitespace.
  194.             if ($phpcsFile->isReference($checkToken=== true{
  195.                 $whitespace ($checkToken - 1);
  196.             else {
  197.                 $whitespace $checkToken;
  198.             }
  199.  
  200.             if (empty($params=== false{
  201.                 // This is not the first argument in the function declaration.
  202.                 $arg $tokens[$nextParam]['content'];
  203.  
  204.                 // Before we throw an error, make sure there is no type hint.
  205.                 $comma     $phpcsFile->findPrevious(T_COMMA($nextParam - 1));
  206.                 $nextToken $phpcsFile->findNext(T_WHITESPACE($comma + 1)nulltrue);
  207.                 if ($phpcsFile->isReference($nextToken=== true{
  208.                     $nextToken++;
  209.                 }
  210.  
  211.                 $gap = 0;
  212.                 if ($tokens[$whitespace]['code'=== T_WHITESPACE{
  213.                     $gap strlen($tokens[$whitespace]['content']);
  214.                 }
  215.  
  216.                 if ($nextToken !== $nextParam{
  217.                     // There was a type hint, so check the spacing between
  218.                     // the hint and the variable as well.
  219.                     $hint $tokens[$nextToken]['content'];
  220.  
  221.                     if ($gap !== 1{
  222.                         $error 'Expected 1 space between type hint and argument "%s"; %s found';
  223.                         $data  = array(
  224.                                   $arg,
  225.                                   $gap,
  226.                                  );
  227.                         $fix   $phpcsFile->addFixableError($error$nextToken'SpacingAfterHint'$data);
  228.                         if ($fix === true{
  229.                             if ($gap === 0{
  230.                                 $phpcsFile->fixer->addContent($whitespace' ');
  231.                             else {
  232.                                 $phpcsFile->fixer->replaceToken($whitespace' ');
  233.                             }
  234.                         }
  235.                     }
  236.  
  237.                     if ($multiLine === false{
  238.                         if ($tokens[($comma + 1)]['code'!== T_WHITESPACE{
  239.                             $error 'Expected 1 space between comma and type hint "%s"; 0 found';
  240.                             $data  = array($hint);
  241.                             $fix   $phpcsFile->addFixableError($error$nextToken'NoSpaceBeforeHint'$data);
  242.                             if ($fix === true{
  243.                                 $phpcsFile->fixer->addContent($comma' ');
  244.                             }
  245.                         else {
  246.                             $gap strlen($tokens[($comma + 1)]['content']);
  247.                             if ($gap !== 1{
  248.                                 $error 'Expected 1 space between comma and type hint "%s"; %s found';
  249.                                 $data  = array(
  250.                                           $hint,
  251.                                           $gap,
  252.                                          );
  253.                                 $fix   $phpcsFile->addFixableError($error$nextToken'SpacingBeforeHint'$data);
  254.                                 if ($fix === true{
  255.                                     $phpcsFile->fixer->replaceToken(($comma + 1)' ');
  256.                                 }
  257.                             }
  258.                         }//end if
  259.                     }//end if
  260.                 else {
  261.                     // No type hint.
  262.                     if ($gap === 0{
  263.                         $error 'Expected 1 space between comma and argument "%s"; 0 found';
  264.                         $data  = array($arg);
  265.                         $fix   $phpcsFile->addFixableError($error$nextToken'NoSpaceBeforeArg'$data);
  266.                         if ($fix === true{
  267.                             $phpcsFile->fixer->addContent($whitespace' ');
  268.                         }
  269.                     else if ($gap !== 1{
  270.                         // Just make sure this is not actually an indent.
  271.                         if ($tokens[$whitespace]['line'=== $tokens[($whitespace - 1)]['line']{
  272.                             $error 'Expected 1 space between comma and argument "%s"; %s found';
  273.                             $data  = array(
  274.                                       $arg,
  275.                                       $gap,
  276.                                      );
  277.  
  278.                             $fix $phpcsFile->addFixableError($error$nextToken'SpacingBeforeArg'$data);
  279.                             if ($fix === true{
  280.                                 $phpcsFile->fixer->replaceToken($whitespace' ');
  281.                             }
  282.                         }
  283.                     }//end if
  284.                 }//end if
  285.             else {
  286.                 $gap = 0;
  287.                 if ($tokens[$whitespace]['code'=== T_WHITESPACE{
  288.                     $gap strlen($tokens[$whitespace]['content']);
  289.                 }
  290.  
  291.                 $arg $tokens[$nextParam]['content'];
  292.  
  293.                 // Before we throw an error, make sure there is no type hint.
  294.                 $bracket   $phpcsFile->findPrevious(T_OPEN_PARENTHESIS($nextParam - 1));
  295.                 $nextToken $phpcsFile->findNext(T_WHITESPACE($bracket + 1)nulltrue);
  296.                 if ($phpcsFile->isReference($nextToken=== true{
  297.                     $nextToken++;
  298.                 }
  299.  
  300.                 if ($tokens[$nextToken]['code'!== T_ELLIPSIS && $nextToken !== $nextParam{
  301.                     // There was a type hint, so check the spacing between
  302.                     // the hint and the variable as well.
  303.                     $hint $tokens[$nextToken]['content'];
  304.  
  305.                     if ($gap !== 1{
  306.                         $error 'Expected 1 space between type hint and argument "%s"; %s found';
  307.                         $data  = array(
  308.                                   $arg,
  309.                                   $gap,
  310.                                  );
  311.                         $fix   $phpcsFile->addFixableError($error$nextToken'SpacingAfterHint'$data);
  312.                         if ($fix === true{
  313.                             if ($gap === 0{
  314.                                 $phpcsFile->fixer->addContent($nextToken' ');
  315.                             else {
  316.                                 $phpcsFile->fixer->replaceToken(($nextToken + 1)' ');
  317.                             }
  318.                         }
  319.                     }
  320.  
  321.                     $spaceAfterOpen = 0;
  322.                     if ($tokens[($bracket + 1)]['code'=== T_WHITESPACE{
  323.                         $spaceAfterOpen strlen($tokens[($bracket + 1)]['content']);
  324.                     }
  325.  
  326.                     if ($multiLine === false && $spaceAfterOpen !== $this->requiredSpacesAfterOpen{
  327.                         $error 'Expected %s spaces between opening bracket and type hint "%s"; %s found';
  328.                         $data  = array(
  329.                                   $this->requiredSpacesAfterOpen,
  330.                                   $hint,
  331.                                   $spaceAfterOpen,
  332.                                  );
  333.                         $fix   $phpcsFile->addFixableError($error$nextToken'SpacingAfterOpenHint'$data);
  334.                         if ($fix === true{
  335.                             $padding str_repeat(' '$this->requiredSpacesAfterOpen);
  336.                             if ($spaceAfterOpen === 0{
  337.                                 $phpcsFile->fixer->addContent($openBracket$padding);
  338.                             else {
  339.                                 $phpcsFile->fixer->replaceToken(($openBracket + 1)$padding);
  340.                             }
  341.                         }
  342.                     }
  343.                 else if ($multiLine === false && $gap !== $this->requiredSpacesAfterOpen{
  344.                     $error 'Expected %s spaces between opening bracket and argument "%s"; %s found';
  345.                     $data  = array(
  346.                               $this->requiredSpacesAfterOpen,
  347.                               $arg,
  348.                               $gap,
  349.                              );
  350.                     $fix   $phpcsFile->addFixableError($error$nextToken'SpacingAfterOpen'$data);
  351.                     if ($fix === true{
  352.                         $padding str_repeat(' '$this->requiredSpacesAfterOpen);
  353.                         if ($gap === 0{
  354.                             $phpcsFile->fixer->addContent($openBracket$padding);
  355.                         else {
  356.                             $phpcsFile->fixer->replaceToken(($openBracket + 1)$padding);
  357.                         }
  358.                     }
  359.                 }//end if
  360.             }//end if
  361.  
  362.             $params[$nextParam;
  363.         }//end while
  364.  
  365.         $gap = 0;
  366.         if ($tokens[($closeBracket - 1)]['code'=== T_WHITESPACE{
  367.             $gap strlen($tokens[($closeBracket - 1)]['content']);
  368.         }
  369.  
  370.         if (empty($params=== true{
  371.             // There are no parameters for this function.
  372.             if (($closeBracket $openBracket!== 1{
  373.                 $error 'Expected 0 spaces between brackets of function declaration; %s found';
  374.                 $data  = array($gap);
  375.                 $fix   $phpcsFile->addFixableError($error$openBracket'SpacingBetween'$data);
  376.                 if ($fix === true{
  377.                     $phpcsFile->fixer->replaceToken(($openBracket + 1)'');
  378.                 }
  379.             }
  380.         else if ($multiLine === false && $gap !== $this->requiredSpacesBeforeClose{
  381.             $lastParam array_pop($params);
  382.             $error     'Expected %s spaces between argument "%s" and closing bracket; %s found';
  383.             $data      = array(
  384.                           $this->requiredSpacesBeforeClose,
  385.                           $tokens[$lastParam]['content'],
  386.                           $gap,
  387.                          );
  388.             $fix       $phpcsFile->addFixableError($error$closeBracket'SpacingBeforeClose'$data);
  389.             if ($fix === true{
  390.                 $padding str_repeat(' '$this->requiredSpacesBeforeClose);
  391.                 if ($gap === 0{
  392.                     $phpcsFile->fixer->addContentBefore($closeBracket$padding);
  393.                 else {
  394.                     $phpcsFile->fixer->replaceToken(($closeBracket - 1)$padding);
  395.                 }
  396.             }
  397.         }//end if
  398.  
  399.     }//end processBracket()
  400.  
  401.  
  402. }//end class

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