From b6bb114825897346566fec0c2f55ac3f97ab4aa1 Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Mon, 5 Oct 2026 21:54:09 +0200 Subject: [PATCH 1/4] Check the #[\Override] attribute on class constants and enum cases Closes phpstan/phpstan#15370 --- conf/config.neon | 1 + conf/parametersSchema.neon | 1 + src/Php/PhpVersions.php | 5 + .../OverrideAttributeOnConstantCheck.php | 155 ++++++++++++++++++ .../Constants/OverridingConstantRule.php | 18 +- .../EnumCases/OverridingEnumCaseRule.php | 67 ++++++++ .../Constants/OverridingConstantRuleTest.php | 83 +++++++++- .../data/constant-override-attr-fix.php | 16 ++ .../data/constant-override-attr-fix.php.fixed | 16 ++ .../Constants/data/constant-override-attr.php | 70 ++++++++ .../EnumCases/OverridingEnumCaseRuleTest.php | 45 +++++ .../data/enum-case-override-attr.php | 28 ++++ 12 files changed, 503 insertions(+), 2 deletions(-) create mode 100644 src/Rules/Constants/OverrideAttributeOnConstantCheck.php create mode 100644 src/Rules/EnumCases/OverridingEnumCaseRule.php create mode 100644 tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php create mode 100644 tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php.fixed create mode 100644 tests/PHPStan/Rules/Constants/data/constant-override-attr.php create mode 100644 tests/PHPStan/Rules/EnumCases/OverridingEnumCaseRuleTest.php create mode 100644 tests/PHPStan/Rules/EnumCases/data/enum-case-override-attr.php diff --git a/conf/config.neon b/conf/config.neon index 52860b21fe9..6e4f730cf69 100644 --- a/conf/config.neon +++ b/conf/config.neon @@ -108,6 +108,7 @@ parameters: reportPossiblyNonexistentConstantArrayOffset: false checkMissingOverrideMethodAttribute: false checkMissingOverridePropertyAttribute: null + checkMissingOverrideConstantAttribute: null mixinExcludeClasses: [] scanFiles: [] scanDirectories: [] diff --git a/conf/parametersSchema.neon b/conf/parametersSchema.neon index 3bae9593991..ce1f5d6cf64 100644 --- a/conf/parametersSchema.neon +++ b/conf/parametersSchema.neon @@ -112,6 +112,7 @@ parametersSchema: reportPossiblyNonexistentConstantArrayOffset: bool() checkMissingOverrideMethodAttribute: bool() checkMissingOverridePropertyAttribute: schema(bool(), nullable()) + checkMissingOverrideConstantAttribute: schema(bool(), nullable()) parallel: structure([ jobSize: int(), processTimeout: float(), diff --git a/src/Php/PhpVersions.php b/src/Php/PhpVersions.php index 84bd2c3f5f2..2344a53f93f 100644 --- a/src/Php/PhpVersions.php +++ b/src/Php/PhpVersions.php @@ -93,6 +93,11 @@ public function supportsOverrideAttributeOnProperty(): TrinaryLogic return IntegerRangeType::fromInterval(80500, null)->isSuperTypeOf($this->phpVersions)->result; } + public function supportsOverrideAttributeOnClassConstant(): TrinaryLogic + { + return IntegerRangeType::fromInterval(80600, null)->isSuperTypeOf($this->phpVersions)->result; + } + public function supportsAttributesOnGlobalConstants(): TrinaryLogic { return IntegerRangeType::fromInterval(80500, null)->isSuperTypeOf($this->phpVersions)->result; diff --git a/src/Rules/Constants/OverrideAttributeOnConstantCheck.php b/src/Rules/Constants/OverrideAttributeOnConstantCheck.php new file mode 100644 index 00000000000..f0fb90ad43d --- /dev/null +++ b/src/Rules/Constants/OverrideAttributeOnConstantCheck.php @@ -0,0 +1,155 @@ + + */ + public function check( + Scope $scope, + ClassReflection $classReflection, + string $constantName, + ?ClassConstantReflection $prototype, + array $attrGroups, + ?Node $fixableNode, + bool $isEnumCase, + ): array + { + $description = $isEnumCase ? 'Enum case' : 'Constant'; + + if ($prototype === null) { + if (!$this->hasOverrideAttribute($attrGroups)) { + return []; + } + + $errorBuilder = RuleErrorBuilder::message(sprintf( + '%s %s::%s has #[\Override] attribute but does not override any constant.', + $description, + $classReflection->getDisplayName(false), + $constantName, + )) + ->nonIgnorable() + ->identifier($isEnumCase ? 'enum.caseOverride' : 'classConstant.override'); + + if ($fixableNode !== null) { + $errorBuilder->fixNode($fixableNode, function (Node\Stmt\ClassConst|Node\Stmt\EnumCase $node) { + $node->attrGroups = $this->filterOverrideAttribute($node->attrGroups); + return $node; + }); + } + + return [$errorBuilder->build()]; + } + + if ( + $scope->isInTrait() + || $this->hasOverrideAttribute($attrGroups) + || !$this->isMissingOverrideChecked($scope) + ) { + return []; + } + + $errorBuilder = RuleErrorBuilder::message(sprintf( + '%s %s::%s overrides constant %s::%s but is missing the #[\Override] attribute.', + $description, + $classReflection->getDisplayName(false), + $constantName, + $prototype->getDeclaringClass()->getDisplayName(false), + $prototype->getName(), + )) + ->identifier($isEnumCase ? 'enum.caseMissingOverride' : 'classConstant.missingOverride'); + + if ($fixableNode !== null) { + $errorBuilder->fixNode($fixableNode, static function (Node\Stmt\ClassConst|Node\Stmt\EnumCase $node) { + $node->attrGroups[] = new Node\AttributeGroup([ + new Attribute(new Node\Name\FullyQualified('Override')), + ]); + + return $node; + }); + } + + return [$errorBuilder->build()]; + } + + private function isMissingOverrideChecked(Scope $scope): bool + { + if ($this->checkMissingOverrideConstantAttribute !== null) { + return $this->checkMissingOverrideConstantAttribute; + } + + return $this->checkMissingOverrideMethodAttribute + && $scope->getPhpVersion()->supportsOverrideAttributeOnClassConstant()->yes(); + } + + /** + * @param Node\AttributeGroup[] $attrGroups + * @return Node\AttributeGroup[] + */ + private function filterOverrideAttribute(array $attrGroups): array + { + foreach ($attrGroups as $i => $attrGroup) { + foreach ($attrGroup->attrs as $j => $attr) { + if ($attr->name->toLowerString() !== 'override') { + continue; + } + + unset($attrGroup->attrs[$j]); + if (count($attrGroup->attrs) !== 0) { + continue; + } + + unset($attrGroups[$i]); + } + } + + return $attrGroups; + } + + /** + * @param Node\AttributeGroup[] $attrGroups + */ + private function hasOverrideAttribute(array $attrGroups): bool + { + foreach ($attrGroups as $attrGroup) { + foreach ($attrGroup->attrs as $attr) { + if ($attr->name->toLowerString() === 'override') { + return true; + } + } + } + + return false; + } + +} diff --git a/src/Rules/Constants/OverridingConstantRule.php b/src/Rules/Constants/OverridingConstantRule.php index ad538c34688..9af77b6622f 100644 --- a/src/Rules/Constants/OverridingConstantRule.php +++ b/src/Rules/Constants/OverridingConstantRule.php @@ -14,6 +14,7 @@ use PHPStan\ShouldNotHappenException; use PHPStan\Type\VerbosityLevel; use function array_merge; +use function count; use function sprintf; /** @@ -26,6 +27,7 @@ final class OverridingConstantRule implements Rule public function __construct( #[AutowiredParameter] private bool $checkPhpDocMethodSignatures, + private OverrideAttributeOnConstantCheck $overrideAttributeCheck, ) { } @@ -41,10 +43,24 @@ public function processNode(Node $node, Scope $scope): array throw new ShouldNotHappenException(); } + $classReflection = $scope->getClassReflection(); + + // the attributes of `const A = 1, B = 2;` apply to every constant, so only fix single declarations + $fixableNode = count($node->consts) === 1 ? $node : null; + $errors = []; foreach ($node->consts as $const) { $constantName = $const->name->toString(); - $errors = array_merge($errors, $this->processSingleConstant($scope->getClassReflection(), $constantName)); + $errors = array_merge($errors, $this->overrideAttributeCheck->check( + $scope, + $classReflection, + $constantName, + $this->findPrototype($classReflection, $constantName), + $node->attrGroups, + $fixableNode, + false, + )); + $errors = array_merge($errors, $this->processSingleConstant($classReflection, $constantName)); } return $errors; diff --git a/src/Rules/EnumCases/OverridingEnumCaseRule.php b/src/Rules/EnumCases/OverridingEnumCaseRule.php new file mode 100644 index 00000000000..7d5c6989e46 --- /dev/null +++ b/src/Rules/EnumCases/OverridingEnumCaseRule.php @@ -0,0 +1,67 @@ + + */ +#[RegisteredRule(level: 0)] +final class OverridingEnumCaseRule implements Rule +{ + + public function __construct(private OverrideAttributeOnConstantCheck $overrideAttributeCheck) + { + } + + public function getNodeType(): string + { + return Node\Stmt\EnumCase::class; + } + + public function processNode(Node $node, Scope $scope): array + { + if (!$scope->isInClass()) { + return []; + } + + $classReflection = $scope->getClassReflection(); + if (!$classReflection->isEnum()) { + return []; + } + + $caseName = $node->name->toString(); + + return $this->overrideAttributeCheck->check( + $scope, + $classReflection, + $caseName, + $this->findPrototype($classReflection, $caseName), + $node->attrGroups, + $node, + true, + ); + } + + /** + * An enum case can only override a constant of an implemented interface. + */ + private function findPrototype(ClassReflection $classReflection, string $caseName): ?ClassConstantReflection + { + foreach ($classReflection->getImmediateInterfaces() as $immediateInterface) { + if ($immediateInterface->hasConstant($caseName)) { + return $immediateInterface->getConstant($caseName); + } + } + + return null; + } + +} diff --git a/tests/PHPStan/Rules/Constants/OverridingConstantRuleTest.php b/tests/PHPStan/Rules/Constants/OverridingConstantRuleTest.php index ef17e188446..b868d00db5b 100644 --- a/tests/PHPStan/Rules/Constants/OverridingConstantRuleTest.php +++ b/tests/PHPStan/Rules/Constants/OverridingConstantRuleTest.php @@ -11,9 +11,17 @@ class OverridingConstantRuleTest extends RuleTestCase { + private ?bool $checkMissingOverrideConstantAttribute = false; + protected function getRule(): Rule { - return new OverridingConstantRule(true); + return new OverridingConstantRule( + true, + new OverrideAttributeOnConstantCheck( + $this->checkMissingOverrideConstantAttribute, + checkMissingOverrideMethodAttribute: true, + ), + ); } public function testRule(): void @@ -114,4 +122,77 @@ public function testNativeTypes(): void ]); } + public function testOverrideAttribute(): void + { + $this->checkMissingOverrideConstantAttribute = true; + $this->analyse([__DIR__ . '/data/constant-override-attr.php'], [ + [ + 'Constant ConstantOverrideAttr\\Bar::PRIVATE_FROM_PARENT has #[\\Override] attribute but does not override any constant.', + 28, + ], + [ + 'Constant ConstantOverrideAttr\\Bar::NOT_OVERRIDING has #[\\Override] attribute but does not override any constant.', + 31, + ], + [ + 'Constant ConstantOverrideAttr\\Baz::FROM_PARENT overrides constant ConstantOverrideAttr\\Foo::FROM_PARENT but is missing the #[\\Override] attribute.', + 39, + ], + [ + 'Constant ConstantOverrideAttr\\Baz::ALSO_NOT_OVERRIDING has #[\\Override] attribute but does not override any constant.', + 41, + ], + [ + 'Constant ConstantOverrideAttr\\BarInterface::NOT_OVERRIDING has #[\\Override] attribute but does not override any constant.', + 50, + ], + [ + 'Constant ConstantOverrideAttr\\UsesTraitWithoutParent::FROM_PARENT has #[\\Override] attribute but does not override any constant.', + 56, + ], + ]); + } + + public function testMissingOverrideAttributeNotCheckedByDefaultBeforePhp86(): void + { + $this->checkMissingOverrideConstantAttribute = null; + $errors = []; + if (PHP_VERSION_ID >= 80600) { + $errors[] = [ + 'Constant ConstantOverrideAttr\\Baz::FROM_PARENT overrides constant ConstantOverrideAttr\\Foo::FROM_PARENT but is missing the #[\\Override] attribute.', + 39, + ]; + } + + $this->analyse([__DIR__ . '/data/constant-override-attr.php'], [ + [ + 'Constant ConstantOverrideAttr\\Bar::PRIVATE_FROM_PARENT has #[\\Override] attribute but does not override any constant.', + 28, + ], + [ + 'Constant ConstantOverrideAttr\\Bar::NOT_OVERRIDING has #[\\Override] attribute but does not override any constant.', + 31, + ], + ...$errors, + [ + 'Constant ConstantOverrideAttr\\Baz::ALSO_NOT_OVERRIDING has #[\\Override] attribute but does not override any constant.', + 41, + ], + [ + 'Constant ConstantOverrideAttr\\BarInterface::NOT_OVERRIDING has #[\\Override] attribute but does not override any constant.', + 50, + ], + [ + 'Constant ConstantOverrideAttr\\UsesTraitWithoutParent::FROM_PARENT has #[\\Override] attribute but does not override any constant.', + 56, + ], + ]); + } + + public function testFixOverrideAttribute(): void + { + $this->checkMissingOverrideConstantAttribute = true; + $this->fix(__DIR__ . '/data/constant-override-attr-fix.php', __DIR__ . '/data/constant-override-attr-fix.php.fixed'); + } + } diff --git a/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php b/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php new file mode 100644 index 00000000000..cc1200d090a --- /dev/null +++ b/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php @@ -0,0 +1,16 @@ += 8.0 + +namespace ConstantOverrideAttrFix; + +class Foo +{ + const FOO = 1; +} + +class Bar extends Foo +{ + const FOO = 2; + + #[\Override] + const BAR = 2; +} diff --git a/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php.fixed b/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php.fixed new file mode 100644 index 00000000000..a152cd21a43 --- /dev/null +++ b/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php.fixed @@ -0,0 +1,16 @@ += 8.0 + +namespace ConstantOverrideAttrFix; + +class Foo +{ + const FOO = 1; +} + +class Bar extends Foo +{ + #[\Override] + const FOO = 2; + + const BAR = 2; +} diff --git a/tests/PHPStan/Rules/Constants/data/constant-override-attr.php b/tests/PHPStan/Rules/Constants/data/constant-override-attr.php new file mode 100644 index 00000000000..68e12d5bc1b --- /dev/null +++ b/tests/PHPStan/Rules/Constants/data/constant-override-attr.php @@ -0,0 +1,70 @@ += 8.0 + +namespace ConstantOverrideAttr; + +interface FooInterface +{ + const FROM_INTERFACE = 1; +} + +class Foo +{ + const FROM_PARENT = 1; + protected const PROTECTED_FROM_PARENT = 1; + private const PRIVATE_FROM_PARENT = 1; +} + +class Bar extends Foo implements FooInterface +{ + #[\Override] + const FROM_INTERFACE = 2; + + #[\Override] + const FROM_PARENT = 2; + + #[\Override] + protected const PROTECTED_FROM_PARENT = 2; + + #[\Override] + const PRIVATE_FROM_PARENT = 2; + + #[\Override] + const NOT_OVERRIDING = 2; + + const NEW_CONSTANT = 2; +} + +class Baz extends Foo +{ + const FROM_PARENT = 3; + + #[\Override] + const PROTECTED_FROM_PARENT = 3, ALSO_NOT_OVERRIDING = 3; +} + +interface BarInterface extends FooInterface +{ + #[\Override] + const FROM_INTERFACE = 4; + + #[\Override] + const NOT_OVERRIDING = 4; +} + +trait FooTrait +{ + #[\Override] + const FROM_PARENT = 5; + + const PROTECTED_FROM_PARENT = 5; +} + +class UsesTraitWithParent extends Foo +{ + use FooTrait; +} + +class UsesTraitWithoutParent +{ + use FooTrait; +} diff --git a/tests/PHPStan/Rules/EnumCases/OverridingEnumCaseRuleTest.php b/tests/PHPStan/Rules/EnumCases/OverridingEnumCaseRuleTest.php new file mode 100644 index 00000000000..5036c7f7d6f --- /dev/null +++ b/tests/PHPStan/Rules/EnumCases/OverridingEnumCaseRuleTest.php @@ -0,0 +1,45 @@ + + */ +class OverridingEnumCaseRuleTest extends RuleTestCase +{ + + protected function getRule(): Rule + { + return new OverridingEnumCaseRule( + new OverrideAttributeOnConstantCheck( + checkMissingOverrideConstantAttribute: true, + checkMissingOverrideMethodAttribute: true, + ), + ); + } + + #[RequiresPhp('>= 8.1.0')] + public function testRule(): void + { + $this->analyse([__DIR__ . '/data/enum-case-override-attr.php'], [ + [ + 'Enum case EnumCaseOverrideAttr\Foo::BAR has #[\Override] attribute but does not override any constant.', + 15, + ], + [ + 'Enum case EnumCaseOverrideAttr\Bar::FOO overrides constant EnumCaseOverrideAttr\FooInterface::FOO but is missing the #[\Override] attribute.', + 21, + ], + [ + 'Enum case EnumCaseOverrideAttr\Baz::BAZ has #[\Override] attribute but does not override any constant.', + 26, + ], + ]); + } + +} diff --git a/tests/PHPStan/Rules/EnumCases/data/enum-case-override-attr.php b/tests/PHPStan/Rules/EnumCases/data/enum-case-override-attr.php new file mode 100644 index 00000000000..85e56b3c93e --- /dev/null +++ b/tests/PHPStan/Rules/EnumCases/data/enum-case-override-attr.php @@ -0,0 +1,28 @@ += 8.1 + +namespace EnumCaseOverrideAttr; + +interface FooInterface +{ + const FOO = 'foo'; +} + +enum Foo: string implements FooInterface +{ + #[\Override] + case FOO = 'foo'; + + #[\Override] + case BAR = 'bar'; +} + +enum Bar: string implements FooInterface +{ + case FOO = 'foo'; +} + +enum Baz +{ + #[\Override] + case BAZ; +} From 6712f9bcfe60723838221e95f7008056c4ccd0a6 Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Tue, 6 Oct 2026 05:02:26 +0200 Subject: [PATCH 2/4] Require PHP 8.2 for the trait constant fixture and cover a PHP version range spanning 8.6 --- .../OverridingConstantRuleConfigPhpTest.php | 58 +++++++++++++++++++ .../Constants/OverridingConstantRuleTest.php | 2 + .../constant-override-attr-php-version.neon | 4 ++ .../Constants/data/constant-override-attr.php | 2 +- 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/Rules/Constants/OverridingConstantRuleConfigPhpTest.php create mode 100644 tests/PHPStan/Rules/Constants/data/constant-override-attr-php-version.neon diff --git a/tests/PHPStan/Rules/Constants/OverridingConstantRuleConfigPhpTest.php b/tests/PHPStan/Rules/Constants/OverridingConstantRuleConfigPhpTest.php new file mode 100644 index 00000000000..3dae648629b --- /dev/null +++ b/tests/PHPStan/Rules/Constants/OverridingConstantRuleConfigPhpTest.php @@ -0,0 +1,58 @@ + */ +class OverridingConstantRuleConfigPhpTest extends RuleTestCase +{ + + protected function getRule(): Rule + { + return new OverridingConstantRule( + true, + new OverrideAttributeOnConstantCheck( + checkMissingOverrideConstantAttribute: null, + checkMissingOverrideMethodAttribute: true, + ), + ); + } + + #[RequiresPhp('>= 8.2.0')] + public function testMissingOverrideAttributeNotCheckedOnPhpVersionRangeSpanning86(): void + { + $this->analyse([__DIR__ . '/data/constant-override-attr.php'], [ + [ + 'Constant ConstantOverrideAttr\Bar::PRIVATE_FROM_PARENT has #[\Override] attribute but does not override any constant.', + 28, + ], + [ + 'Constant ConstantOverrideAttr\Bar::NOT_OVERRIDING has #[\Override] attribute but does not override any constant.', + 31, + ], + [ + 'Constant ConstantOverrideAttr\Baz::ALSO_NOT_OVERRIDING has #[\Override] attribute but does not override any constant.', + 41, + ], + [ + 'Constant ConstantOverrideAttr\BarInterface::NOT_OVERRIDING has #[\Override] attribute but does not override any constant.', + 50, + ], + [ + 'Constant ConstantOverrideAttr\UsesTraitWithoutParent::FROM_PARENT has #[\Override] attribute but does not override any constant.', + 56, + ], + ]); + } + + public static function getAdditionalConfigFiles(): array + { + return [ + __DIR__ . '/data/constant-override-attr-php-version.neon', + ]; + } + +} diff --git a/tests/PHPStan/Rules/Constants/OverridingConstantRuleTest.php b/tests/PHPStan/Rules/Constants/OverridingConstantRuleTest.php index b868d00db5b..99bf9728269 100644 --- a/tests/PHPStan/Rules/Constants/OverridingConstantRuleTest.php +++ b/tests/PHPStan/Rules/Constants/OverridingConstantRuleTest.php @@ -122,6 +122,7 @@ public function testNativeTypes(): void ]); } + #[RequiresPhp('>= 8.2.0')] public function testOverrideAttribute(): void { $this->checkMissingOverrideConstantAttribute = true; @@ -153,6 +154,7 @@ public function testOverrideAttribute(): void ]); } + #[RequiresPhp('>= 8.2.0')] public function testMissingOverrideAttributeNotCheckedByDefaultBeforePhp86(): void { $this->checkMissingOverrideConstantAttribute = null; diff --git a/tests/PHPStan/Rules/Constants/data/constant-override-attr-php-version.neon b/tests/PHPStan/Rules/Constants/data/constant-override-attr-php-version.neon new file mode 100644 index 00000000000..37a89190078 --- /dev/null +++ b/tests/PHPStan/Rules/Constants/data/constant-override-attr-php-version.neon @@ -0,0 +1,4 @@ +parameters: + phpVersion: + min: 80500 + max: 80600 diff --git a/tests/PHPStan/Rules/Constants/data/constant-override-attr.php b/tests/PHPStan/Rules/Constants/data/constant-override-attr.php index 68e12d5bc1b..7426d136890 100644 --- a/tests/PHPStan/Rules/Constants/data/constant-override-attr.php +++ b/tests/PHPStan/Rules/Constants/data/constant-override-attr.php @@ -1,4 +1,4 @@ -= 8.0 += 8.2 namespace ConstantOverrideAttr; From 517ce740f8978c89953a9e06aac6c2a94b5cc8f4 Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Tue, 6 Oct 2026 10:32:21 +0200 Subject: [PATCH 3/4] Lint the #[\Override] constant fixtures on PHP 8.6 only --- .../PHPStan/Rules/Constants/data/constant-override-attr-fix.php | 2 +- .../Rules/Constants/data/constant-override-attr-fix.php.fixed | 2 +- tests/PHPStan/Rules/Constants/data/constant-override-attr.php | 2 +- tests/PHPStan/Rules/EnumCases/data/enum-case-override-attr.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php b/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php index cc1200d090a..ef2dd9364e4 100644 --- a/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php +++ b/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php @@ -1,4 +1,4 @@ -= 8.0 += 8.6 namespace ConstantOverrideAttrFix; diff --git a/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php.fixed b/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php.fixed index a152cd21a43..7981c940a1c 100644 --- a/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php.fixed +++ b/tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php.fixed @@ -1,4 +1,4 @@ -= 8.0 += 8.6 namespace ConstantOverrideAttrFix; diff --git a/tests/PHPStan/Rules/Constants/data/constant-override-attr.php b/tests/PHPStan/Rules/Constants/data/constant-override-attr.php index 7426d136890..7440314b890 100644 --- a/tests/PHPStan/Rules/Constants/data/constant-override-attr.php +++ b/tests/PHPStan/Rules/Constants/data/constant-override-attr.php @@ -1,4 +1,4 @@ -= 8.2 += 8.6 namespace ConstantOverrideAttr; diff --git a/tests/PHPStan/Rules/EnumCases/data/enum-case-override-attr.php b/tests/PHPStan/Rules/EnumCases/data/enum-case-override-attr.php index 85e56b3c93e..6f26a4869f3 100644 --- a/tests/PHPStan/Rules/EnumCases/data/enum-case-override-attr.php +++ b/tests/PHPStan/Rules/EnumCases/data/enum-case-override-attr.php @@ -1,4 +1,4 @@ -= 8.1 += 8.6 namespace EnumCaseOverrideAttr; From c83e21f8f30329157e4c865bdca0934df84a1ee7 Mon Sep 17 00:00:00 2001 From: Pascal CESCON - Amoifr Date: Tue, 6 Oct 2026 10:40:52 +0200 Subject: [PATCH 4/4] Exclude the #[\Override] constant fixtures from lint --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index ea78ec2e2cb..a5c99321182 100644 --- a/Makefile +++ b/Makefile @@ -131,6 +131,8 @@ lint: --exclude tests/PHPStan/Rules/Properties/data/property-override-attr-missing.php \ --exclude tests/PHPStan/Rules/Properties/data/override-attr-on-property.php \ --exclude tests/PHPStan/Rules/Properties/data/property-override-attr.php \ + --exclude tests/PHPStan/Rules/Constants/data/constant-override-attr.php \ + --exclude tests/PHPStan/Rules/Constants/data/constant-override-attr-fix.php \ --exclude tests/PHPStan/Rules/Classes/data/bug-14250.php \ --exclude tests/PHPStan/Rules/Classes/data/bug-14250-promoted-properties.php \ --exclude tests/PHPStan/Rules/Operators/data/bug-3585.php \