1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Use wider class-string when combining class strings with intersections

Fixes vimeo/psalm#10799
This commit is contained in:
Bruce Weirdan 2024-03-09 18:25:46 +01:00
parent 87f7101e01
commit 739d87dba7
3 changed files with 29 additions and 1 deletions

View File

@ -1005,7 +1005,20 @@ final class TypeCombiner
if (!$type->as_type) {
$combination->class_string_types['object'] = new TObject();
} else {
$combination->class_string_types[$type->as] = $type->as_type;
if (isset($combination->class_string_types[$type->as])
&& $combination->class_string_types[$type->as] instanceof TNamedObject
) {
if ($combination->class_string_types[$type->as]->extra_types === []) {
// do nothing, existing type is wider or the same
} elseif ($type->as_type->extra_types === []) {
$combination->class_string_types[$type->as] = $type->as_type;
} else {
// todo: figure out what to do with class-string<A&B>|class-string<A&C>
$combination->class_string_types[$type->as] = $type->as_type;
}
} else {
$combination->class_string_types[$type->as] = $type->as_type;
}
}
} elseif ($type instanceof TLiteralString) {
if ($combination->strings !== null && count($combination->strings) < $literal_limit) {

View File

@ -940,6 +940,13 @@ class TypeCombinationTest extends TestCase
'"0"',
],
],
'unionOfClassStringAndClassStringWithIntersection' => [
'class-string<IFoo>',
[
'class-string<IFoo>',
'class-string<IFoo & IBar>',
],
],
];
}

View File

@ -1148,6 +1148,14 @@ class TypeParseTest extends TestCase
$this->assertSame('int-mask-of<value-of<A::FOO>>', $docblock_type->getId());
}
public function testUnionOfClassStringAndClassStringWithIntersection(): void
{
$this->assertSame(
'class-string<IFoo>',
(string) Type::parseString('class-string<IFoo>|class-string<IFoo&IBar>'),
);
}
public function testReflectionTypeParse(): void
{
if (!function_exists('Psalm\Tests\someFunction')) {