Skip to content

Commit

Permalink
Allow union of class-strings in signature
Browse files Browse the repository at this point in the history
Ref #1851
  • Loading branch information
muglug committed Jun 27, 2019
1 parent 3088432 commit ba121a9
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 2 deletions.
6 changes: 5 additions & 1 deletion src/Psalm/Internal/Type/TypeCombination.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -877,7 +877,11 @@ private static function scrapeTypeProperties(
return null; return null;
} }


if ($type instanceof TLiteralString) { if ($type instanceof Type\Atomic\TTemplateParamClass) {
$combination->value_types[$type_key] = $type;
} elseif ($type instanceof Type\Atomic\TClassString && $type->as !== 'object') {
$combination->value_types[$type_key] = $type;
} elseif ($type instanceof TLiteralString) {
if ($combination->strings !== null && count($combination->strings) < $literal_limit) { if ($combination->strings !== null && count($combination->strings) < $literal_limit) {
$combination->strings[$type_key] = $type; $combination->strings[$type_key] = $type;
} else { } else {
Expand Down
2 changes: 1 addition & 1 deletion src/Psalm/Type/Atomic/TTemplateParamClass.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function __toString()
*/ */
public function getId() public function getId()
{ {
return $this->getKey(); return 'class-string<' . $this->param_name . ' as ' . $this->as . '>';
} }


/** /**
Expand Down
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -487,6 +487,24 @@ class A {}
bar(foo(A::class));', bar(foo(A::class));',
], ],
'templateAsUnionClassStringPassingValidClass' => [
'<?php
class A {}
class B {}
/**
* @template T1 as A
* @template T2 as B
* @param class-string<T1>|class-string<T2> $type
* @return T1|T2
*/
function f(string $type) {
return new $type();
}
f(A::class);
f(B::class);',
],
]; ];
} }


Expand Down Expand Up @@ -552,6 +570,25 @@ function bar(Traversable $t) : void {
}', }',
'error_message' => 'MixedArgumentTypeCoercion', 'error_message' => 'MixedArgumentTypeCoercion',
], ],
'templateAsUnionClassStringPassingInvalidClass' => [
'<?php
class A {}
class B {}
class C {}
/**
* @template T1 as A
* @template T2 as B
* @param class-string<T1>|class-string<T2> $type
* @return T1|T2
*/
function f(string $type) {
return new $type();
}
f(C::class);',
'error_message' => 'InvalidArgument',
],
]; ];
} }
} }
8 changes: 8 additions & 0 deletions tests/TypeParseTest.php
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -291,6 +291,14 @@ public function testParamaterizedClassString()
$this->assertSame('class-string<A>', (string) Type::parseString('class-string<A>')); $this->assertSame('class-string<A>', (string) Type::parseString('class-string<A>'));
} }


/**
* @return void
*/
public function testParamaterizedClassStringUnion()
{
$this->assertSame('class-string<A>|class-string<B>', (string) Type::parseString('class-string<A>|class-string<B>'));
}

/** /**
* *
* @return void * @return void
Expand Down

0 comments on commit ba121a9

Please sign in to comment.