Skip to content

Commit

Permalink
PHP 8.3: Support for #[Override] attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Nov 13, 2023
1 parent ae6b2aa commit e9a5639
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Php/PhpVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,9 @@ public function supportsAbstractTraitMethods(): bool
return $this->versionId >= 80000;
}

public function supportsOverrideAttribute(): bool
{
return $this->versionId >= 80300;
}

}
24 changes: 24 additions & 0 deletions src/Rules/Methods/OverridingMethodRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ public function processNode(Node $node, Scope $scope): array
}
}
}

if ($this->phpVersion->supportsOverrideAttribute() && $this->hasOverrideAttribute($node->getOriginalNode())) {
return [
RuleErrorBuilder::message(sprintf(
'Method %s::%s() has #[Override] attribute but does not override any method.',
$method->getDeclaringClass()->getDisplayName(),
$method->getName(),
))->nonIgnorable()->build(),
];
}

return [];
}

Expand Down Expand Up @@ -267,6 +278,19 @@ private function hasReturnTypeWillChangeAttribute(Node\Stmt\ClassMethod $method)
return false;
}

private function hasOverrideAttribute(Node\Stmt\ClassMethod $method): bool
{
foreach ($method->attrGroups as $attrGroup) {
foreach ($attrGroup->attrs as $attr) {
if ($attr->name->toLowerString() === 'override') {
return true;
}
}
}

return false;
}

private function findPrototype(ClassReflection $classReflection, string $methodName): ?ExtendedMethodReflection
{
foreach ($classReflection->getImmediateInterfaces() as $immediateInterface) {
Expand Down
15 changes: 15 additions & 0 deletions tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -724,4 +724,19 @@ public function testTraits(): void
$this->analyse([__DIR__ . '/data/overriding-trait-methods.php'], $errors);
}

public function testOverrideAttribute(): void
{
if (PHP_VERSION_ID < 80300) {
$this->markTestSkipped('Test requires PHP 8.3.');
}

$this->phpVersionId = PHP_VERSION_ID;
$this->analyse([__DIR__ . '/data/override-attribute.php'], [
[
'Method OverrideAttribute\Bar::test2() has #[Override] attribute but does not override any method.',
24,
],
]);
}

}
30 changes: 30 additions & 0 deletions tests/PHPStan/Rules/Methods/data/override-attribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace OverrideAttribute;

class Foo
{

public function test(): void
{

}

}

class Bar extends Foo
{

#[\Override]
public function test(): void
{

}

#[\Override]
public function test2(): void
{

}

}

0 comments on commit e9a5639

Please sign in to comment.