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_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_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.             // Take references into account when expecting the
  187.             // location of whitespace.
  188.             $checkToken ($nextParam - 1);
  189.             if ($tokens[$checkToken]['code'=== T_ELLIPSIS{
  190.                 $checkToken--;
  191.             }
  192.  
  193.             if ($phpcsFile->isReference($checkToken=== true{
  194.                 $whitespace ($checkToken - 1);
  195.             else {
  196.                 $whitespace $checkToken;
  197.             }
  198.  
  199.             if (empty($params=== false{
  200.                 // This is not the first argument in the function declaration.
  201.                 $arg $tokens[$nextParam]['content'];
  202.  
  203.                 // Before we throw an error, make sure there is no type hint.
  204.                 $comma     $phpcsFile->findPrevious(T_COMMA($nextParam - 1));
  205.                 $nextToken $phpcsFile->findNext(T_WHITESPACE($comma + 1)nulltrue);
  206.                 if ($phpcsFile->isReference($nextToken=== true{
  207.                     $nextToken++;
  208.                 }
  209.  
  210.                 $gap = 0;
  211.                 if ($tokens[$whitespace]['code'=== T_WHITESPACE{
  212.                     $gap strlen($tokens[$whitespace]['content']);
  213.                 }
  214.  
  215.                 if ($nextToken !== $nextParam{
  216.                     // There was a type hint, so check the spacing between
  217.                     // the hint and the variable as well.
  218.                     $hint $tokens[$nextToken]['content'];
  219.  
  220.                     if ($gap !== 1{
  221.                         $error 'Expected 1 space between type hint and argument "%s"; %s found';
  222.                         $data  = array(
  223.                                   $arg,
  224.                                   $gap,
  225.                                  );
  226.                         $fix   $phpcsFile->addFixableError($error$nextToken'SpacingAfterHint'$data);
  227.                         if ($fix === true{
  228.                             if ($gap === 0{
  229.                                 $phpcsFile->fixer->addContent($whitespace' ');
  230.                             else {
  231.                                 $phpcsFile->fixer->replaceToken($whitespace' ');
  232.                             }
  233.                         }
  234.                     }
  235.  
  236.                     if ($multiLine === false{
  237.                         if ($tokens[($comma + 1)]['code'!== T_WHITESPACE{
  238.                             $error 'Expected 1 space between comma and type hint "%s"; 0 found';
  239.                             $data  = array($hint);
  240.                             $fix   $phpcsFile->addFixableError($error$nextToken'NoSpaceBeforeHint'$data);
  241.                             if ($fix === true{
  242.                                 $phpcsFile->fixer->addContent($comma' ');
  243.                             }
  244.                         else {
  245.                             $gap strlen($tokens[($comma + 1)]['content']);
  246.                             if ($gap !== 1{
  247.                                 $error 'Expected 1 space between comma and type hint "%s"; %s found';
  248.                                 $data  = array(
  249.                                           $hint,
  250.                                           $gap,
  251.                                          );
  252.                                 $fix   $phpcsFile->addFixableError($error$nextToken'SpacingBeforeHint'$data);
  253.                                 if ($fix === true{
  254.                                     $phpcsFile->fixer->replaceToken(($comma + 1)' ');
  255.                                 }
  256.                             }
  257.                         }//end if
  258.                     }//end if
  259.                 else {
  260.                     // No type hint.
  261.                     if ($gap === 0{
  262.                         $error 'Expected 1 space between comma and argument "%s"; 0 found';
  263.                         $data  = array($arg);
  264.                         $fix   $phpcsFile->addFixableError($error$nextToken'NoSpaceBeforeArg'$data);
  265.                         if ($fix === true{
  266.                             $phpcsFile->fixer->addContent($whitespace' ');
  267.                         }
  268.                     else if ($gap !== 1{
  269.                         // Just make sure this is not actually an indent.
  270.                         if ($tokens[$whitespace]['line'=== $tokens[($whitespace - 1)]['line']{
  271.                             $error 'Expected 1 space between comma and argument "%s"; %s found';
  272.                             $data  = array(
  273.                                       $arg,
  274.                                       $gap,
  275.                                      );
  276.  
  277.                             $fix $phpcsFile->addFixableError($error$nextToken'SpacingBeforeArg'$data);
  278.                             if ($fix === true{
  279.                                 $phpcsFile->fixer->replaceToken($whitespace' ');
  280.                             }
  281.                         }
  282.                     }//end if
  283.                 }//end if
  284.             else {
  285.                 $gap = 0;
  286.                 if ($tokens[$whitespace]['code'=== T_WHITESPACE{
  287.                     $gap strlen($tokens[$whitespace]['content']);
  288.                 }
  289.  
  290.                 $arg $tokens[$nextParam]['content'];
  291.  
  292.                 // Before we throw an error, make sure there is no type hint.
  293.                 $bracket   $phpcsFile->findPrevious(T_OPEN_PARENTHESIS($nextParam - 1));
  294.                 $nextToken $phpcsFile->findNext(T_WHITESPACE($bracket + 1)nulltrue);
  295.                 if ($phpcsFile->isReference($nextToken=== true{
  296.                     $nextToken++;
  297.                 }
  298.  
  299.                 if ($tokens[$nextToken]['code'!== T_ELLIPSIS && $nextToken !== $nextParam{
  300.                     // There was a type hint, so check the spacing between
  301.                     // the hint and the variable as well.
  302.                     $hint $tokens[$nextToken]['content'];
  303.  
  304.                     if ($gap !== 1{
  305.                         $error 'Expected 1 space between type hint and argument "%s"; %s found';
  306.                         $data  = array(
  307.                                   $arg,
  308.                                   $gap,
  309.                                  );
  310.                         $fix   $phpcsFile->addFixableError($error$nextToken'SpacingAfterHint'$data);
  311.                         if ($fix === true{
  312.                             if ($gap === 0{
  313.                                 $phpcsFile->fixer->addContent($nextToken' ');
  314.                             else {
  315.                                 $phpcsFile->fixer->replaceToken(($nextToken + 1)' ');
  316.                             }
  317.                         }
  318.                     }
  319.  
  320.                     $spaceAfterOpen = 0;
  321.                     if ($tokens[($bracket + 1)]['code'=== T_WHITESPACE{
  322.                         $spaceAfterOpen strlen($tokens[($bracket + 1)]['content']);
  323.                     }
  324.  
  325.                     if ($multiLine === false && $spaceAfterOpen !== $this->requiredSpacesAfterOpen{
  326.                         $error 'Expected %s spaces between opening bracket and type hint "%s"; %s found';
  327.                         $data  = array(
  328.                                   $this->requiredSpacesAfterOpen,
  329.                                   $hint,
  330.                                   $spaceAfterOpen,
  331.                                  );
  332.                         $fix   $phpcsFile->addFixableError($error$nextToken'SpacingAfterOpenHint'$data);
  333.                         if ($fix === true{
  334.                             $padding str_repeat(' '$this->requiredSpacesAfterOpen);
  335.                             if ($spaceAfterOpen === 0{
  336.                                 $phpcsFile->fixer->addContent($openBracket$padding);
  337.                             else {
  338.                                 $phpcsFile->fixer->replaceToken(($openBracket + 1)$padding);
  339.                             }
  340.                         }
  341.                     }
  342.                 else if ($multiLine === false && $gap !== $this->requiredSpacesAfterOpen{
  343.                     $error 'Expected %s spaces between opening bracket and argument "%s"; %s found';
  344.                     $data  = array(
  345.                               $this->requiredSpacesAfterOpen,
  346.                               $arg,
  347.                               $gap,
  348.                              );
  349.                     $fix   $phpcsFile->addFixableError($error$nextToken'SpacingAfterOpen'$data);
  350.                     if ($fix === true{
  351.                         $padding str_repeat(' '$this->requiredSpacesAfterOpen);
  352.                         if ($gap === 0{
  353.                             $phpcsFile->fixer->addContent($openBracket$padding);
  354.                         else {
  355.                             $phpcsFile->fixer->replaceToken(($openBracket + 1)$padding);
  356.                         }
  357.                     }
  358.                 }//end if
  359.             }//end if
  360.  
  361.             $params[$nextParam;
  362.         }//end while
  363.  
  364.         $gap = 0;
  365.         if ($tokens[($closeBracket - 1)]['code'=== T_WHITESPACE{
  366.             $gap strlen($tokens[($closeBracket - 1)]['content']);
  367.         }
  368.  
  369.         if (empty($params=== true{
  370.             // There are no parameters for this function.
  371.             if (($closeBracket $openBracket!== 1{
  372.                 $error 'Expected 0 spaces between brackets of function declaration; %s found';
  373.                 $data  = array($gap);
  374.                 $fix   $phpcsFile->addFixableError($error$openBracket'SpacingBetween'$data);
  375.                 if ($fix === true{
  376.                     $phpcsFile->fixer->replaceToken(($openBracket + 1)'');
  377.                 }
  378.             }
  379.         else if ($multiLine === false && $gap !== $this->requiredSpacesBeforeClose{
  380.             $lastParam array_pop($params);
  381.             $error     'Expected %s spaces between argument "%s" and closing bracket; %s found';
  382.             $data      = array(
  383.                           $this->requiredSpacesBeforeClose,
  384.                           $tokens[$lastParam]['content'],
  385.                           $gap,
  386.                          );
  387.             $fix       $phpcsFile->addFixableError($error$closeBracket'SpacingBeforeClose'$data);
  388.             if ($fix === true{
  389.                 $padding str_repeat(' '$this->requiredSpacesBeforeClose);
  390.                 if ($gap === 0{
  391.                     $phpcsFile->fixer->addContentBefore($closeBracket$padding);
  392.                 else {
  393.                     $phpcsFile->fixer->replaceToken(($closeBracket - 1)$padding);
  394.                 }
  395.             }
  396.         }//end if
  397.  
  398.     }//end processBracket()
  399.  
  400.  
  401. }//end class

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