From d45cb648279a6462a116918bac9935d2fba2b54e 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 | 12 +++++++++++- src/Psalm/Storage/EnumCaseStorage.php | 5 +++++ tests/DeprecatedAnnotationTest.php | 16 ++++++++++++++++ 4 files changed, 44 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 7fb934dcc..e6cb06ca1 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 @@ class ClassConstFetchAnalyzer } $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 7dd662c12..b202293b6 100644 --- a/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php +++ b/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php @@ -1345,10 +1345,20 @@ class ClassLikeNodeScanner $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) { + $comments = DocComment::parsePreservingLength($comment); + + if (isset($comments->tags['deprecated'])) { + $case->deprecated = true; + } + } + $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 915fcd259..c61fcea3d 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 c01125793..828e0f0ff 100644 --- a/tests/DeprecatedAnnotationTest.php +++ b/tests/DeprecatedAnnotationTest.php @@ -251,6 +251,22 @@ class DeprecatedAnnotationTest extends TestCase ', 'error_message' => 'DeprecatedProperty', ], + 'deprecatedEnumCaseFetch' => [ + ' 'DeprecatedConstant', + [], + false, + '8.1', + ] ]; } }