Skip to content

Commit aeb28f2

Browse files
committed
Also handle phpDoc comments in the comment length fixer
1 parent e997296 commit aeb28f2

File tree

2 files changed

+241
-45
lines changed

2 files changed

+241
-45
lines changed

src/Fixer/CommentLengthFixer.php

+97-45
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
namespace Contao\EasyCodingStandard\Fixer;
1414

1515
use PhpCsFixer\AbstractFixer;
16+
use PhpCsFixer\DocBlock\DocBlock;
1617
use PhpCsFixer\FixerDefinition\CodeSample;
1718
use PhpCsFixer\FixerDefinition\FixerDefinition;
1819
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
@@ -26,7 +27,7 @@ final class CommentLengthFixer extends AbstractFixer
2627
public function getDefinition(): FixerDefinitionInterface
2728
{
2829
return new FixerDefinition(
29-
'Inline comments should be between 74 and 86 characters per line.',
30+
'Comments should be between 74 and 86 characters long per line.',
3031
[
3132
new CodeSample(
3233
<<<'EOT'
@@ -44,7 +45,7 @@ public function getDefinition(): FixerDefinitionInterface
4445

4546
public function isCandidate(Tokens $tokens): bool
4647
{
47-
return $tokens->isTokenKindFound(T_COMMENT);
48+
return $tokens->isAnyTokenKindsFound([T_COMMENT, T_DOC_COMMENT]);
4849
}
4950

5051
/**
@@ -58,71 +59,122 @@ public function getPriority(): int
5859
protected function applyFix(\SplFileInfo $file, Tokens $tokens): void
5960
{
6061
for ($index = 1, $count = \count($tokens); $index < $count; ++$index) {
61-
if (!$tokens[$index]->isGivenKind(T_COMMENT)) {
62-
continue;
62+
if ($tokens[$index]->isGivenKind(T_COMMENT)) {
63+
$index = $this->handleComment($tokens, $index);
64+
} elseif ($tokens[$index]->isGivenKind(T_DOC_COMMENT)) {
65+
$index = $this->handleDocComment($tokens, $index);
6366
}
67+
}
68+
}
6469

65-
$content = $tokens[$index]->getContent();
70+
private function handleComment(Tokens $tokens, int $index): int
71+
{
72+
$content = $tokens[$index]->getContent();
6673

67-
if (!str_starts_with($content, '// ')) {
68-
continue;
74+
if (!str_starts_with($content, '// ')) {
75+
return $index + 1;
76+
}
77+
78+
// Ignore comments that are on the same line as the code
79+
if (!str_contains($tokens[$index - 1]->getContent(), "\n")) {
80+
return $index + 1;
81+
}
82+
83+
$end = $index;
84+
$comment = substr($content, 3);
85+
86+
while (true) {
87+
$next = $tokens->getNextNonWhitespace($end);
88+
89+
if (null === $next || !$tokens[$next]->isGivenKind(T_COMMENT)) {
90+
break;
6991
}
7092

71-
// Ignore comments that are on the same line as the code
72-
if (!str_contains($tokens[$index - 1]->getContent(), "\n")) {
73-
continue;
93+
$content = $tokens[$next]->getContent();
94+
95+
// Preserve lines that contain URLs or lists
96+
if (preg_match('#^// (https:|- |\d+\. )#', $content)) {
97+
return $next + 1;
7498
}
7599

76-
$end = $index;
77-
$comment = substr($content, 3);
100+
$comment .= ' '.substr($content, 3);
101+
$end = $next;
102+
}
78103

79-
while (true) {
80-
$next = $tokens->getNextNonWhitespace($end);
104+
$lines = $this->getLines($comment, 80, '//');
81105

82-
if (null === $next || !$tokens[$next]->isGivenKind(T_COMMENT)) {
83-
break;
84-
}
106+
if (substr_count((string) end($lines), ' ') < 2) {
107+
$lines = $this->getLines($comment, 86, '//');
85108

86-
$content = $tokens[$next]->getContent();
109+
if (substr_count((string) end($lines), ' ') < 2) {
110+
$lines = $this->getLines($comment, 74, '//');
111+
}
112+
}
87113

88-
// Preserve lines that contain only a URL
89-
if (str_starts_with($content, '// https:')) {
90-
continue 2;
91-
}
114+
$new = [];
115+
$indent = $this->getIndent($tokens, $index);
92116

93-
$comment .= ' '.substr($content, 3);
94-
$end = $next;
117+
for ($i = 0, $c = \count($lines); $i < $c; ++$i) {
118+
if ($i > 0) {
119+
$new[] = new Token([T_WHITESPACE, $indent]);
95120
}
96121

97-
$lines = $this->getLines($comment, 80);
122+
$new[] = new Token([T_COMMENT, $lines[$i]]);
123+
}
98124

99-
if (substr_count((string) end($lines), ' ') < 2) {
100-
$lines = $this->getLines($comment, 86);
125+
$tokens->clearRange($index, $end);
126+
$tokens->insertAt($index, $new);
101127

102-
if (substr_count((string) end($lines), ' ') < 2) {
103-
$lines = $this->getLines($comment, 74);
104-
}
105-
}
128+
return $end + 1;
129+
}
130+
131+
private function handleDocComment(Tokens $tokens, int $index): int
132+
{
133+
$text = null;
134+
$newLines = [];
135+
136+
$docBlock = new DocBlock($tokens[$index]->getContent());
137+
$lines = $docBlock->getLines();
138+
$content = end($lines)->getContent();
139+
$indent = substr($content, 0, strpos($content, '*'));
106140

107-
$new = [];
108-
$indent = $this->getIndent($tokens, $index);
141+
foreach ($lines as $line) {
142+
$content = $line->getContent();
109143

110-
for ($i = 0, $c = \count($lines); $i < $c; ++$i) {
111-
if ($i > 0) {
112-
$new[] = new Token([T_WHITESPACE, $indent]);
144+
// Preserve lines that contain URLs, lists or indented content
145+
if ($line->containsATag() || !$line->containsUsefulContent() || preg_match('#^ *\* ( |https:|- |\d+\. )#', $content)) {
146+
if ($text) {
147+
$comment = rtrim($text);
148+
$lns = $this->getLines($comment, 80, '*');
149+
150+
if (substr_count((string) end($lns), ' ') < 2) {
151+
$lns = $this->getLines($comment, 86, '*');
152+
153+
if (substr_count((string) end($lns), ' ') < 2) {
154+
$lns = $this->getLines($comment, 74, '*');
155+
}
156+
}
157+
158+
foreach ($lns as $ln) {
159+
$newLines[] = "$indent$ln\n";
160+
}
161+
162+
$text = null;
113163
}
114164

115-
$new[] = new Token([T_COMMENT, $lines[$i]]);
165+
$newLines[] = $content;
166+
continue;
116167
}
117168

118-
$tokens->clearRange($index, $end);
119-
$tokens->insertAt($index, $new);
120-
121-
$index = $end + 1;
169+
$text .= rtrim(substr($content, \strlen($indent) + 2)).' ';
122170
}
171+
172+
$tokens->offsetSet($index, new Token([T_DOC_COMMENT, implode('', $newLines)]));
173+
174+
return $index + 1;
123175
}
124176

125-
private function getLines(string $comment, int $length): array
177+
private function getLines(string $comment, int $length, string $prefix = ''): array
126178
{
127179
$lines = [];
128180
$i = 0;
@@ -132,11 +184,11 @@ private function getLines(string $comment, int $length): array
132184
$word = array_shift($chunks);
133185

134186
if (!isset($lines[$i])) {
135-
$lines[$i] = '//';
187+
$lines[$i] = $prefix;
136188
}
137189

138-
if ('//' !== $lines[$i] && \strlen($lines[$i]) + \strlen($word) > $length) {
139-
$lines[++$i] = '//';
190+
if ($prefix !== $lines[$i] && \strlen($lines[$i]) + \strlen($word) > $length) {
191+
$lines[++$i] = $prefix;
140192
}
141193

142194
$lines[$i] .= " $word";

0 commit comments

Comments
 (0)