Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. FunctionCommentSniff.php

function FunctionCommentSniff::processParams

Same name in this branch
  1. 11.1.x vendor/drupal/coder/coder_sniffer/Drupal/Sniffs/Commenting/FunctionCommentSniff.php \Drupal\Sniffs\Commenting\FunctionCommentSniff::processParams()
  2. 11.1.x vendor/squizlabs/php_codesniffer/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php \PHP_CodeSniffer\Standards\Squiz\Sniffs\Commenting\FunctionCommentSniff::processParams()

Process the function parameter comments.

Parameters

\PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.:

int $stackPtr The position of the current token: in the stack passed in $tokens.

int $commentStart The position in the stack where the comment started.:

Return value

void

1 call to FunctionCommentSniff::processParams()
FunctionCommentSniff::process in vendor/squizlabs/php_codesniffer/src/Standards/PEAR/Sniffs/Commenting/FunctionCommentSniff.php
Processes this test, when one of its tokens is encountered.
1 method overrides FunctionCommentSniff::processParams()
FunctionCommentSniff::processParams in vendor/squizlabs/php_codesniffer/src/Standards/Squiz/Sniffs/Commenting/FunctionCommentSniff.php
Process the function parameter comments.

File

vendor/squizlabs/php_codesniffer/src/Standards/PEAR/Sniffs/Commenting/FunctionCommentSniff.php, line 265

Class

FunctionCommentSniff

Namespace

PHP_CodeSniffer\Standards\PEAR\Sniffs\Commenting

Code

