Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/*** Parses and verifies the doc comments for classes.** PHP version 5** @category PHP* @package PHP_CodeSniffer* @author Greg Sherwood <gsherwood@squiz.net>* @author Marc McIntyre <mmcintyre@squiz.net>* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence* @version CVS: $Id: ClassCommentSniff.php 270281 2008-12-02 02:38:34Z squiz $* @link http://pear.php.net/package/PHP_CodeSniffer*/if (class_exists('PHP_CodeSniffer_CommentParser_ClassCommentParser', true) === false) {$error = 'Class PHP_CodeSniffer_CommentParser_ClassCommentParser not found';throw new PHP_CodeSniffer_Exception($error);}if (class_exists('PEAR_Sniffs_Commenting_FileCommentSniff', true) === false) {$error = 'Class PEAR_Sniffs_Commenting_FileCommentSniff not found';throw new PHP_CodeSniffer_Exception($error);}/*** Parses and verifies the doc comments for classes.** Verifies that :* <ul>* <li>A doc comment exists.</li>* <li>There is a blank newline after the short description.</li>* <li>There is a blank newline between the long and short description.</li>* <li>There is a blank newline between the long description and tags.</li>* <li>Check the order of the tags.</li>* <li>Check the indentation of each tag.</li>* <li>Check required and optional tags and the format of their content.</li>* </ul>** @category PHP* @package PHP_CodeSniffer* @author Greg Sherwood <gsherwood@squiz.net>* @author Marc McIntyre <mmcintyre@squiz.net>* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence* @version Release: 1.2.1* @link http://pear.php.net/package/PHP_CodeSniffer*/class PEAR_Sniffs_Commenting_ClassCommentSniff extends PEAR_Sniffs_Commenting_FileCommentSniff{/*** Returns an array of tokens this test wants to listen for.** @return array*/public function register(){return array(T_CLASS,T_INTERFACE,);}//end register()/*** 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){$this->currentFile = $phpcsFile;$tokens = $phpcsFile->getTokens();$type = strtolower($tokens[$stackPtr]['content']);$find = array(T_ABSTRACT,T_WHITESPACE,T_FINAL,);// Extract the class comment docblock.$commentEnd = $phpcsFile->findPrevious($find, ($stackPtr - 1), null, true);if ($commentEnd !== false && $tokens[$commentEnd]['code'] === T_COMMENT) {$error = "You must use \"/**\" style comments for a $type comment";$phpcsFile->addError($error, $stackPtr);return;} else if ($commentEnd === false|| $tokens[$commentEnd]['code'] !== T_DOC_COMMENT) {$phpcsFile->addError("Missing $type doc comment", $stackPtr);return;}$commentStart = ($phpcsFile->findPrevious(T_DOC_COMMENT, ($commentEnd - 1), null, true) + 1);$commentNext = $phpcsFile->findPrevious(T_WHITESPACE, ($commentEnd + 1), $stackPtr, false, $phpcsFile->eolChar);// Distinguish file and class comment.$prevClassToken = $phpcsFile->findPrevious(T_CLASS, ($stackPtr - 1));if ($prevClassToken === false) {// This is the first class token in this file, need extra checks.$prevNonComment = $phpcsFile->findPrevious(T_DOC_COMMENT, ($commentStart - 1), null, true);if ($prevNonComment !== false) {$prevComment = $phpcsFile->findPrevious(T_DOC_COMMENT, ($prevNonComment - 1));if ($prevComment === false) {// There is only 1 doc comment between open tag and class token.$newlineToken = $phpcsFile->findNext(T_WHITESPACE, ($commentEnd + 1), $stackPtr, false, $phpcsFile->eolChar);if ($newlineToken !== false) {$newlineToken = $phpcsFile->findNext(T_WHITESPACE,($newlineToken + 1),$stackPtr,false,$phpcsFile->eolChar);if ($newlineToken !== false) {// Blank line between the class and the doc block.// The doc block is most likely a file comment.$error = "Missing $type doc comment";$phpcsFile->addError($error, ($stackPtr + 1));return;}}//end if}//end if}//end if}//end if$comment = $phpcsFile->getTokensAsString($commentStart,($commentEnd - $commentStart + 1));// Parse the class comment.docblock.try {$this->commentParser = new PHP_CodeSniffer_CommentParser_ClassCommentParser($comment, $phpcsFile);$this->commentParser->parse();} catch (PHP_CodeSniffer_CommentParser_ParserException $e) {$line = ($e->getLineWithinComment() + $commentStart);$phpcsFile->addError($e->getMessage(), $line);return;}$comment = $this->commentParser->getComment();if (is_null($comment) === true) {$error = ucfirst($type).' doc comment is empty';$phpcsFile->addError($error, $commentStart);return;}// No extra newline before short description.$short = $comment->getShortComment();$newlineCount = 0;$newlineSpan = strspn($short, $phpcsFile->eolChar);if ($short !== '' && $newlineSpan > 0) {$line = ($newlineSpan > 1) ? 'newlines' : 'newline';$error = "Extra $line found before $type comment short description";$phpcsFile->addError($error, ($commentStart + 1));}$newlineCount = (substr_count($short, $phpcsFile->eolChar) + 1);// Exactly one blank line between short and long description.$long = $comment->getLongComment();if (empty($long) === false) {$between = $comment->getWhiteSpaceBetween();$newlineBetween = substr_count($between, $phpcsFile->eolChar);if ($newlineBetween !== 2) {$error = "There must be exactly one blank line between descriptions in $type comments";$phpcsFile->addError($error, ($commentStart + $newlineCount + 1));}$newlineCount += $newlineBetween;}// Exactly one blank line before tags.$tags = $this->commentParser->getTagOrders();if (count($tags) > 1) {$newlineSpan = $comment->getNewlineAfter();if ($newlineSpan !== 2) {$error = "There must be exactly one blank line before the tags in $type comments";if ($long !== '') {$newlineCount += (substr_count($long, $phpcsFile->eolChar) - $newlineSpan + 1);}$phpcsFile->addError($error, ($commentStart + $newlineCount));$short = rtrim($short, $phpcsFile->eolChar.' ');}}// Check each tag.$this->processTags($commentStart, $commentEnd);}//end process()/*** Process the version tag.** @param int $errorPos The line number where the error occurs.** @return void*/protected function processVersion($errorPos){$version = $this->commentParser->getVersion();if ($version !== null) {$content = $version->getContent();$matches = array();if (empty($content) === true) {$error = 'Content missing for @version tag in doc comment';$this->currentFile->addError($error, $errorPos);} else if ((strstr($content, 'Release:') === false)) {$error = "Invalid version \"$content\" in doc comment; consider \"Release: <package_version>\" instead";$this->currentFile->addWarning($error, $errorPos);}}}//end processVersion()}//end class?>