Skip to content

Commit bd5566e

Browse files
committed
Make #[Override] attribute errors fixable
1 parent 7534ee1 commit bd5566e

File tree

4 files changed

+118
-1
lines changed

4 files changed

+118
-1
lines changed

src/Rules/Methods/OverridingMethodRule.php

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\Rules\Methods;
44

55
use PhpParser\Node;
6+
use PhpParser\Node\Attribute;
67
use PHPStan\Analyser\Scope;
78
use PHPStan\Node\InClassMethodNode;
89
use PHPStan\Php\PhpVersion;
@@ -94,6 +95,10 @@ public function processNode(Node $node, Scope $scope): array
9495
))
9596
->nonIgnorable()
9697
->identifier('method.override')
98+
->fixNode($node->getOriginalNode(), function (Node\Stmt\ClassMethod $method) {
99+
$method->attrGroups = $this->filterOverrideAttribute($method->attrGroups);
100+
return $method;
101+
})
97102
->build(),
98103
];
99104
}
@@ -116,7 +121,16 @@ public function processNode(Node $node, Scope $scope): array
116121
$method->getName(),
117122
$prototypeDeclaringClass->getDisplayName(true),
118123
$prototype->getName(),
119-
))->identifier('method.missingOverride')->build();
124+
))
125+
->identifier('method.missingOverride')
126+
->fixNode($node->getOriginalNode(), static function (Node\Stmt\ClassMethod $method) {
127+
$method->attrGroups[] = new Node\AttributeGroup([
128+
new Attribute(new Node\Name\FullyQualified('Override')),
129+
]);
130+
131+
return $method;
132+
})
133+
->build();
120134
}
121135
if ($prototype->isFinalByKeyword()->yes()) {
122136
$messages[] = RuleErrorBuilder::message(sprintf(
@@ -278,6 +292,30 @@ public function processNode(Node $node, Scope $scope): array
278292
return $this->addErrors($messages, $node, $scope);
279293
}
280294

295+
/**
296+
* @param Node\AttributeGroup[] $attrGroups
297+
* @return Node\AttributeGroup[]
298+
*/
299+
private function filterOverrideAttribute(array $attrGroups): array
300+
{
301+
foreach ($attrGroups as $i => $attrGroup) {
302+
foreach ($attrGroup->attrs as $j => $attr) {
303+
if ($attr->name->toLowerString() !== 'override') {
304+
continue;
305+
}
306+
307+
unset($attrGroup->attrs[$j]);
308+
if (count($attrGroup->attrs) !== 0) {
309+
continue;
310+
}
311+
312+
unset($attrGroups[$i]);
313+
}
314+
}
315+
316+
return $attrGroups;
317+
}
318+
281319
/**
282320
* @param list<IdentifierRuleError> $errors
283321
* @return list<IdentifierRuleError>

tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,4 +834,15 @@ public function testSimpleXmlElementChildClass(): void
834834
$this->analyse([__DIR__ . '/data/simple-xml-element-child.php'], []);
835835
}
836836

837+
public function testFixOverride(): void
838+
{
839+
if (PHP_VERSION_ID < 80300) {
840+
$this->markTestSkipped('Test requires PHP 8.3.');
841+
}
842+
843+
$this->phpVersionId = PHP_VERSION_ID;
844+
$this->checkMissingOverrideMethodAttribute = true;
845+
$this->fix(__DIR__ . '/data/fix-override-attribute.php', __DIR__ . '/data/fix-override-attribute.php.fixed');
846+
}
847+
837848
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php // lint >= 8.3
2+
3+
namespace FixOverrideAttribute;
4+
5+
class Foo
6+
{
7+
8+
public function doFoo(): void
9+
{
10+
11+
}
12+
13+
}
14+
15+
class Bar extends Foo
16+
{
17+
18+
public function doFoo(): void
19+
{
20+
21+
}
22+
23+
24+
public function doBar(): void
25+
{
26+
27+
}
28+
29+
#[\Override]
30+
public function doBaz(): void
31+
{
32+
}
33+
34+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php // lint >= 8.3
2+
3+
namespace FixOverrideAttribute;
4+
5+
class Foo
6+
{
7+
8+
public function doFoo(): void
9+
{
10+
11+
}
12+
13+
}
14+
15+
class Bar extends Foo
16+
{
17+
18+
#[\Override]
19+
public function doFoo(): void
20+
{
21+
22+
}
23+
24+
25+
public function doBar(): void
26+
{
27+
28+
}
29+
30+
public function doBaz(): void
31+
{
32+
}
33+
34+
}

0 commit comments

Comments
 (0)