Skip to content

Commit

Permalink
Merge pull request #10109 from weirdan/fix-10090
Browse files Browse the repository at this point in the history
  • Loading branch information
weirdan committed Aug 13, 2023
2 parents 84bbf2b + 4ca9dcc commit a645331
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 9 deletions.
Expand Up @@ -228,7 +228,7 @@ public static function analyze(
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,
Expand Down Expand Up @@ -979,16 +979,31 @@ public static function processUnspecialTaints(
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(
Expand Down
36 changes: 36 additions & 0 deletions tests/EnumTest.php
Expand Up @@ -574,6 +574,42 @@ enum IntEnum: int {
'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',
],
];
}

Expand Down

0 comments on commit a645331

Please sign in to comment.