From 9e24c43cc0f675a00b3a099899268f06368f0ed0 Mon Sep 17 00:00:00 2001 From: Philip Hofstetter Date: Mon, 20 Dec 2021 14:20:11 +0100 Subject: [PATCH] allow marking enum cases as @deprecated --- .../Expression/Fetch/ClassConstFetchAnalyzer.php | 12 ++++++++++++ .../Reflector/ClassLikeNodeScanner.php | 16 +++++++++++++++- src/Psalm/Storage/EnumCaseStorage.php | 5 +++++ tests/DeprecatedAnnotationTest.php | 16 ++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php index ce007570863..bc898fcee4e 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ClassConstFetchAnalyzer.php @@ -218,6 +218,18 @@ public static function analyze( } $const_class_storage = $codebase->classlike_storage_provider->get($fq_class_name); + if ($const_class_storage->is_enum) { + $case = $const_class_storage->enum_cases[(string)$stmt->name] ?? null; + if ($case && $case->deprecated) { + IssueBuffer::maybeAdd( + new DeprecatedConstant( + "Enum Case $const_id is marked as deprecated", + new CodeLocation($statements_analyzer->getSource(), $stmt), + ), + $statements_analyzer->getSuppressedIssues() + ); + } + } if ($fq_class_name === $context->self || ( diff --git a/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php b/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php index 7dd662c12ac..c6c8ebe74de 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php @@ -1345,10 +1345,24 @@ private function visitEnumDeclaration( $case_location = new CodeLocation($this->file_scanner, $stmt); if (!isset($storage->enum_cases[$stmt->name->name])) { - $storage->enum_cases[$stmt->name->name] = new EnumCaseStorage( + $case = new EnumCaseStorage( $enum_value, $case_location ); + + $comment = $stmt->getDocComment(); + if ($comment) { + $var_comments = CommentAnalyzer::getTypeFromComment( + $comment, + $this->file_scanner, + $this->aliases, + [], + $this->type_aliases + ); + $var_comment = array_pop($var_comments); + $case->deprecated = $var_comment ? $var_comment->deprecated : false; + } + $storage->enum_cases[$stmt->name->name] = $case; } else { if (IssueBuffer::accepts( new DuplicateEnumCase( diff --git a/src/Psalm/Storage/EnumCaseStorage.php b/src/Psalm/Storage/EnumCaseStorage.php index 915fcd259ef..c61fcea3d24 100644 --- a/src/Psalm/Storage/EnumCaseStorage.php +++ b/src/Psalm/Storage/EnumCaseStorage.php @@ -14,6 +14,11 @@ class EnumCaseStorage /** @var CodeLocation */ public $stmt_location; + /** + * @var bool + */ + public $deprecated = false; + /** * @param int|string|null $value */ diff --git a/tests/DeprecatedAnnotationTest.php b/tests/DeprecatedAnnotationTest.php index c011257935e..828e0f0ff15 100644 --- a/tests/DeprecatedAnnotationTest.php +++ b/tests/DeprecatedAnnotationTest.php @@ -251,6 +251,22 @@ class Bar ', 'error_message' => 'DeprecatedProperty', ], + 'deprecatedEnumCaseFetch' => [ + ' 'DeprecatedConstant', + [], + false, + '8.1', + ] ]; } }