Skip to content

Commit

Permalink
Use wider class-string when combining class strings with intersections
Browse files Browse the repository at this point in the history
Fixes #10799
  • Loading branch information
weirdan committed Mar 9, 2024
1 parent 87f7101 commit 739d87d
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/Psalm/Internal/Type/TypeCombiner.php
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,20 @@ private static function scrapeStringProperties(
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) {
Expand Down
7 changes: 7 additions & 0 deletions tests/TypeCombinationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,13 @@ public function providerTestValidTypeCombination(): array
'"0"',
],
],
'unionOfClassStringAndClassStringWithIntersection' => [
'class-string<IFoo>',
[
'class-string<IFoo>',
'class-string<IFoo & IBar>',
],
],
];
}

Expand Down
8 changes: 8 additions & 0 deletions tests/TypeParseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,14 @@ public function testIntMaskOfWithValidValueOf(): void
$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')) {
Expand Down

0 comments on commit 739d87d

Please sign in to comment.