diff --git a/src/Rules/EnumCases/EnumCaseOutsideEnumRule.php b/src/Rules/EnumCases/EnumCaseOutsideEnumRule.php new file mode 100644 index 0000000000..ba0290e5ea --- /dev/null +++ b/src/Rules/EnumCases/EnumCaseOutsideEnumRule.php @@ -0,0 +1,42 @@ + + */ +#[RegisteredRule(level: 0)] +final class EnumCaseOutsideEnumRule implements Rule +{ + + 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 []; + } + + return [ + RuleErrorBuilder::message('Enum case can only be used in enums.') + ->nonIgnorable() + ->identifier('enum.caseOutsideOfEnum') + ->build(), + ]; + } + +} diff --git a/tests/PHPStan/Rules/EnumCases/EnumCaseOutsideEnumRuleTest.php b/tests/PHPStan/Rules/EnumCases/EnumCaseOutsideEnumRuleTest.php new file mode 100644 index 0000000000..7c86412167 --- /dev/null +++ b/tests/PHPStan/Rules/EnumCases/EnumCaseOutsideEnumRuleTest.php @@ -0,0 +1,35 @@ + + */ +class EnumCaseOutsideEnumRuleTest extends RuleTestCase +{ + + protected function getRule(): Rule + { + return new EnumCaseOutsideEnumRule(); + } + + #[RequiresPhp('>= 8.1')] + public function testRule(): void + { + $this->analyse([__DIR__ . '/data/bug-14252.php'], [ + [ + 'Enum case can only be used in enums.', + 9, + ], + [ + 'Enum case can only be used in enums.', + 14, + ], + ]); + } + +} diff --git a/tests/PHPStan/Rules/EnumCases/data/bug-14252.php b/tests/PHPStan/Rules/EnumCases/data/bug-14252.php new file mode 100644 index 0000000000..d8f86ec336 --- /dev/null +++ b/tests/PHPStan/Rules/EnumCases/data/bug-14252.php @@ -0,0 +1,20 @@ += 8.1 + +declare(strict_types = 1); + +namespace Bug14252; + +class Foo +{ + case Active; +} + +interface Bar +{ + case Active; +} + +enum Qux +{ + case Active; +}