Skip to content

Commit

Permalink
recognize Deprecated attribute on enum cases
Browse files Browse the repository at this point in the history
just like with properties, this recognizes both `Psalm\Deprecated` and
`JetBrains\\PhpStorm\\Deprecated`
  • Loading branch information
pilif committed Dec 21, 2021
1 parent 1df74bd commit 8e6f59d
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 23 deletions.
90 changes: 67 additions & 23 deletions src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php
Expand Up @@ -46,6 +46,7 @@
use Psalm\Issue\MissingDocblockType;
use Psalm\Issue\ParseError;
use Psalm\IssueBuffer;
use Psalm\Storage\AttributeStorage;
use Psalm\Storage\ClassConstantStorage;
use Psalm\Storage\ClassLikeStorage;
use Psalm\Storage\EnumCaseStorage;
Expand Down Expand Up @@ -1350,6 +1351,23 @@ private function visitEnumDeclaration(
$case_location
);

$attrs = $this->getAttributeStorageFromStatement(
$this->codebase,
$this->file_scanner,
$this->file_storage,
$this->aliases,
$stmt,
$this->storage->name ?? null
);

foreach ($attrs as $attribute) {
if ($attribute->fq_class_name === 'Psalm\\Deprecated'
|| $attribute->fq_class_name === 'JetBrains\\PhpStorm\\Deprecated'
) {
$case->deprecated = true;
}
}

$comment = $stmt->getDocComment();
if ($comment) {
$var_comments = CommentAnalyzer::getTypeFromComment(
Expand All @@ -1375,6 +1393,34 @@ private function visitEnumDeclaration(
}
}

/**
* @param PhpParser\Node\Stmt\Property|PhpParser\Node\Stmt\EnumCase $stmt
* @return list<AttributeStorage>
*/
private function getAttributeStorageFromStatement(
Codebase $codebase,
FileScanner $file_scanner,
FileStorage $file_storage,
Aliases $aliases,
PhpParser\Node\Stmt $stmt,
?string $fq_classlike_name
): array {
$storages = [];
foreach ($stmt->attrGroups as $attr_group) {
foreach ($attr_group->attrs as $attr) {
$storages[] = AttributeResolver::resolve(
$codebase,
$file_scanner,
$file_storage,
$aliases,
$attr,
$fq_classlike_name
);
}
}
return $storages;
}

private function visitPropertyDeclaration(
PhpParser\Node\Stmt\Property $stmt,
Config $config,
Expand Down Expand Up @@ -1570,33 +1616,31 @@ private function visitPropertyDeclaration(
$storage->inheritable_property_ids[$property->name->name] = $property_id;
}

foreach ($stmt->attrGroups as $attr_group) {
foreach ($attr_group->attrs as $attr) {
$attribute = AttributeResolver::resolve(
$this->codebase,
$this->file_scanner,
$this->file_storage,
$this->aliases,
$attr,
$this->storage->name ?? null
);

if ($attribute->fq_class_name === 'Psalm\\Deprecated'
|| $attribute->fq_class_name === 'JetBrains\\PhpStorm\\Deprecated'
) {
$property_storage->deprecated = true;
}
$attrs = $this->getAttributeStorageFromStatement(
$this->codebase,
$this->file_scanner,
$this->file_storage,
$this->aliases,
$stmt,
$this->storage->name ?? null
);

if ($attribute->fq_class_name === 'Psalm\\Internal' && !$property_storage->internal) {
$property_storage->internal = NamespaceAnalyzer::getNameSpaceRoot($fq_classlike_name);
}
foreach ($attrs as $attribute) {
if ($attribute->fq_class_name === 'Psalm\\Deprecated'
|| $attribute->fq_class_name === 'JetBrains\\PhpStorm\\Deprecated'
) {
$property_storage->deprecated = true;
}

if ($attribute->fq_class_name === 'Psalm\\Readonly') {
$property_storage->readonly = true;
}
if ($attribute->fq_class_name === 'Psalm\\Internal' && !$property_storage->internal) {
$property_storage->internal = NamespaceAnalyzer::getNameSpaceRoot($fq_classlike_name);
}

$property_storage->attributes[] = $attribute;
if ($attribute->fq_class_name === 'Psalm\\Readonly') {
$property_storage->readonly = true;
}

$property_storage->attributes[] = $attribute;
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions tests/EnumTest.php
Expand Up @@ -591,6 +591,22 @@ enum Status { }
false,
'8.1',
],
'deprecatedAttribute' => [
'<?php
enum Foo {
case A;
#[Psalm\Deprecated]
case B;
}
Foo::B;
',
'error_message' => 'DeprecatedConstant',
[],
false,
'8.1',
],
];
}
}

0 comments on commit 8e6f59d

Please sign in to comment.