From 5de526650985cce3c27c9934461df79ef5c7fd16 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 8 Aug 2024 10:38:30 +0200 Subject: [PATCH] [docblock] Remove commment duplicating class name (#55) --- src/DocBlock/UselessDocBlockCleaner.php | 15 ++++- .../RemoveUselessDefaultCommentFixer.php | 8 ++- src/Fixer/Naming/ClassNameResolver.php | 60 +++++++++++++++++++ .../Fixture/name_class_itself.php.inc | 23 +++++++ .../Fixture/trait_name_class_itself.php.inc | 28 +++++++++ 5 files changed, 131 insertions(+), 3 deletions(-) create mode 100644 src/Fixer/Naming/ClassNameResolver.php create mode 100644 tests/Fixer/Commenting/RemoveUselessDefaultCommentFixer/Fixture/name_class_itself.php.inc create mode 100644 tests/Fixer/Commenting/RemoveUselessDefaultCommentFixer/Fixture/trait_name_class_itself.php.inc diff --git a/src/DocBlock/UselessDocBlockCleaner.php b/src/DocBlock/UselessDocBlockCleaner.php index 9700daa9..caa8ae98 100644 --- a/src/DocBlock/UselessDocBlockCleaner.php +++ b/src/DocBlock/UselessDocBlockCleaner.php @@ -60,13 +60,17 @@ final class UselessDocBlockCleaner */ private const COMMENT_CONSTRUCTOR_CLASS_REGEX = '#^(\/\/|(\s|\*)+)(\s\w+\s)?constructor(\.)?$#i'; - public function clearDocTokenContent(Token $currentToken): string + public function clearDocTokenContent(Token $currentToken, ?string $classLikeName): string { $docContent = $currentToken->getContent(); $cleanedCommentLines = []; foreach (explode("\n", $docContent) as $key => $commentLine) { + if ($this->isClassLikeName($commentLine, $classLikeName)) { + continue; + } + foreach (self::CLEANING_REGEXES as $cleaningRegex) { $commentLine = Strings::replace($commentLine, $cleaningRegex); } @@ -100,4 +104,13 @@ private function isEmptyDocblock(array $commentLines): bool return $startCommentLine === '/**' && trim($endCommentLine) === '*/'; } + + private function isClassLikeName(string $commentLine, ?string $classLikeName): bool + { + if ($classLikeName === null) { + return false; + } + + return trim($commentLine, '* ') === $classLikeName; + } } diff --git a/src/Fixer/Commenting/RemoveUselessDefaultCommentFixer.php b/src/Fixer/Commenting/RemoveUselessDefaultCommentFixer.php index 94fd3e90..79713c45 100644 --- a/src/Fixer/Commenting/RemoveUselessDefaultCommentFixer.php +++ b/src/Fixer/Commenting/RemoveUselessDefaultCommentFixer.php @@ -11,6 +11,7 @@ use SplFileInfo; use Symplify\CodingStandard\DocBlock\UselessDocBlockCleaner; use Symplify\CodingStandard\Fixer\AbstractSymplifyFixer; +use Symplify\CodingStandard\Fixer\Naming\ClassNameResolver; use Symplify\CodingStandard\TokenRunner\Traverser\TokenReverser; use Symplify\RuleDocGenerator\Contract\DocumentedRuleInterface; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -28,7 +29,8 @@ final class RemoveUselessDefaultCommentFixer extends AbstractSymplifyFixer imple public function __construct( private readonly UselessDocBlockCleaner $uselessDocBlockCleaner, - private readonly TokenReverser $tokenReverser + private readonly TokenReverser $tokenReverser, + private readonly ClassNameResolver $classNameResolver, ) { } @@ -63,8 +65,10 @@ public function fix(SplFileInfo $fileInfo, Tokens $tokens): void continue; } + $classLikeName = $this->classNameResolver->resolveClassName($fileInfo, $tokens); + $originalContent = $token->getContent(); - $cleanedDocContent = $this->uselessDocBlockCleaner->clearDocTokenContent($token); + $cleanedDocContent = $this->uselessDocBlockCleaner->clearDocTokenContent($token, $classLikeName); if ($cleanedDocContent === '') { // remove token diff --git a/src/Fixer/Naming/ClassNameResolver.php b/src/Fixer/Naming/ClassNameResolver.php new file mode 100644 index 00000000..cad8e7b6 --- /dev/null +++ b/src/Fixer/Naming/ClassNameResolver.php @@ -0,0 +1,60 @@ + + */ + private array $classNameByFilePath = []; + + /** + * @param Tokens $tokens + */ + public function resolveClassName(SplFileInfo $splFileInfo, Tokens $tokens): ?string + { + $filePath = $splFileInfo->getRealPath(); + + if (isset($this->classNameByFilePath[$filePath])) { + return $this->classNameByFilePath[$filePath]; + } + + $classLikeName = $this->resolveFromTokens($tokens); + if (! is_string($classLikeName)) { + return null; + } + + $this->classNameByFilePath[$filePath] = $classLikeName; + + return $classLikeName; + } + + /** + * @param Tokens $tokens + */ + private function resolveFromTokens(Tokens $tokens): ?string + { + foreach ($tokens as $position => $token) { + if (! $token->isGivenKind([T_CLASS, T_TRAIT, T_INTERFACE])) { + continue; + } + + $nextNextMeaningfulTokenIndex = $tokens->getNextMeaningfulToken($position + 1); + $nextNextMeaningfulToken = $tokens[$nextNextMeaningfulTokenIndex]; + + // skip anonymous classes + if (! $nextNextMeaningfulToken->isGivenKind(T_STRING)) { + continue; + } + + return $nextNextMeaningfulToken->getContent(); + } + + return null; + } +} diff --git a/tests/Fixer/Commenting/RemoveUselessDefaultCommentFixer/Fixture/name_class_itself.php.inc b/tests/Fixer/Commenting/RemoveUselessDefaultCommentFixer/Fixture/name_class_itself.php.inc new file mode 100644 index 00000000..01a5c4ca --- /dev/null +++ b/tests/Fixer/Commenting/RemoveUselessDefaultCommentFixer/Fixture/name_class_itself.php.inc @@ -0,0 +1,23 @@ + +----- + diff --git a/tests/Fixer/Commenting/RemoveUselessDefaultCommentFixer/Fixture/trait_name_class_itself.php.inc b/tests/Fixer/Commenting/RemoveUselessDefaultCommentFixer/Fixture/trait_name_class_itself.php.inc new file mode 100644 index 00000000..f7d773ec --- /dev/null +++ b/tests/Fixer/Commenting/RemoveUselessDefaultCommentFixer/Fixture/trait_name_class_itself.php.inc @@ -0,0 +1,28 @@ + +----- +