diff --git a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php index a337ece0f..6eca8ec95 100644 --- a/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php @@ -2000,7 +2000,7 @@ abstract class FunctionLikeAnalyzer extends SourceAnalyzer MethodAnalyzer::checkMethodSignatureMustOmitReturnType($storage, $codeLocation); if ($appearing_class_storage->is_enum) { - MethodAnalyzer::checkForbiddenEnumMethod($storage); + MethodAnalyzer::checkForbiddenEnumMethod($storage, $appearing_class_storage); } if (!$context->calling_method_id || !$context->collect_initializations) { diff --git a/src/Psalm/Internal/Analyzer/MethodAnalyzer.php b/src/Psalm/Internal/Analyzer/MethodAnalyzer.php index 0a5077c14..89af7aaec 100644 --- a/src/Psalm/Internal/Analyzer/MethodAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/MethodAnalyzer.php @@ -16,6 +16,7 @@ use Psalm\Issue\NonStaticSelfCall; use Psalm\Issue\UndefinedMethod; use Psalm\IssueBuffer; use Psalm\StatementsSource; +use Psalm\Storage\ClassLikeStorage; use Psalm\Storage\MethodStorage; use UnexpectedValueException; @@ -310,7 +311,7 @@ class MethodAnalyzer extends FunctionLikeAnalyzer ); } - public static function checkForbiddenEnumMethod(MethodStorage $method_storage): void + public static function checkForbiddenEnumMethod(MethodStorage $method_storage, ClassLikeStorage $enum_storage): void { if ($method_storage->cased_name === null || $method_storage->location === null) { return; @@ -324,5 +325,21 @@ class MethodAnalyzer extends FunctionLikeAnalyzer $method_storage->defining_fqcln . '::' . $method_storage->cased_name, )); } + + if ($method_name_lc === 'cases') { + IssueBuffer::maybeAdd(new InvalidEnumMethod( + 'Enums cannot define ' . $method_storage->cased_name, + $method_storage->location, + $method_storage->defining_fqcln . '::' . $method_storage->cased_name, + )); + } + + if ($enum_storage->enum_type && ($method_name_lc === 'from' || $method_name_lc === 'tryfrom')) { + IssueBuffer::maybeAdd(new InvalidEnumMethod( + 'Enums cannot define ' . $method_storage->cased_name, + $method_storage->location, + $method_storage->defining_fqcln . '::' . $method_storage->cased_name, + )); + } } } diff --git a/tests/EnumTest.php b/tests/EnumTest.php index 9477ef7cc..74483e04b 100644 --- a/tests/EnumTest.php +++ b/tests/EnumTest.php @@ -805,6 +805,62 @@ class EnumTest extends TestCase 'ignored_issues' => [], 'php_version' => '8.1', ], + 'forbiddenUnitEnumCasesMethod' => [ + 'code' => ' 'InvalidEnumMethod', + 'ignored_issues' => [], + 'php_version' => '8.1', + ], + 'forbiddenBackedEnumCasesMethod' => [ + 'code' => ' 'InvalidEnumMethod', + 'ignored_issues' => [], + 'php_version' => '8.1', + ], + 'forbiddenBackedEnumFromMethod' => [ + 'code' => ' 'InvalidEnumMethod', + 'ignored_issues' => [], + 'php_version' => '8.1', + ], + 'forbiddenBackedEnumTryFromMethod' => [ + 'code' => ' 'InvalidEnumMethod', + 'ignored_issues' => [], + 'php_version' => '8.1', + ], ]; } }