Skip to content

Commit 971fac1

Browse files
committed
Add custom ClassCommentSniff
This sniff is the Squiz ClassComment sniff, but only disallowing certain tags in the class docblock
1 parent 1a3f1ea commit 971fac1

File tree

2 files changed

+96
-1
lines changed

2 files changed

+96
-1
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
/**
3+
* Parses and verifies the class doc comment.
4+
*
5+
* Verifies that :
6+
* <ul>
7+
* <li>A class doc comment exists.</li>
8+
* <li>There is exactly one blank line before the class comment.</li>
9+
* <li>There are no blank lines after the class comment.</li>
10+
* <li>Short and long descriptions end with a full stop and start with capital letter.</li>
11+
* <li>There is a blank line between descriptions.</li>
12+
* <li>Disallows throws, return, var and param tags.</li>
13+
* </ul>
14+
*/
15+
final class Chadicus_Sniffs_Commenting_ClassCommentSniff implements PHP_CodeSniffer_Sniff
16+
{
17+
public $disallowedTags = array('@throws', '@return', '@var', '@param');
18+
19+
/**
20+
* Returns an array of tokens this test wants to listen for.
21+
*
22+
* @return array
23+
*/
24+
public function register()
25+
{
26+
return array(T_CLASS, T_INTERFACE);
27+
}
28+
29+
/**
30+
* Processes this test, when one of its tokens is encountered.
31+
*
32+
* @param PHP_CodeSniffer_File $phpcsFile The file being scanned.
33+
* @param int $stackPtr The position of the current token
34+
* in the stack passed in $tokens.
35+
*
36+
* @return void
37+
*/
38+
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
39+
{
40+
$tokens = $phpcsFile->getTokens();
41+
$find = PHP_CodeSniffer_Tokens::$methodPrefixes;
42+
$find[] = T_WHITESPACE;
43+
44+
$commentEnd = $phpcsFile->findPrevious($find, ($stackPtr - 1), null, true);
45+
if ($tokens[$commentEnd]['code'] !== T_DOC_COMMENT_CLOSE_TAG
46+
&& $tokens[$commentEnd]['code'] !== T_COMMENT
47+
) {
48+
$phpcsFile->addError('Missing class doc comment', $stackPtr, 'Missing');
49+
return;
50+
}
51+
52+
// Try and determine if this is a file comment instead of a class comment.
53+
// We assume that if this is the first comment after the open PHP tag, then
54+
// it is most likely a file comment instead of a class comment.
55+
if ($tokens[$commentEnd]['code'] === T_DOC_COMMENT_CLOSE_TAG) {
56+
$start = ($tokens[$commentEnd]['comment_opener'] - 1);
57+
} else {
58+
$start = $phpcsFile->findPrevious(T_COMMENT, ($commentEnd - 1), null, true);
59+
}
60+
61+
$prev = $phpcsFile->findPrevious(T_WHITESPACE, $start, null, true);
62+
if ($tokens[$prev]['code'] === T_OPEN_TAG) {
63+
$prevOpen = $phpcsFile->findPrevious(T_OPEN_TAG, ($prev - 1));
64+
if ($prevOpen === false) {
65+
// This is a comment directly after the first open tag,
66+
// so probably a file comment.
67+
$phpcsFile->addError('Missing class doc comment', $stackPtr, 'Missing');
68+
return;
69+
}
70+
}
71+
72+
if ($tokens[$commentEnd]['code'] === T_COMMENT) {
73+
$phpcsFile->addError('You must use "/**" style comments for a class comment', $stackPtr, 'WrongStyle');
74+
return;
75+
}
76+
77+
if ($tokens[$commentEnd]['line'] !== ($tokens[$stackPtr]['line'] - 1)) {
78+
$error = 'There must be no blank lines after the class comment';
79+
$phpcsFile->addError($error, $commentEnd, 'SpacingAfter');
80+
}
81+
82+
$commentStart = $tokens[$commentEnd]['comment_opener'];
83+
if ($tokens[$prev]['line'] !== ($tokens[$commentStart]['line'] - 2)) {
84+
$error = 'There must be exactly one blank line before the class comment';
85+
$phpcsFile->addError($error, $commentStart, 'SpacingBefore');
86+
}
87+
88+
foreach ($tokens[$commentStart]['comment_tags'] as $tag) {
89+
if (in_array($tokens[$tag]['content'], $this->disallowedTags)) {
90+
$error = '%s tag is not allowed in class comment';
91+
$data = array($tokens[$tag]['content']);
92+
$phpcsFile->addWarning($error, $tag, 'TagNotAllowed', $data);
93+
}
94+
}
95+
}
96+
}

Chadicus/ruleset.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement" />
99
<rule ref="Generic.CodeAnalysis.UselessOverridingMethod" />
1010
<rule ref="Generic.ControlStructures.InlineControlStructure" />
11-
<rule ref="Squiz.Commenting.ClassComment" />
1211
<rule ref="Squiz.Commenting.DocCommentAlignment" />
1312
<rule ref="Squiz.Commenting.FunctionComment" />
1413
<rule ref="Squiz.Commenting.FunctionCommentThrowTag" />

0 commit comments

Comments
 (0)