-
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: Commenting\DisallowEmptyComment sniff
Detects empty comments (doc-blocks, multiline and inline comments) and redundant empty lines in comments. Two empty lines next to each other are disallowed, also - empty lines at the beginning and at the end of the comment are disallowed.
- Loading branch information
1 parent
df93d48
commit 79599b9
Showing
4 changed files
with
343 additions
and
0 deletions.
There are no files selected for viewing
149 changes: 149 additions & 0 deletions
149
src/WebimpressCodingStandard/Sniffs/Commenting/DisallowEmptyCommentSniff.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace WebimpressCodingStandard\Sniffs\Commenting; | ||
|
||
use PHP_CodeSniffer\Files\File; | ||
use PHP_CodeSniffer\Sniffs\Sniff; | ||
use PHP_CodeSniffer\Util\Common; | ||
|
||
use function preg_match; | ||
use function preg_replace; | ||
use function strpos; | ||
use function trim; | ||
|
||
use const T_COMMENT; | ||
use const T_DOC_COMMENT_CLOSE_TAG; | ||
use const T_DOC_COMMENT_OPEN_TAG; | ||
use const T_DOC_COMMENT_STAR; | ||
use const T_DOC_COMMENT_WHITESPACE; | ||
use const T_WHITESPACE; | ||
|
||
class DisallowEmptyCommentSniff implements Sniff | ||
{ | ||
/** | ||
* @return int[] | ||
*/ | ||
public function register() : array | ||
{ | ||
return [ | ||
T_DOC_COMMENT_OPEN_TAG, | ||
T_COMMENT, | ||
]; | ||
} | ||
|
||
/** | ||
* @param int $stackPtr | ||
*/ | ||
public function process(File $phpcsFile, $stackPtr) : int | ||
{ | ||
$tokens = $phpcsFile->getTokens(); | ||
|
||
if ($tokens[$stackPtr]['code'] === T_DOC_COMMENT_OPEN_TAG) { | ||
$next = $phpcsFile->findNext([T_DOC_COMMENT_WHITESPACE, T_DOC_COMMENT_STAR], $stackPtr + 1, null, true); | ||
|
||
if ($tokens[$next]['code'] === T_DOC_COMMENT_CLOSE_TAG) { | ||
$error = 'Empty doc-block comment'; | ||
|
||
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'DocBlock'); | ||
if ($fix) { | ||
$after = $phpcsFile->findNext(T_WHITESPACE, $next + 1, null, true); | ||
$phpcsFile->fixer->beginChangeset(); | ||
for ($i = $stackPtr; $i < $after; ++$i) { | ||
$phpcsFile->fixer->replaceToken($i, ''); | ||
} | ||
$phpcsFile->fixer->endChangeset(); | ||
} | ||
} | ||
|
||
return $stackPtr + 1; | ||
} | ||
|
||
$line = $tokens[$stackPtr]['line']; | ||
$comment = trim($tokens[$stackPtr]['content']); | ||
if (strpos($comment, '/*') === 0) { | ||
$i = $stackPtr; | ||
$content = ''; | ||
do { | ||
$content .= $tokens[$i]['content']; | ||
} while ($tokens[++$i]['code'] === T_COMMENT); | ||
|
||
$end = $i; | ||
|
||
if (preg_replace('#[\s\*/]#', '', $content) === '') { | ||
$fix = $phpcsFile->addFixableError('Empty comment', $stackPtr, 'Multiline'); | ||
if ($fix) { | ||
$next = $phpcsFile->findNext(T_WHITESPACE, $i, null, true) ?: $phpcsFile->numTokens; | ||
$phpcsFile->fixer->beginChangeset(); | ||
for ($i = $stackPtr; $i < $next; ++$i) { | ||
$phpcsFile->fixer->replaceToken($i, ''); | ||
} | ||
$phpcsFile->fixer->endChangeset(); | ||
} | ||
|
||
return $end; | ||
} | ||
|
||
$newContent = preg_replace('#(^/\*\s*?$)(?:\n^[\s\*]*$)+#m', '\\1', $content); | ||
$newContent = preg_replace('#(?:^[\s\*]*$\n)+(\s*?\*/)#m', '\\1', $newContent); | ||
$newContent = preg_replace('#(^[\s\*]*$\n){2,}#m', '\\1', $newContent); | ||
|
||
if ($newContent !== $content) { | ||
$error = 'Redundant empty lines in comment; found: %s but expected %s'; | ||
$data = [ | ||
Common::prepareForOutput($content), | ||
Common::prepareForOutput($newContent), | ||
]; | ||
|
||
$fix = $phpcsFile->addFixableError($error, $stackPtr, 'Lines', $data); | ||
if ($fix) { | ||
$phpcsFile->fixer->beginChangeset(); | ||
while (--$i >= $stackPtr) { | ||
$phpcsFile->fixer->replaceToken($i, ''); | ||
} | ||
$phpcsFile->fixer->addContent($stackPtr, $newContent); | ||
$phpcsFile->fixer->endChangeset(); | ||
} | ||
} | ||
|
||
return $end; | ||
} | ||
|
||
if ($this->isEmptyComment($comment)) { | ||
$before = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); | ||
$after = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); | ||
|
||
$hasBefore = false; | ||
$hasAfter = false; | ||
|
||
if ($tokens[$before]['code'] === T_COMMENT | ||
&& $tokens[$before]['line'] === $line - 1 | ||
&& ! $this->isEmptyComment($tokens[$before]['content']) | ||
) { | ||
$hasBefore = true; | ||
} | ||
|
||
if ($tokens[$after]['code'] === T_COMMENT | ||
&& $tokens[$after]['line'] === $line + 1 | ||
&& ! $this->isEmptyComment($tokens[$after]['content']) | ||
) { | ||
$hasAfter = true; | ||
} | ||
|
||
if (! $hasBefore || ! $hasAfter) { | ||
$fix = $phpcsFile->addFixableError('Empty inline comment ' . $comment, $stackPtr, 'Inline'); | ||
if ($fix) { | ||
$phpcsFile->fixer->replaceToken($stackPtr, ''); | ||
} | ||
} | ||
} | ||
|
||
return $stackPtr + 1; | ||
} | ||
|
||
private function isEmptyComment(string $comment) : bool | ||
{ | ||
return preg_match('@^(//|#)[\s/#*-]*$@', $comment) === 1; | ||
} | ||
} |
101 changes: 101 additions & 0 deletions
101
test/Sniffs/Commenting/DisallowEmptyCommentUnitTest.inc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<?php | ||
/** | ||
* non empty doc-block comment | ||
*/ | ||
|
||
/** | ||
* | ||
*/ | ||
|
||
/** | ||
*/ | ||
|
||
/** */ | ||
|
||
/* */ | ||
|
||
/* * */ | ||
|
||
/* | ||
*/ | ||
|
||
/* | ||
* | ||
*/ | ||
|
||
/* | ||
*/ | ||
|
||
/* | ||
* | ||
* | ||
*/ | ||
|
||
// | ||
|
||
# | ||
|
||
// Hello | ||
// | ||
// Above line can be empty | ||
|
||
# The same | ||
# | ||
# here | ||
|
||
/* | ||
* Below line cannot be empty | ||
* | ||
*/ | ||
|
||
/* | ||
* | ||
* Above line cannot be empty | ||
*/ | ||
|
||
// | ||
// Above line cannot be empty | ||
|
||
// Below line cannot be empty | ||
// | ||
|
||
// Mixed types: Below line cannot be empty. | ||
// | ||
# | ||
# Above and below lines cannot be empty. | ||
# | ||
/* something */ | ||
|
||
/**** | ||
* | ||
*/ | ||
|
||
/* | ||
Remove empty lines above and below | ||
*/ | ||
|
||
/* | ||
* | ||
* | ||
* Multi-line | ||
* | ||
* | ||
* comment | ||
* | ||
* | ||
*/ | ||
|
||
// / / / / / / / / / / / / | ||
|
||
////////////////////////// | ||
|
||
/// | ||
/// | ||
|
||
# # # # | ||
|
||
####### |
46 changes: 46 additions & 0 deletions
46
test/Sniffs/Commenting/DisallowEmptyCommentUnitTest.inc.fixed
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
/** | ||
* non empty doc-block comment | ||
*/ | ||
|
||
|
||
|
||
// Hello | ||
// | ||
// Above line can be empty | ||
|
||
# The same | ||
# | ||
# here | ||
|
||
/* | ||
* Below line cannot be empty | ||
*/ | ||
|
||
/* | ||
* Above line cannot be empty | ||
*/ | ||
|
||
// Above line cannot be empty | ||
|
||
// Below line cannot be empty | ||
|
||
// Mixed types: Below line cannot be empty. | ||
# Above and below lines cannot be empty. | ||
# | ||
/* something */ | ||
|
||
/* | ||
Remove empty lines above and below | ||
*/ | ||
|
||
/* | ||
* Multi-line | ||
* | ||
* comment | ||
*/ | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace WebimpressCodingStandardTest\Sniffs\Commenting; | ||
|
||
use WebimpressCodingStandardTest\Sniffs\AbstractTestCase; | ||
|
||
class DisallowEmptyCommentUnitTest extends AbstractTestCase | ||
{ | ||
protected function getErrorList(string $testFile = '') : array | ||
{ | ||
return [ | ||
6 => 1, | ||
10 => 1, | ||
14 => 1, | ||
16 => 1, | ||
18 => 1, | ||
20 => 1, | ||
23 => 1, | ||
27 => 1, | ||
31 => 1, | ||
36 => 1, | ||
38 => 1, | ||
48 => 1, | ||
53 => 1, | ||
58 => 1, | ||
62 => 1, | ||
65 => 1, | ||
66 => 1, | ||
71 => 1, | ||
75 => 1, | ||
81 => 1, | ||
92 => 1, | ||
94 => 1, | ||
96 => 1, | ||
97 => 1, | ||
99 => 1, | ||
101 => 1, | ||
]; | ||
} | ||
|
||
protected function getWarningList(string $testFile = '') : array | ||
{ | ||
return []; | ||
} | ||
} |