Fix phpstan/phpstan#14252: Enum case outside of enum should be reported#5188
Conversation
| case Active; | ||
| } | ||
|
|
||
| interface Bar |
There was a problem hiding this comment.
Misses a test for a trait which uses a enum case
There was a problem hiding this comment.
Tests completed successfully (the one failure is the pre-existing RawErrorFormatterTest issue, unrelated to our changes). Everything is committed and pushed.
|
The review from VincentLanglet is an APPROVED review with no requested changes. The previous feedback from staabm (adding a trait test case) was already addressed in the latest commits. There are no code changes to make - the PR has been approved and is ready to merge. |
403efc7 to
fc50c29
Compare
- Added new EnumCaseOutsideEnumRule that reports an error when `case` is used in classes or interfaces instead of enums - New regression test in tests/PHPStan/Rules/EnumCases/data/bug-14252.php - The rule is registered at level 0 and uses the identifier `enum.caseOutsideOfEnum` Closes phpstan/phpstan#14252
Add trait test case as requested in review. Handle the trait scope separately since traits are analyzed in the context of their consumer class. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
fc50c29 to
f97c99a
Compare
ondrejmirtes
left a comment
There was a problem hiding this comment.
The two RuleErrorBuilders have exactly the same message and identifier. I'm sure you can find a way how to deduplicate it and have a single RuleErrorBuilder call 😊
Restructure the condition logic to return early for the valid case (enum context) and have a single RuleErrorBuilder call for all invalid contexts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Static analysis passed too. Everything is green and pushed. Summary of changes: Restructured |
Summary
PHPStan did not report an error when an enum
casedeclaration appeared inside a regular class or interface (instead of an enum). PHP itself produces a fatal error "Case can only be used in enums" for such code, but PHPStan silently accepted it.Changes
src/Rules/EnumCases/EnumCaseOutsideEnumRule.php— a new rule that checks ifNode\Stmt\EnumCaseappears inside a non-enum class and reports "Enum case can only be used in enums."tests/PHPStan/Rules/EnumCases/EnumCaseOutsideEnumRuleTest.php— test case for the new ruletests/PHPStan/Rules/EnumCases/data/bug-14252.php— test data with enum case in class, interface, and enum (enum case in enum should not error)Root cause
There was no rule checking whether
EnumCaseAST nodes appear in the correct context. The parser (nikic/php-parser) parsescase Active;asNode\Stmt\EnumCaseregardless of whether it's inside an enum or a class/interface. PHPStan had rules for validating enum case attributes and sanity checks within enums, but nothing to catch an enum case declaration outside of an enum.Test
The regression test verifies that:
case Active;inside a class reports an error on line 9case Active;inside an interface reports an error on line 14case Active;inside an enum does NOT report an error (line 19)Fixes phpstan/phpstan#14252