1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Correctly process constant references on enum-valued variables

This commit is contained in:
Bruce Weirdan 2021-11-27 04:32:32 +02:00
parent f215ed28d0
commit 97445b52f3
No known key found for this signature in database
GPG Key ID: CFC3AAB181751B0D
2 changed files with 61 additions and 44 deletions

View File

@ -509,53 +509,43 @@ class ClassConstFetchAnalyzer
$const_class_storage = $codebase->classlike_storage_provider->get($fq_class_name); $const_class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
if ($const_class_storage->is_enum) { if ($fq_class_name === $context->self
if (isset($const_class_storage->enum_cases[$stmt->name->name])) { || (
$class_constant_type = new Type\Union([ $statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer &&
new Type\Atomic\TEnumCase($fq_class_name, $stmt->name->name) $fq_class_name === $statements_analyzer->getSource()->getFQCLN()
]); )
} else { ) {
$class_constant_type = null; $class_visibility = \ReflectionProperty::IS_PRIVATE;
} } elseif ($context->self &&
($codebase->classlikes->classExtends($context->self, $fq_class_name)
|| $codebase->classlikes->classExtends($fq_class_name, $context->self))
) {
$class_visibility = \ReflectionProperty::IS_PROTECTED;
} else { } else {
if ($fq_class_name === $context->self $class_visibility = \ReflectionProperty::IS_PUBLIC;
|| ( }
$statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer &&
$fq_class_name === $statements_analyzer->getSource()->getFQCLN() try {
) $class_constant_type = $codebase->classlikes->getClassConstantType(
) { $fq_class_name,
$class_visibility = \ReflectionProperty::IS_PRIVATE; $stmt->name->name,
} elseif ($context->self && $class_visibility,
($codebase->classlikes->classExtends($context->self, $fq_class_name) $statements_analyzer
|| $codebase->classlikes->classExtends($fq_class_name, $context->self)) );
) { } catch (\InvalidArgumentException $_) {
$class_visibility = \ReflectionProperty::IS_PROTECTED; return true;
} else { } catch (\Psalm\Exception\CircularReferenceException $e) {
$class_visibility = \ReflectionProperty::IS_PUBLIC; if (IssueBuffer::accepts(
new CircularReference(
'Constant ' . $const_id . ' contains a circular reference',
new CodeLocation($statements_analyzer->getSource(), $stmt)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
} }
try { return true;
$class_constant_type = $codebase->classlikes->getClassConstantType(
$fq_class_name,
$stmt->name->name,
$class_visibility,
$statements_analyzer
);
} catch (\InvalidArgumentException $_) {
return true;
} catch (\Psalm\Exception\CircularReferenceException $e) {
if (IssueBuffer::accepts(
new CircularReference(
'Constant ' . $const_id . ' contains a circular reference',
new CodeLocation($statements_analyzer->getSource(), $stmt)
),
$statements_analyzer->getSuppressedIssues()
)) {
// fall through
}
return true;
}
} }
if (!$class_constant_type) { if (!$class_constant_type) {

View File

@ -194,6 +194,33 @@ class EnumTest extends TestCase
[], [],
'8.1', '8.1',
], ],
'constantOfAVariableEnumClassString' => [
'<?php
enum A { const C = 3; }
$e = A::class;
$_z = $e::C;
',
'assertions' => [
'$_z===' => '3',
],
[],
'8.1',
],
'constantOfAVariableEnumInstance' => [
'<?php
enum A {
const C = 3;
case AA;
}
$e = A::AA;
$_z = $e::C;
',
'assertions' => [
'$_z===' => '3',
],
[],
'8.1',
],
'EnumCaseInAttribute' => [ 'EnumCaseInAttribute' => [
'<?php '<?php
class CreateController { class CreateController {