3
* Squiz_Sniffs_Commenting_InlineCommentSniff.
8
* @package PHP_CodeSniffer
9
* @author Greg Sherwood <gsherwood@squiz.net>
10
* @author Marc McIntyre <mmcintyre@squiz.net>
11
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
12
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
13
* @version CVS: $Id: InlineCommentSniff.php,v 1.11 2008/02/26 03:47:35 squiz Exp $
14
* @link http://pear.php.net/package/PHP_CodeSniffer
18
* Squiz_Sniffs_Commenting_InlineCommentSniff.
20
* Checks that there is adequate spacing between comments.
23
* @package PHP_CodeSniffer
24
* @author Greg Sherwood <gsherwood@squiz.net>
25
* @author Marc McIntyre <mmcintyre@squiz.net>
26
* @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600)
27
* @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence
28
* @version Release: 1.1.0
29
* @link http://pear.php.net/package/PHP_CodeSniffer
31
class Squiz_Sniffs_Commenting_InlineCommentSniff implements PHP_CodeSniffer_Sniff
36
* Returns an array of tokens this test wants to listen for.
40
public function register()
51
* Processes this test, when one of its tokens is encountered.
53
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
54
* @param int $stackPtr The position of the current token in the
55
* stack passed in $tokens.
59
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
61
$tokens = $phpcsFile->getTokens();
63
// If this is a function/class/interface doc block comment, skip it.
64
// We are only interested in inline doc block comments, which are
66
if ($tokens[$stackPtr]['code'] === T_DOC_COMMENT) {
67
$nextToken = $phpcsFile->findNext(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr + 1), null, true);
79
if (in_array($tokens[$nextToken]['code'], $ignore) === true) {
82
$prevToken = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 1), null, true);
83
if ($tokens[$prevToken]['code'] === T_OPEN_TAG) {
87
// Only error once per comment.
88
if (substr($tokens[$stackPtr]['content'], 0, 3) === '/**') {
89
$error = 'Inline doc block comments are not allowed; use "/* Comment */" or "// Comment" instead';
90
$phpcsFile->addError($error, $stackPtr);
95
if ($tokens[$stackPtr]['content']{0} === '#') {
96
$error = 'Perl-style comments are not allowed; use "// Comment" instead';
97
$phpcsFile->addError($error, $stackPtr);
100
// We don't want end of block comments. If the last comment is a closing
102
$previousContent = $phpcsFile->findPrevious(array(T_WHITESPACE), ($stackPtr - 1), null, true);
103
if (($tokens[$previousContent]['line'] === $tokens[$stackPtr]['line']) && ($tokens[$previousContent]['code'] === T_CLOSE_CURLY_BRACKET)) {
107
$comment = rtrim($tokens[$stackPtr]['content']);
108
// Only want inline comments.
109
if (substr($comment, 0, 2) !== '//') {
114
for ($i = 2; $i < strlen($comment); $i++) {
115
if ($comment[$i] !== ' ') {
122
if ($spaceCount === 0) {
123
$error = 'No space before comment text; expected "// '.substr($comment, 2).'" but found "'.$comment.'"';
124
$phpcsFile->addError($error, $stackPtr);
127
if ($spaceCount > 1) {
128
$error = $spaceCount.' spaces found before inline comment; expected "// '.substr($comment, (2 + $spaceCount)).'" but found "'.$comment.'"';
129
$phpcsFile->addError($error, $stackPtr);
133
// The below section determines if a comment block is correctly capitalised,
134
// and ends in a full-stop. It will find the last comment in a block, and
136
$nextComment = $phpcsFile->findNext(array(T_COMMENT), ($stackPtr + 1), null, false);
138
if (($nextComment !== false) && (($tokens[$nextComment]['line']) === ($tokens[$stackPtr]['line'] + 1))) {
142
$topComment = $stackPtr;
143
$lastComment = $stackPtr;
144
while (($topComment = $phpcsFile->findPrevious(array(T_COMMENT), ($lastComment - 1), null, false)) !== false) {
145
if ($tokens[$topComment]['line'] !== ($tokens[$lastComment]['line'] - 1)) {
149
$lastComment = $topComment;
152
$topComment = $lastComment;
155
for ($i = $topComment; $i <= $stackPtr; $i++) {
156
if ($tokens[$i]['code'] === T_COMMENT) {
157
$commentText .= trim(substr($tokens[$i]['content'], 2));
161
if ($commentText === '') {
162
$error = 'Blank comments are not allowed';
163
$phpcsFile->addError($error, $stackPtr);
167
if (preg_match('|[A-Z]|', $commentText[0]) === 0) {
168
$error = 'Inline comments must start with a capital letter';
169
$phpcsFile->addError($error, $topComment);
172
$commentCloser = $commentText[(strlen($commentText) - 1)];
173
$acceptedClosers = array(
175
'exclamation marks' => '!',
176
'or question marks' => '?',
179
if (in_array($commentCloser, $acceptedClosers) === false) {
180
$error = 'Inline comments must end in';
181
foreach ($acceptedClosers as $closerName => $symbol) {
182
$error .= ' '.$closerName.',';
185
$error = rtrim($error, ',');
186
$phpcsFile->addError($error, $stackPtr);
189
// Finally, the line below the last comment cannot be empty.
191
for ($i = ($stackPtr + 1); $i < $phpcsFile->numTokens; $i++) {
192
if ($tokens[$i]['line'] === ($tokens[$stackPtr]['line'] + 1)) {
193
if ($tokens[$i]['code'] !== T_WHITESPACE) {
196
} else if ($tokens[$i]['line'] > ($tokens[$stackPtr]['line'] + 1)) {
201
$error = 'There must be no blank line following an inline comment';
202
$phpcsFile->addError($error, $stackPtr);