Skip to content

Commit

Permalink
Fix #1911 - allow proper namespaces in union assertions
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Jul 7, 2019
1 parent ea83068 commit bceb4ef
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 5 deletions.
17 changes: 12 additions & 5 deletions src/Psalm/Internal/Visitor/ReflectorVisitor.php
Expand Up @@ -2440,11 +2440,18 @@ private function getAssertionParts(
$assertion_type_parts = explode('|', $assertion_type); $assertion_type_parts = explode('|', $assertion_type);


foreach ($assertion_type_parts as $i => $assertion_type_part) { foreach ($assertion_type_parts as $i => $assertion_type_part) {
if ($assertion_type_part !== 'falsy' if ($assertion_type_part !== 'falsy') {
&& !isset($template_types[$assertion_type_part]) $namespaced_type = Type::parseTokens(
&& !isset(Type::PSALM_RESERVED_WORDS[$assertion_type_part]) Type::fixUpLocalType(
) { $assertion_type_part,
$assertion_type_parts[$i] = $prefix . Type::getFQCLNFromString($assertion_type_part, $this->aliases); $this->aliases,
$this->function_template_types + $this->class_template_types,
$this->type_aliases,
null
)
);

$assertion_type_parts[$i] = $prefix . $namespaced_type->getId();
} else { } else {
$assertion_type_parts[$i] = $prefix . $assertion_type_part; $assertion_type_parts[$i] = $prefix . $assertion_type_part;
} }
Expand Down
48 changes: 48 additions & 0 deletions tests/AssertTest.php
Expand Up @@ -908,6 +908,54 @@ function assertIntOrFoo($b) : void {
if (!is_int($a)) $a->bar();', if (!is_int($a)) $a->bar();',
], ],
'assertUnionInNamespace' => [
'<?php
namespace Foo\Bar\Baz;
/**
* @psalm-template ExpectedType of object
* @param mixed $value
* @psalm-param class-string<ExpectedType> $interface
* @psalm-assert ExpectedType|class-string<ExpectedType> $value
*/
function implementsInterface($value, $interface, string $message = ""): void {}
/**
* @psalm-template ExpectedType of object
* @param mixed $value
* @psalm-param class-string<ExpectedType> $interface
* @psalm-assert null|ExpectedType|class-string<ExpectedType> $value
*/
function nullOrImplementsInterface(?object $value, $interface, string $message = ""): void {}
interface A
{
}
/**
* @param mixed $value
*
* @psalm-return A|class-string<A>
*/
function consume($value) {
implementsInterface($value, A::class);
return $value;
}
/**
* @param mixed $value
*
* @psalm-return A|class-string<A>|null
*/
function consume2($value)
{
nullOrImplementsInterface($value, A::class);
return $value;
}'
],
]; ];
} }


Expand Down

0 comments on commit bceb4ef

Please sign in to comment.