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

Source for file UnusedFunctionParameterSniff.php

Documentation is available at UnusedFunctionParameterSniff.php

  1. <?php
  2. /**
  3.  * Checks the for unused function parameters.
  4.  *
  5.  * This sniff checks that all function parameters are used in the function body.
  6.  * One exception is made for empty function bodies or function bodies that only
  7.  * contain comments. This could be useful for the classes that implement an
  8.  * interface that defines multiple methods but the implementation only needs some
  9.  * of them.
  10.  *
  11.  * @author    Manuel Pichler <mapi@manuel-pichler.de>
  12.  * @author    Greg Sherwood <gsherwood@squiz.net>
  13.  * @copyright 2007-2014 Manuel Pichler. All rights reserved.
  14.  * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  15.  */
  16.  
  17. namespace PHP_CodeSniffer\Standards\Generic\Sniffs\CodeAnalysis;
  18.  
  19. use PHP_CodeSniffer\Sniffs\Sniff;
  20. use PHP_CodeSniffer\Files\File;
  21. use PHP_CodeSniffer\Util\Tokens;
  22.  
  23. class UnusedFunctionParameterSniff implements Sniff
  24. {
  25.  
  26.  
  27.     /**
  28.      * Returns an array of tokens this test wants to listen for.
  29.      *
  30.      * @return array 
  31.      */
  32.     public function register()
  33.     {
  34.         return array(
  35.                 T_FUNCTION,
  36.                 T_CLOSURE,
  37.                );
  38.  
  39.     }//end register()
  40.  
  41.  
  42.     /**
  43.      * Processes this test, when one of its tokens is encountered.
  44.      *
  45.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
  46.      * @param int                         $stackPtr  The position of the current token
  47.      *                                                in the stack passed in $tokens.
  48.      *
  49.      * @return void 
  50.      */
  51.     public function process(File $phpcsFile, $stackPtr)
  52.     {
  53.         $tokens = $phpcsFile->getTokens();
  54.         $token  = $tokens[$stackPtr];
  55.  
  56.         // Skip broken function declarations.
  57.         if (isset($token['scope_opener']) === false || isset($token['parenthesis_opener']) === false) {
  58.             return;
  59.         }
  60.  
  61.         $params = array();
  62.         foreach ($phpcsFile->getMethodParameters($stackPtr) as $param) {
  63.             $params[$param['name']] = $stackPtr;
  64.         }
  65.  
  66.         $next = ++$token['scope_opener'];
  67.         $end  = --$token['scope_closer'];
  68.  
  69.         $foundContent = false;
  70.         $validTokens  = array(
  71.                          T_HEREDOC              => T_HEREDOC,
  72.                          T_NOWDOC               => T_NOWDOC,
  73.                          T_END_HEREDOC          => T_END_HEREDOC,
  74.                          T_END_NOWDOC           => T_END_NOWDOC,
  75.                          T_DOUBLE_QUOTED_STRING => T_DOUBLE_QUOTED_STRING,
  76.                         );
  77.         $validTokens += Tokens::$emptyTokens;
  78.  
  79.         for (; $next <= $end; ++$next) {
  80.             $token = $tokens[$next];
  81.             $code  = $token['code'];
  82.  
  83.             // Ignorable tokens.
  84.             if (isset(Tokens::$emptyTokens[$code]) === true) {
  85.                 continue;
  86.             }
  87.  
  88.             if ($foundContent === false) {
  89.                 // A throw statement as the first content indicates an interface method.
  90.                 if ($code === T_THROW) {
  91.                     return;
  92.                 }
  93.  
  94.                 // A return statement as the first content indicates an interface method.
  95.                 if ($code === T_RETURN) {
  96.                     $tmp = $phpcsFile->findNext(Tokens::$emptyTokens, ($next + 1), null, true);
  97.                     if ($tmp === false) {
  98.                         return;
  99.                     }
  100.  
  101.                     // There is a return.
  102.                     if ($tokens[$tmp]['code'] === T_SEMICOLON) {
  103.                         return;
  104.                     }
  105.  
  106.                     $tmp = $phpcsFile->findNext(Tokens::$emptyTokens, ($tmp + 1), null, true);
  107.                     if ($tmp !== false && $tokens[$tmp]['code'] === T_SEMICOLON) {
  108.                         // There is a return <token>.
  109.                         return;
  110.                     }
  111.                 }//end if
  112.             }//end if
  113.  
  114.             $foundContent = true;
  115.  
  116.             if ($code === T_VARIABLE && isset($params[$token['content']]) === true) {
  117.                 unset($params[$token['content']]);
  118.             } else if ($code === T_DOLLAR) {
  119.                 $nextToken = $phpcsFile->findNext(T_WHITESPACE, ($next + 1), null, true);
  120.                 if ($tokens[$nextToken]['code'] === T_OPEN_CURLY_BRACKET) {
  121.                     $nextToken = $phpcsFile->findNext(T_WHITESPACE, ($nextToken + 1), null, true);
  122.                     if ($tokens[$nextToken]['code'] === T_STRING) {
  123.                         $varContent = '$'.$tokens[$nextToken]['content'];
  124.                         if (isset($params[$varContent]) === true) {
  125.                             unset($params[$varContent]);
  126.                         }
  127.                     }
  128.                 }
  129.             } else if ($code === T_DOUBLE_QUOTED_STRING
  130.                 || $code === T_START_HEREDOC
  131.                 || $code === T_START_NOWDOC
  132.             ) {
  133.                 // Tokenize strings that can contain variables.
  134.                 // Make sure the string is re-joined if it occurs over multiple lines.
  135.                 $content = $token['content'];
  136.                 for ($i = ($next + 1); $i <= $end; $i++) {
  137.                     if (isset($validTokens[$tokens[$i]['code']]) === true) {
  138.                         $content .= $tokens[$i]['content'];
  139.                         $next++;
  140.                     } else {
  141.                         break;
  142.                     }
  143.                 }
  144.  
  145.                 $stringTokens = token_get_all(sprintf('<?php %s;?>', $content));
  146.                 foreach ($stringTokens as $stringPtr => $stringToken) {
  147.                     if (is_array($stringToken) === false) {
  148.                         continue;
  149.                     }
  150.  
  151.                     $varContent = '';
  152.                     if ($stringToken[0] === T_DOLLAR_OPEN_CURLY_BRACES) {
  153.                         $varContent = '$'.$stringTokens[($stringPtr + 1)][1];
  154.                     } else if ($stringToken[0] === T_VARIABLE) {
  155.                         $varContent = $stringToken[1];
  156.                     }
  157.  
  158.                     if ($varContent !== '' && isset($params[$varContent]) === true) {
  159.                         unset($params[$varContent]);
  160.                     }
  161.                 }
  162.             }//end if
  163.         }//end for
  164.  
  165.         if ($foundContent === true && count($params) > 0) {
  166.             foreach ($params as $paramName => $position) {
  167.                 $error = 'The method parameter %s is never used';
  168.                 $data  = array($paramName);
  169.                 $phpcsFile->addWarning($error, $position, 'Found', $data);
  170.             }
  171.         }
  172.  
  173.     }//end process()
  174.  
  175.  
  176. }//end class

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