Skip to content
This repository was archived by the owner on Nov 5, 2022. It is now read-only.

Commit 55afc64

Browse files
committed
Fixed class comment tags
1 parent daac1ef commit 55afc64

File tree

3 files changed

+175
-2
lines changed

3 files changed

+175
-2
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
<?php
2+
/**
3+
* Class Comment
4+
*
5+
* @package CodeIgniter4-Standard
6+
* @author Louis Linehan <louis.linehan@gmail.com>
7+
* @copyright 2017 Louis Linehan
8+
* @license https://github.com/louisl/CodeIgniter4-Standard/blob/master/LICENSE MIT License
9+
*/
10+
11+
namespace CodeIgniter4\Sniffs\Commenting;
12+
13+
use CodeIgniter4\Sniffs\Commenting\FileCommentSniff;
14+
use PHP_CodeSniffer\Sniffs\Sniff;
15+
use PHP_CodeSniffer\Files\File;
16+
use PHP_CodeSniffer\Util\Tokens;
17+
18+
/**
19+
* Class Comment Sniff
20+
*
21+
* Parses and verifies the doc comments for classes.
22+
*
23+
* @author Louis Linehan <louis.linehan@gmail.com>
24+
*/
25+
class ClassCommentSniff extends FileCommentSniff
26+
{
27+
28+
/**
29+
* Tags in correct order and related info.
30+
*
31+
* @var array
32+
*/
33+
protected $tags = array(
34+
'@package' => array(
35+
'required' => true,
36+
'allow_multiple' => false,
37+
),
38+
'@subpackage' => array(
39+
'required' => false,
40+
'allow_multiple' => false,
41+
),
42+
'@category' => array(
43+
'required' => false,
44+
'allow_multiple' => false,
45+
),
46+
'@author' => array(
47+
'required' => false,
48+
'allow_multiple' => true,
49+
),
50+
'@copyright' => array(
51+
'required' => false,
52+
'allow_multiple' => true,
53+
),
54+
'@license' => array(
55+
'required' => false,
56+
'allow_multiple' => false,
57+
),
58+
'@link' => array(
59+
'required' => false,
60+
'allow_multiple' => true,
61+
),
62+
'@since' => array(
63+
'required' => false,
64+
'allow_multiple' => false,
65+
),
66+
'@version' => array(
67+
'required' => false,
68+
'allow_multiple' => false,
69+
),
70+
'@see' => array(
71+
'required' => false,
72+
'allow_multiple' => true,
73+
),
74+
'@deprecated' => array(
75+
'required' => false,
76+
'allow_multiple' => false,
77+
),
78+
);
79+
80+
81+
/**
82+
* Returns an array of tokens this test wants to listen for.
83+
*
84+
* @return array
85+
*/
86+
public function register()
87+
{
88+
return array(
89+
T_CLASS,
90+
T_INTERFACE,
91+
);
92+
93+
}//end register()
94+
95+
96+
/**
97+
* Processes this test, when one of its tokens is encountered.
98+
*
99+
* @param File $phpcsFile The file being scanned.
100+
* @param int $stackPtr The position of the current token
101+
* in the stack passed in $tokens.
102+
*
103+
* @return void
104+
*/
105+
public function process(File $phpcsFile, $stackPtr)
106+
{
107+
$this->currentFile = $phpcsFile;
108+
109+
$tokens = $phpcsFile->getTokens();
110+
$type = strtolower($tokens[$stackPtr]['content']);
111+
$errorData = array($type);
112+
113+
$find = Tokens::$methodPrefixes;
114+
$find[] = T_WHITESPACE;
115+
116+
$commentEnd = $phpcsFile->findPrevious($find, ($stackPtr - 1), null, true);
117+
if ($tokens[$commentEnd]['code'] !== T_DOC_COMMENT_CLOSE_TAG
118+
&& $tokens[$commentEnd]['code'] !== T_COMMENT
119+
) {
120+
$phpcsFile->addError('Missing class doc comment', $stackPtr, 'Missing');
121+
$phpcsFile->recordMetric($stackPtr, 'Class has doc comment', 'no');
122+
return;
123+
} else {
124+
$phpcsFile->recordMetric($stackPtr, 'Class has doc comment', 'yes');
125+
}
126+
127+
// Try and determine if this is a file comment instead of a class comment.
128+
// We assume that if this is the first comment after the open PHP tag, then
129+
// it is most likely a file comment instead of a class comment.
130+
if ($tokens[$commentEnd]['code'] === T_DOC_COMMENT_CLOSE_TAG) {
131+
$start = ($tokens[$commentEnd]['comment_opener'] - 1);
132+
} else {
133+
$start = $phpcsFile->findPrevious(T_COMMENT, ($commentEnd - 1), null, true);
134+
}
135+
136+
$prev = $phpcsFile->findPrevious(T_WHITESPACE, $start, null, true);
137+
if ($tokens[$prev]['code'] === T_OPEN_TAG) {
138+
$prevOpen = $phpcsFile->findPrevious(T_OPEN_TAG, ($prev - 1));
139+
if ($prevOpen === false) {
140+
// This is a comment directly after the first open tag,
141+
// so probably a file comment.
142+
$phpcsFile->addError('Missing class doc comment', $stackPtr, 'Missing');
143+
return;
144+
}
145+
}
146+
147+
if ($tokens[$commentEnd]['code'] === T_COMMENT) {
148+
$phpcsFile->addError('You must use "/**" style comments for a class comment', $stackPtr, 'WrongStyle');
149+
return;
150+
}
151+
152+
// Check each tag.
153+
$this->processTags($phpcsFile, $stackPtr, $tokens[$commentEnd]['comment_opener']);
154+
155+
}//end process()
156+
157+
158+
}//end class

CodeIgniter4/Sniffs/Commenting/FileCommentSniff.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,11 @@ protected function processTags(File $phpcsFile, $stackPtr, $commentStart)
171171
{
172172
$tokens = $phpcsFile->getTokens();
173173

174-
$docBlock = 'file';
174+
if (get_class($this) === 'FileCommentSniff') {
175+
$docBlock = 'file';
176+
} else {
177+
$docBlock = 'class';
178+
}
175179

176180
$commentEnd = $tokens[$commentStart]['comment_closer'];
177181

@@ -487,7 +491,7 @@ protected function processLink(File $phpcsFile, array $tags)
487491
preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i", $parts[0], $matches);
488492
if (count($matches) !== 1) {
489493
$error = 'The URL must come before the description';
490-
$phpcsFile->addError($error, $tag, 'LicenseURLNotFirst');
494+
$phpcsFile->addError($error, $tag, 'LinkURLNotFirst');
491495
}
492496
}
493497
}//end foreach

CodeIgniter4/ruleset.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
-->
1212
<!--
1313
Files MUST have a doc block comment.
14+
Checks file comment tag format and order.
1415
-->
1516
<rule ref="CodeIgniter4.Commenting.FileComment">
1617
<properties>
@@ -22,6 +23,16 @@
2223
-->
2324
<rule ref="Squiz.Commenting.ClassComment"/>
2425
<!--
26+
Checks class comment tag format and order.
27+
-->
28+
<rule ref="CodeIgniter4.Commenting.ClassComment"/>
29+
<!--
30+
Allow class tags.
31+
-->
32+
<rule ref="Squiz.Commenting.ClassComment.TagNotAllowed">
33+
<severity>0</severity>
34+
</rule>
35+
<!--
2536
Properties MUST have a doc block comment.
2637
-->
2738
<rule ref="Squiz.Commenting.VariableComment"/>

0 commit comments

Comments
 (0)