Skip to content

Commit e9a5639

Browse files
committed
PHP 8.3: Support for #[Override] attribute
1 parent ae6b2aa commit e9a5639

File tree

4 files changed

+74
-0
lines changed

4 files changed

+74
-0
lines changed

src/Php/PhpVersion.php

+5
Original file line numberDiff line numberDiff line change
@@ -252,4 +252,9 @@ public function supportsAbstractTraitMethods(): bool
252252
return $this->versionId >= 80000;
253253
}
254254

255+
public function supportsOverrideAttribute(): bool
256+
{
257+
return $this->versionId >= 80300;
258+
}
259+
255260
}

src/Rules/Methods/OverridingMethodRule.php

+24
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,17 @@ public function processNode(Node $node, Scope $scope): array
7979
}
8080
}
8181
}
82+
83+
if ($this->phpVersion->supportsOverrideAttribute() && $this->hasOverrideAttribute($node->getOriginalNode())) {
84+
return [
85+
RuleErrorBuilder::message(sprintf(
86+
'Method %s::%s() has #[Override] attribute but does not override any method.',
87+
$method->getDeclaringClass()->getDisplayName(),
88+
$method->getName(),
89+
))->nonIgnorable()->build(),
90+
];
91+
}
92+
8293
return [];
8394
}
8495

@@ -267,6 +278,19 @@ private function hasReturnTypeWillChangeAttribute(Node\Stmt\ClassMethod $method)
267278
return false;
268279
}
269280

281+
private function hasOverrideAttribute(Node\Stmt\ClassMethod $method): bool
282+
{
283+
foreach ($method->attrGroups as $attrGroup) {
284+
foreach ($attrGroup->attrs as $attr) {
285+
if ($attr->name->toLowerString() === 'override') {
286+
return true;
287+
}
288+
}
289+
}
290+
291+
return false;
292+
}
293+
270294
private function findPrototype(ClassReflection $classReflection, string $methodName): ?ExtendedMethodReflection
271295
{
272296
foreach ($classReflection->getImmediateInterfaces() as $immediateInterface) {

tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php

+15
Original file line numberDiff line numberDiff line change
@@ -724,4 +724,19 @@ public function testTraits(): void
724724
$this->analyse([__DIR__ . '/data/overriding-trait-methods.php'], $errors);
725725
}
726726

727+
public function testOverrideAttribute(): void
728+
{
729+
if (PHP_VERSION_ID < 80300) {
730+
$this->markTestSkipped('Test requires PHP 8.3.');
731+
}
732+
733+
$this->phpVersionId = PHP_VERSION_ID;
734+
$this->analyse([__DIR__ . '/data/override-attribute.php'], [
735+
[
736+
'Method OverrideAttribute\Bar::test2() has #[Override] attribute but does not override any method.',
737+
24,
738+
],
739+
]);
740+
}
741+
727742
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace OverrideAttribute;
4+
5+
class Foo
6+
{
7+
8+
public function test(): void
9+
{
10+
11+
}
12+
13+
}
14+
15+
class Bar extends Foo
16+
{
17+
18+
#[\Override]
19+
public function test(): void
20+
{
21+
22+
}
23+
24+
#[\Override]
25+
public function test2(): void
26+
{
27+
28+
}
29+
30+
}

0 commit comments

Comments
 (0)