mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Add support for conditional checks on literal ints & strings
This commit is contained in:
parent
7fdccc0439
commit
1439c90789
@ -2641,7 +2641,30 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
return new Type\Union([new Type\Atomic\TLiteralInt($value)]);
|
||||
}
|
||||
|
||||
if ($existing_var_type->hasInt()) {
|
||||
$has_int = false;
|
||||
|
||||
foreach ($existing_var_atomic_types as $existing_var_atomic_type) {
|
||||
if ($existing_var_atomic_type instanceof TInt) {
|
||||
$has_int = true;
|
||||
} elseif ($existing_var_atomic_type instanceof TTemplateParam) {
|
||||
if ($existing_var_atomic_type->as->hasMixed()
|
||||
|| $existing_var_atomic_type->as->hasScalar()
|
||||
|| $existing_var_atomic_type->as->hasNumeric()
|
||||
) {
|
||||
if ($is_loose_equality) {
|
||||
return $existing_var_type;
|
||||
}
|
||||
|
||||
return new Type\Union([new Type\Atomic\TLiteralInt($value)]);
|
||||
}
|
||||
|
||||
if ($existing_var_atomic_type->as->hasInt()) {
|
||||
$has_int = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($has_int) {
|
||||
$existing_int_types = $existing_var_type->getLiteralInts();
|
||||
|
||||
if ($existing_int_types) {
|
||||
@ -2744,7 +2767,30 @@ class AssertionReconciler extends \Psalm\Type\Reconciler
|
||||
return new Type\Union([new Type\Atomic\TLiteralString($value)]);
|
||||
}
|
||||
|
||||
if ($existing_var_type->hasString()) {
|
||||
$has_string = false;
|
||||
|
||||
foreach ($existing_var_atomic_types as $existing_var_atomic_type) {
|
||||
if ($existing_var_atomic_type instanceof TString) {
|
||||
$has_string = true;
|
||||
} elseif ($existing_var_atomic_type instanceof TTemplateParam) {
|
||||
if ($existing_var_atomic_type->as->hasMixed()
|
||||
|| $existing_var_atomic_type->as->hasScalar()
|
||||
|| $existing_var_atomic_type->as->hasArrayKey()
|
||||
) {
|
||||
if ($is_loose_equality) {
|
||||
return $existing_var_type;
|
||||
}
|
||||
|
||||
return new Type\Union([new Type\Atomic\TLiteralString($value)]);
|
||||
}
|
||||
|
||||
if ($existing_var_atomic_type->as->hasString()) {
|
||||
$has_string = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($has_string) {
|
||||
$existing_string_types = $existing_var_type->getLiteralStrings();
|
||||
|
||||
if ($existing_string_types) {
|
||||
|
@ -1151,6 +1151,66 @@ class AnnotationTest extends TestCase
|
||||
'$c' => 'array<string, string>|string'
|
||||
]
|
||||
],
|
||||
'nestedConditionalOnIntReturnType' => [
|
||||
'<?php
|
||||
/**
|
||||
* @template T as int
|
||||
* @param T $i
|
||||
* @psalm-return (T is 0 ? string : (T is 1 ? int : bool))
|
||||
*/
|
||||
function getDifferentType(int $i) {
|
||||
if ($i === 0) {
|
||||
return "hello";
|
||||
}
|
||||
|
||||
if ($i === 1) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
return true;
|
||||
}'
|
||||
],
|
||||
'nestedConditionalOnStringsReturnType' => [
|
||||
'<?php
|
||||
/**
|
||||
* @template T as string
|
||||
* @param T $i
|
||||
* @psalm-return (T is "0" ? string : (T is "1" ? int : bool))
|
||||
*/
|
||||
function getDifferentType(string $i) {
|
||||
if ($i === "0") {
|
||||
return "hello";
|
||||
}
|
||||
|
||||
if ($i === "1") {
|
||||
return 5;
|
||||
}
|
||||
|
||||
return true;
|
||||
}'
|
||||
],
|
||||
'nestedConditionalOnClassStringsReturnType' => [
|
||||
'<?php
|
||||
class A {}
|
||||
class B {}
|
||||
|
||||
/**
|
||||
* @template T as string
|
||||
* @param T $i
|
||||
* @psalm-return (T is A::class ? string : (T is B::class ? int : bool))
|
||||
*/
|
||||
function getDifferentType(string $i) {
|
||||
if ($i === A::class) {
|
||||
return "hello";
|
||||
}
|
||||
|
||||
if ($i === B::class) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
return true;
|
||||
}'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user