mirror of
https://github.com/danog/psalm.git
synced 2024-11-30 04:39:00 +01:00
Merge pull request #6995 from vimeo/enum-constants
This commit is contained in:
commit
03aea28c73
@ -210,53 +210,43 @@ class ClassConstFetchAnalyzer
|
||||
|
||||
$const_class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
|
||||
|
||||
if ($const_class_storage->is_enum) {
|
||||
if (isset($const_class_storage->enum_cases[$stmt->name->name])) {
|
||||
$class_constant_type = new Type\Union([
|
||||
new Type\Atomic\TEnumCase($fq_class_name, $stmt->name->name)
|
||||
]);
|
||||
} else {
|
||||
$class_constant_type = null;
|
||||
}
|
||||
if ($fq_class_name === $context->self
|
||||
|| (
|
||||
$statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer &&
|
||||
$fq_class_name === $statements_analyzer->getSource()->getFQCLN()
|
||||
)
|
||||
) {
|
||||
$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 {
|
||||
if ($fq_class_name === $context->self
|
||||
|| (
|
||||
$statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer &&
|
||||
$fq_class_name === $statements_analyzer->getSource()->getFQCLN()
|
||||
)
|
||||
) {
|
||||
$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 {
|
||||
$class_visibility = \ReflectionProperty::IS_PUBLIC;
|
||||
$class_visibility = \ReflectionProperty::IS_PUBLIC;
|
||||
}
|
||||
|
||||
try {
|
||||
$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
|
||||
}
|
||||
|
||||
try {
|
||||
$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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$class_constant_type) {
|
||||
@ -519,53 +509,43 @@ class ClassConstFetchAnalyzer
|
||||
|
||||
$const_class_storage = $codebase->classlike_storage_provider->get($fq_class_name);
|
||||
|
||||
if ($const_class_storage->is_enum) {
|
||||
if (isset($const_class_storage->enum_cases[$stmt->name->name])) {
|
||||
$class_constant_type = new Type\Union([
|
||||
new Type\Atomic\TEnumCase($fq_class_name, $stmt->name->name)
|
||||
]);
|
||||
} else {
|
||||
$class_constant_type = null;
|
||||
}
|
||||
if ($fq_class_name === $context->self
|
||||
|| (
|
||||
$statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer &&
|
||||
$fq_class_name === $statements_analyzer->getSource()->getFQCLN()
|
||||
)
|
||||
) {
|
||||
$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 {
|
||||
if ($fq_class_name === $context->self
|
||||
|| (
|
||||
$statements_analyzer->getSource()->getSource() instanceof TraitAnalyzer &&
|
||||
$fq_class_name === $statements_analyzer->getSource()->getFQCLN()
|
||||
)
|
||||
) {
|
||||
$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 {
|
||||
$class_visibility = \ReflectionProperty::IS_PUBLIC;
|
||||
$class_visibility = \ReflectionProperty::IS_PUBLIC;
|
||||
}
|
||||
|
||||
try {
|
||||
$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
|
||||
}
|
||||
|
||||
try {
|
||||
$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;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!$class_constant_type) {
|
||||
|
@ -174,6 +174,53 @@ class EnumTest extends TestCase
|
||||
[],
|
||||
'8.1',
|
||||
],
|
||||
'wildcardConstantsOnEnum' => [
|
||||
'<?php
|
||||
enum A {
|
||||
const C_1 = 1;
|
||||
const C_2 = 2;
|
||||
const C_3 = 3;
|
||||
|
||||
/**
|
||||
* @param self::C_* $i
|
||||
*/
|
||||
public static function foo(int $i) : void {}
|
||||
}
|
||||
|
||||
A::foo(A::C_1);
|
||||
A::foo(A::C_2);
|
||||
A::foo(A::C_3);',
|
||||
'assertions' => [],
|
||||
[],
|
||||
'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' => [
|
||||
'<?php
|
||||
class CreateController {
|
||||
|
Loading…
Reference in New Issue
Block a user