Verifies that :
- A comment exists
- There is a blank newline after the short description
- There is a blank newline between the long and short description
- There is a blank newline between the long description and tags
- Parameter names represent those in the method
- Parameter comments are in the correct order
- Parameter comments are complete
- A type hint is provided for array and custom class
- Type hint matches the actual variable/class type
- A blank line is present before the first and after the last parameter
- A return type exists
- Any throw tag must have a comment
- The tag order and indentation are correct
/** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { parent::process($phpcsFile, $stackPtr); $tokens = $phpcsFile->getTokens(); $find = PHP_CodeSniffer_Tokens::$methodPrefixes; $find[] = T_WHITESPACE; $commentEnd = $phpcsFile->findPrevious($find, $stackPtr - 1, null, true); if ($tokens[$commentEnd]['code'] !== T_DOC_COMMENT_CLOSE_TAG) { return; } $commentStart = $tokens[$commentEnd]['comment_opener']; $hasApiTag = false; foreach ($tokens[$commentStart]['comment_tags'] as $tag) { if ($tokens[$tag]['content'] === '@api') { if ($hasApiTag === true) { // We've come across an API tag already, which means // we were not the first tag in the API list. $error = 'The @api tag must come first in the @api tag list in a function comment'; $phpcsFile->addError($error, $tag, 'ApiNotFirst'); } $hasApiTag = true; // There needs to be a blank line before the @api tag. $prev = $phpcsFile->findPrevious(array(T_DOC_COMMENT_STRING, T_DOC_COMMENT_TAG), $tag - 1); if ($tokens[$prev]['line'] !== $tokens[$tag]['line'] - 2) { $error = 'There must be one blank line before the @api tag in a function comment'; $phpcsFile->addError($error, $tag, 'ApiSpacing'); } } else { if (substr($tokens[$tag]['content'], 0, 5) === '@api-') { $hasApiTag = true; $prev = $phpcsFile->findPrevious(array(T_DOC_COMMENT_STRING, T_DOC_COMMENT_TAG), $tag - 1); if ($tokens[$prev]['line'] !== $tokens[$tag]['line'] - 1) { $error = 'There must be no blank line before the @%s tag in a function comment'; $data = array($tokens[$tag]['content']); $phpcsFile->addError($error, $tag, 'ApiTagSpacing', $data); } } } //end if } //end foreach if ($hasApiTag === true && substr($tokens[$tag]['content'], 0, 4) !== '@api') { // API tags must be the last tags in a function comment. $error = 'The @api tags must be the last tags in a function comment'; $phpcsFile->addError($error, $commentEnd, 'ApiNotLast'); } }
/** * Process the function parameter comments. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * @param int $commentStart The position in the stack where the comment started. * * @return void */ protected function processParams(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $commentStart) { // Accept inheriting of comments to be sufficient. if ($this->isInherited($phpcsFile, $commentStart)) { return; } $previous = PHP_CodeSniffer::$allowedTypes; PHP_CodeSniffer::$allowedTypes[] = 'int'; PHP_CodeSniffer::$allowedTypes[] = 'bool'; parent::processParams($phpcsFile, $stackPtr, $commentStart); PHP_CodeSniffer::$allowedTypes = $previous; }