protected function processParams(File $phpcsFile, $stackPtr, $commentStart) {
    $tokens = $phpcsFile->getTokens();
    $params = [];
    $maxType = 0;
    $maxVar = 0;
    foreach ($tokens[$commentStart]['comment_tags'] as $pos => $tag) {
        if ($tokens[$tag]['content'] !== '@param') {
            continue;
        }
        $type = '';
        $typeSpace = 0;
        $var = '';
        $varSpace = 0;
        $comment = '';
        $commentEnd = 0;
        $commentTokens = [];
        if ($tokens[$tag + 2]['code'] === T_DOC_COMMENT_STRING) {
            $matches = [];
            preg_match('/((?:(?![$.]|&(?=\\$)).)*)(?:((?:\\.\\.\\.)?(?:\\$|&)[^\\s]+)(?:(\\s+)(.*))?)?/', $tokens[$tag + 2]['content'], $matches);
            if (empty($matches) === false) {
                $typeLen = strlen($matches[1]);
                $type = trim($matches[1]);
                $typeSpace = $typeLen - strlen($type);
                $typeLen = strlen($type);
                if ($typeLen > $maxType) {
                    $maxType = $typeLen;
                }
            }
            if (isset($matches[2]) === true) {
                $var = $matches[2];
                $varLen = strlen($var);
                if ($varLen > $maxVar) {
                    $maxVar = $varLen;
                }
                if (isset($matches[4]) === true) {
                    $varSpace = strlen($matches[3]);
                    $comment = $matches[4];
                    // Any strings until the next tag belong to this comment.
                    if (isset($tokens[$commentStart]['comment_tags'][$pos + 1]) === true) {
                        $end = $tokens[$commentStart]['comment_tags'][$pos + 1];
                    }
                    else {
                        $end = $tokens[$commentStart]['comment_closer'];
                    }
                    for ($i = $tag + 3; $i < $end; $i++) {
                        if ($tokens[$i]['code'] === T_DOC_COMMENT_STRING) {
                            $comment .= ' ' . $tokens[$i]['content'];
                            $commentEnd = $i;
                            $commentTokens[] = $i;
                        }
                    }
                }
                else {
                    $error = 'Missing parameter comment';
                    $phpcsFile->addError($error, $tag, 'MissingParamComment');
                }
                
                //end if
            }
            else {
                $error = 'Missing parameter name';
                $phpcsFile->addError($error, $tag, 'MissingParamName');
            }
            
            //end if
        }
        else {
            $error = 'Missing parameter type';
            $phpcsFile->addError($error, $tag, 'MissingParamType');
        }
        
        //end if
        $params[] = [
            'tag' => $tag,
            'type' => $type,
            'var' => $var,
            'comment' => $comment,
            'comment_end' => $commentEnd,
            'comment_tokens' => $commentTokens,
            'type_space' => $typeSpace,
            'var_space' => $varSpace,
        ];
    }
    
    //end foreach
    $realParams = $phpcsFile->getMethodParameters($stackPtr);
    $foundParams = [];
    // We want to use ... for all variable length arguments, so add
    // this prefix to the variable name so comparisons are easier.
    foreach ($realParams as $pos => $param) {
        if ($param['variable_length'] === true) {
            $realParams[$pos]['name'] = '...' . $realParams[$pos]['name'];
        }
    }
    foreach ($params as $pos => $param) {
        if ($param['var'] === '') {
            continue;
        }
        $foundParams[] = $param['var'];
        if (trim($param['type']) !== '') {
            // Check number of spaces after the type.
            $spaces = $maxType - strlen($param['type']) + 1;
            if ($param['type_space'] !== $spaces) {
                $error = 'Expected %s spaces after parameter type; %s found';
                $data = [
                    $spaces,
                    $param['type_space'],
                ];
                $fix = $phpcsFile->addFixableError($error, $param['tag'], 'SpacingAfterParamType', $data);
                if ($fix === true) {
                    $commentToken = $param['tag'] + 2;
                    $content = $param['type'];
                    $content .= str_repeat(' ', $spaces);
                    $content .= $param['var'];
                    $content .= str_repeat(' ', $param['var_space']);
                    $wrapLength = $tokens[$commentToken]['length'] - $param['type_space'] - $param['var_space'] - strlen($param['type']) - strlen($param['var']);
                    $star = $phpcsFile->findPrevious(T_DOC_COMMENT_STAR, $param['tag']);
                    $spaceLength = strlen($content) + $tokens[$commentToken - 1]['length'] + $tokens[$commentToken - 2]['length'];
                    $padding = str_repeat(' ', $tokens[$star]['column'] - 1);
                    $padding .= '* ';
                    $padding .= str_repeat(' ', $spaceLength);
                    $content .= wordwrap($param['comment'], $wrapLength, $phpcsFile->eolChar . $padding);
                    $phpcsFile->fixer
                        ->replaceToken($commentToken, $content);
                    for ($i = $commentToken + 1; $i <= $param['comment_end']; $i++) {
                        $phpcsFile->fixer
                            ->replaceToken($i, '');
                    }
                }
                
                //end if
            }
            
            //end if
        }
        
        //end if
        // Make sure the param name is correct.
        if (isset($realParams[$pos]) === true) {
            $realName = $realParams[$pos]['name'];
            if ($realName !== $param['var']) {
                $code = 'ParamNameNoMatch';
                $data = [
                    $param['var'],
                    $realName,
                ];
                $error = 'Doc comment for parameter %s does not match ';
                if (strtolower($param['var']) === strtolower($realName)) {
                    $error .= 'case of ';
                    $code = 'ParamNameNoCaseMatch';
                }
                $error .= 'actual variable name %s';
                $phpcsFile->addError($error, $param['tag'], $code, $data);
            }
        }
        else {
            if (substr($param['var'], -4) !== ',...') {
                // We must have an extra parameter comment.
                $error = 'Superfluous parameter comment';
                $phpcsFile->addError($error, $param['tag'], 'ExtraParamComment');
            }
        }
        
        //end if
        if ($param['comment'] === '') {
            continue;
        }
        // Check number of spaces after the param name.
        $spaces = $maxVar - strlen($param['var']) + 1;
        if ($param['var_space'] !== $spaces) {
            $error = 'Expected %s spaces after parameter name; %s found';
            $data = [
                $spaces,
                $param['var_space'],
            ];
            $fix = $phpcsFile->addFixableError($error, $param['tag'], 'SpacingAfterParamName', $data);
            if ($fix === true) {
                $commentToken = $param['tag'] + 2;
                $content = $param['type'];
                $content .= str_repeat(' ', $param['type_space']);
                $content .= $param['var'];
                $content .= str_repeat(' ', $spaces);
                $wrapLength = $tokens[$commentToken]['length'] - $param['type_space'] - $param['var_space'] - strlen($param['type']) - strlen($param['var']);
                $star = $phpcsFile->findPrevious(T_DOC_COMMENT_STAR, $param['tag']);
                $spaceLength = strlen($content) + $tokens[$commentToken - 1]['length'] + $tokens[$commentToken - 2]['length'];
                $padding = str_repeat(' ', $tokens[$star]['column'] - 1);
                $padding .= '* ';
                $padding .= str_repeat(' ', $spaceLength);
                $content .= wordwrap($param['comment'], $wrapLength, $phpcsFile->eolChar . $padding);
                $phpcsFile->fixer
                    ->replaceToken($commentToken, $content);
                for ($i = $commentToken + 1; $i <= $param['comment_end']; $i++) {
                    $phpcsFile->fixer
                        ->replaceToken($i, '');
                }
            }
            
            //end if
        }
        
        //end if
        // Check the alignment of multi-line param comments.
        if ($param['tag'] !== $param['comment_end']) {
            $wrapLength = $tokens[$param['tag'] + 2]['length'] - $param['type_space'] - $param['var_space'] - strlen($param['type']) - strlen($param['var']);
            $startColumn = $tokens[$param['tag'] + 2]['column'] + $tokens[$param['tag'] + 2]['length'] - $wrapLength;
            $star = $phpcsFile->findPrevious(T_DOC_COMMENT_STAR, $param['tag']);
            $expected = $startColumn - $tokens[$star]['column'] - 1;
            foreach ($param['comment_tokens'] as $commentToken) {
                if ($tokens[$commentToken]['column'] === $startColumn) {
                    continue;
                }
                $found = 0;
                if ($tokens[$commentToken - 1]['code'] === T_DOC_COMMENT_WHITESPACE) {
                    $found = $tokens[$commentToken - 1]['length'];
                }
                $error = 'Parameter comment not aligned correctly; expected %s spaces but found %s';
                $data = [
                    $expected,
                    $found,
                ];
                if ($found < $expected) {
                    $code = 'ParamCommentAlignment';
                }
                else {
                    $code = 'ParamCommentAlignmentExceeded';
                }
                $fix = $phpcsFile->addFixableError($error, $commentToken, $code, $data);
                if ($fix === true) {
                    $padding = str_repeat(' ', $expected);
                    if ($tokens[$commentToken - 1]['code'] === T_DOC_COMMENT_WHITESPACE) {
                        $phpcsFile->fixer
                            ->replaceToken($commentToken - 1, $padding);
                    }
                    else {
                        $phpcsFile->fixer
                            ->addContentBefore($commentToken, $padding);
                    }
                }
            }
            
            //end foreach
        }
        
        //end if
    }
    
    //end foreach
    $realNames = [];
    foreach ($realParams as $realParam) {
        $realNames[] = $realParam['name'];
    }
    // Report missing comments.
    $diff = array_diff($realNames, $foundParams);
    foreach ($diff as $neededParam) {
        $error = 'Doc comment for parameter "%s" missing';
        $data = [
            $neededParam,
        ];
        $phpcsFile->addError($error, $commentStart, 'MissingParamTag', $data);
    }
}
RSS feed
Powered by Drupal