Skip to content

Commit 53fa635

Browse files
authored
[Annotation] Add RemovePropertyVariableNameDescriptionFixer (#68)
1 parent d29d5ba commit 53fa635

File tree

10 files changed

+223
-3
lines changed

10 files changed

+223
-3
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,22 @@ Fixes @param, @return, `@var` and inline `@var` annotations broken formats
145145

146146
<br>
147147

148+
## RemovePropertyVariableNameDescriptionFixer
149+
150+
Remove docblock descriptions which duplicate their property name
151+
152+
- class: [`Symplify\CodingStandard\Fixer\Annotation\RemovePropertyVariableNameDescriptionFixer`](../src/Fixer/Annotation/RemovePropertyVariableNameDescriptionFixer.php)
153+
154+
```diff
155+
/**
156+
- * @var string $name
157+
+ * @var string
158+
*/
159+
private $name;
160+
```
161+
162+
<br>
163+
148164
## RemoveMethodNameDuplicateDescriptionFixer
149165

150166
Remove docblock descriptions which duplicate their method name

config/symplify.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
declare(strict_types=1);
44

55
use PhpCsFixer\Fixer\Phpdoc\GeneralPhpdocAnnotationRemoveFixer;
6-
use Symplify\CodingStandard\Fixer\Annotation\RemovePHPStormAnnotationFixer;
76
use Symplify\CodingStandard\Fixer\Annotation\RemoveMethodNameDuplicateDescriptionFixer;
7+
use Symplify\CodingStandard\Fixer\Annotation\RemovePHPStormAnnotationFixer;
8+
use Symplify\CodingStandard\Fixer\Annotation\RemovePropertyVariableNameDescriptionFixer;
89
use Symplify\CodingStandard\Fixer\ArrayNotation\ArrayListItemNewlineFixer;
910
use Symplify\CodingStandard\Fixer\ArrayNotation\ArrayOpenerAndCloserNewlineFixer;
1011
use Symplify\CodingStandard\Fixer\Commenting\ParamReturnAndVarTagMalformsFixer;
@@ -23,6 +24,7 @@
2324
ParamReturnAndVarTagMalformsFixer::class,
2425
RemoveUselessDefaultCommentFixer::class,
2526
RemoveMethodNameDuplicateDescriptionFixer::class,
27+
RemovePropertyVariableNameDescriptionFixer::class,
2628

2729
// arrays
2830
ArrayListItemNewlineFixer::class,

src/Fixer/Annotation/RemoveMethodNameDuplicateDescriptionFixer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public function fix(SplFileInfo $fileInfo, Tokens $tokens): void
6262
}
6363

