1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Merge pull request #10109 from weirdan/fix-10090

This commit is contained in:
Bruce Weirdan 2023-08-13 06:03:45 +02:00 committed by GitHub
commit a645331026
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 9 deletions

View File

@ -228,7 +228,7 @@ class AtomicPropertyFetchAnalyzer
self::handleEnumValue($statements_analyzer, $stmt, $stmt_var_type, $class_storage);
} elseif ($prop_name === 'name') {
$has_valid_fetch_type = true;
self::handleEnumName($statements_analyzer, $stmt, $lhs_type_part);
self::handleEnumName($statements_analyzer, $stmt, $stmt_var_type, $class_storage);
} else {
self::handleNonExistentProperty(
$statements_analyzer,
@ -979,16 +979,31 @@ class AtomicPropertyFetchAnalyzer
private static function handleEnumName(
StatementsAnalyzer $statements_analyzer,
PropertyFetch $stmt,
Atomic $lhs_type_part
Union $stmt_var_type,
ClassLikeStorage $class_storage
): void {
if ($lhs_type_part instanceof TEnumCase) {
$statements_analyzer->node_data->setType(
$stmt,
new Union([Type::getAtomicStringFromLiteral($lhs_type_part->case_name)]),
);
} else {
$statements_analyzer->node_data->setType($stmt, Type::getNonEmptyString());
$relevant_enum_cases = array_filter(
$stmt_var_type->getAtomicTypes(),
static fn(Atomic $type): bool => $type instanceof TEnumCase,
);
$relevant_enum_case_names = array_map(
static fn(TEnumCase $enumCase): string => $enumCase->case_name,
$relevant_enum_cases,
);
if (empty($relevant_enum_case_names)) {
$relevant_enum_case_names = array_keys($class_storage->enum_cases);
}
$statements_analyzer->node_data->setType(
$stmt,
empty($relevant_enum_case_names)
? Type::getNonEmptyString()
: new Union(array_map(
fn(string $name): TString => Type::getAtomicStringFromLiteral($name),
$relevant_enum_case_names,
)),
);
}
private static function handleEnumValue(

View File

@ -574,6 +574,42 @@ class EnumTest extends TestCase
'ignored_issues' => [],
'php_version' => '8.1',
],
'nameTypeOnKnownCases' => [
'code' => <<<'PHP'
<?php
enum Transport: string {
case CAR = 'car';
case BIKE = 'bike';
case BOAT = 'boat';
}
$val = Transport::from(uniqid());
$_name = $val->name;
PHP,
'assertions' => [
'$_name===' => "'BIKE'|'BOAT'|'CAR'",
],
'ignored_issues' => [],
'php_version' => '8.1',
],
'nameTypeOnUnknownCases' => [
'code' => <<<'PHP'
<?php
enum Transport: string {
case CAR = 'car';
case BIKE = 'bike';
case BOAT = 'boat';
}
function f(Transport $e): void {
$_name = $e->name;
/** @psalm-check-type-exact $_name='BIKE'|'BOAT'|'CAR' */;
}
PHP,
'assertions' => [],
'ignored_issues' => [],
'php_version' => '8.1',
],
];
}