6464
$methodName = $this->methodNameResolver->resolve($tokens, $index);
65-
if (is_null($methodName)) {
65+
if ($methodName === null) {
6666
continue;
6767
}
6868

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Symplify\CodingStandard\Fixer\Annotation;
6+
7+
use Nette\Utils\Strings;
8+
use PhpCsFixer\FixerDefinition\FixerDefinition;
9+
use PhpCsFixer\FixerDefinition\FixerDefinitionInterface;
10+
use PhpCsFixer\Tokenizer\Token;
11+
use PhpCsFixer\Tokenizer\Tokens;
12+
use SplFileInfo;
13+
use Symplify\CodingStandard\Fixer\AbstractSymplifyFixer;
14+
use Symplify\CodingStandard\Fixer\Naming\PropertyNameResolver;
15+
use Symplify\CodingStandard\TokenRunner\Traverser\TokenReverser;
16+
17+
/**
18+
* @see \Symplify\CodingStandard\Tests\Fixer\Annotation\RemovePropertyVariableNameDescriptionFixer\RemovePropertyVariableNameDescriptionFixerTest
19+
*/
20+
final class RemovePropertyVariableNameDescriptionFixer extends AbstractSymplifyFixer
21+
{
22+
/**
23+
* @var string
24+
*/
25+
private const ERROR_MESSAGE = 'Remove useless "$variable" from @var tag';
26+
27+
private readonly PropertyNameResolver $propertyNameResolver;
28+
29+
public function __construct(
30+
private readonly TokenReverser $tokenReverser
31+
) {
32+
$this->propertyNameResolver = new PropertyNameResolver();
33+
}
34+
35+
public function getDefinition(): FixerDefinitionInterface
36+
{
37+
return new FixerDefinition(self::ERROR_MESSAGE, []);
38+
}
39+
40+
/**
41+
* @param Tokens<Token> $tokens
42+
*/
43+
public function isCandidate(Tokens $tokens): bool
44+
{
45+
if (! $tokens->isTokenKindFound(T_VARIABLE)) {
46+
return false;
47+
}
48+
49+
return $tokens->isAnyTokenKindsFound([T_DOC_COMMENT, T_COMMENT]);
50+
}
51+
52+
/**
53+
* @param Tokens<Token> $tokens
54+
*/
55+
public function fix(SplFileInfo $fileInfo, Tokens $tokens): void
56+
{
57+
$reversedTokens = $this->tokenReverser->reverse($tokens);
58+
59+
foreach ($reversedTokens as $index => $token) {
60+
if (! $token->isGivenKind([T_DOC_COMMENT, T_COMMENT])) {
61+
continue;
62+
}
63+
64+
$propertyName = $this->propertyNameResolver->resolve($tokens, $index);
65+
if ($propertyName === null) {
66+
continue;
67+
}
68+
69+
// skip if not setter or getter
70+
$originalDocContent = $token->getContent();
71+
72+
$hasChanged = false;
73+
74+
$docblockLines = explode("\n", $originalDocContent);
75+
foreach ($docblockLines as $key => $docblockLine) {
76+
if (! str_ends_with($docblockLine, ' ' . $propertyName)) {
77+
continue;
78+
}
79+
80+
// remove last x characters
81+
$docblockLine = Strings::substring($docblockLine, 0, -strlen(' ' . $propertyName));
82+
83+
$hasChanged = true;
84+
$docblockLines[$key] = rtrim($docblockLine);
85+
}
86+
87+
if (! $hasChanged) {
88+
continue;
89+
}
90+
91+
$tokens[$index] = new Token([T_DOC_COMMENT, implode("\n", $docblockLines)]);
92+
}
93+
}
94+
}

src/Fixer/Naming/MethodNameResolver.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
use PhpCsFixer\Tokenizer\Token;
88
use PhpCsFixer\Tokenizer\Tokens;
9-
use SplFileInfo;
109

1110
final class MethodNameResolver
1211
{
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Symplify\CodingStandard\Fixer\Naming;
6+
7+
use PhpCsFixer\Tokenizer\Token;
8+
use PhpCsFixer\Tokenizer\Tokens;
9+
10+
final class PropertyNameResolver
11+
{
12+
/**
13+
* @param Tokens<Token> $tokens
14+
*/
15+
public function resolve(Tokens $tokens, int $currentPosition): ?string
16+
{
17+
foreach ($tokens as $position => $token) {
18+
if ($position <= $currentPosition) {
19+
continue;
20+
}
21+
22+
if (! $token->isGivenKind([T_VARIABLE])) {
23+
continue;
24+
}
25+
26+
return $token->getContent();
27+
}
28+
29+
return null;
30+
}
31+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Symplify\CodingStandard\Tests\Fixer\Annotation\RemovePropertyVariableNameDescriptionFixer\Fixture;
4+
5+
final class SimpleAnnotation
6+
{
7+
/**
8+
* @var string $name
9+
*/
10+
public $name;
11+
}
12+
13+
?>
14+
-----
15+
<?php
16+
17+
namespace Symplify\CodingStandard\Tests\Fixer\Annotation\RemovePropertyVariableNameDescriptionFixer\Fixture;
18+
19+
final class SimpleAnnotation
20+
{
21+
/**
22+
* @var string
23+
*/
24+
public $name;
25+
}
26+
27+
?>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Symplify\CodingStandard\Tests\Fixer\Annotation\RemovePropertyVariableNameDescriptionFixer\Fixture;
4+
5+
final class SkipNameInTheMiddle
6+
{
7+
/**
8+
* @var string not $name my
9+
*/
10+
public $name;
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Symplify\CodingStandard\Tests\Fixer\Annotation\RemovePropertyVariableNameDescriptionFixer;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Symplify\EasyCodingStandard\Testing\PHPUnit\AbstractCheckerTestCase;
10+
11+
final class RemovePropertyVariableNameDescriptionFixerTest extends AbstractCheckerTestCase
12+
{
13+
#[DataProvider('provideData')]
14+
public function test(string $filePath): void
15+
{
16+
$this->doTestFile($filePath);
17+
}
18+
19+
public static function provideData(): Iterator
20+
{
21+
return self::yieldFiles(__DIR__ . '/Fixture');
22+
}
23+
24+
public function provideConfig(): string
25+
{
26+
return __DIR__ . '/config/configured_rule.php';
27+
}
28+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Symplify\CodingStandard\Fixer\Annotation\RemovePropertyVariableNameDescriptionFixer;
6+
use Symplify\EasyCodingStandard\Config\ECSConfig;
7+
8+
return static function (ECSConfig $ecsConfig): void {
9+
$ecsConfig->rules([
10+
RemovePropertyVariableNameDescriptionFixer::class,
11+
]);
12+
};

0 commit comments

Comments
 (0)