Skip to content
Permalink
Browse files

Fix assertions with single templated class-string

  • Loading branch information...
muglug committed May 27, 2019
1 parent 26e7a81 commit b2fb80978e382c045d3d44a8d1aafd9347429bef
Showing with 134 additions and 0 deletions.
  1. +9 −0 src/Psalm/Type/Union.php
  2. +125 −0 tests/AssertTest.php
@@ -1053,6 +1053,8 @@ public function replaceTemplateTypesWithStandins(
&& isset($template_types[$atomic_type->param_name])
) {
if ($replace) {
$was_single = $this->isSingle();
$class_string = new Type\Atomic\TClassString($atomic_type->as, $atomic_type->as_type);
$keys_to_unset[] = $key;
@@ -1085,6 +1087,8 @@ public function replaceTemplateTypesWithStandins(
$valid_input_atomic_types[] = new Type\Atomic\TNamedObject(
$input_atomic_type->as
);
} else {
$valid_input_atomic_types[] = new Type\Atomic\TObject();
}
}
}
@@ -1097,6 +1101,11 @@ public function replaceTemplateTypesWithStandins(
$generic_param,
$depth
];
} elseif ($was_single) {
$generic_params[$atomic_type->param_name][$atomic_type->defining_class ?: ''] = [
Type::getMixed(),
$depth
];
}
}
}
@@ -280,6 +280,131 @@ function getImplementationOfFoo(): Foo {
$bar->sayHello();',
],
'assertInstanceofTemplatedClassMethodUnknownClass' => [
'<?php
namespace Bar;
class C {
/**
* @template T
* @param class-string<T> $expected
* @param mixed $actual
* @psalm-assert T $actual
*/
public function assertInstanceOf($expected, $actual) : void {}
/**
* @param class-string $c
*/
function bar(string $c, object $e) : void {
$this->assertInstanceOf($c, $e);
echo $e->getCode();
}
}',
[],
['MixedArgument', 'MixedMethodCall'],
],
'assertInstanceofTemplatedClassMethodUnknownStringClass' => [
'<?php
namespace Bar;
class C {
/**
* @template T
* @param class-string<T> $expected
* @param mixed $actual
* @psalm-assert T $actual
*/
public function assertInstanceOf($expected, $actual) : void {}
function bar(string $c, object $e) : void {
$this->assertInstanceOf($c, $e);
echo $e->getCode();
}
}',
[],
['MixedArgument', 'MixedMethodCall', 'ArgumentTypeCoercion'],
],
'assertInstanceofTemplatedFunctionUnknownClass' => [
'<?php
namespace Bar;
/**
* @template T
* @param class-string<T> $expected
* @param mixed $actual
* @psalm-assert T $actual
*/
function assertInstanceOf($expected, $actual) : void {}
/**
* @param class-string $c
*/
function bar(string $c, object $e) : void {
assertInstanceOf($c, $e);
echo $e->getCode();
}',
[],
['MixedArgument', 'MixedMethodCall'],
],
'assertInstanceofTemplatedFunctionUnknownStringClass' => [
'<?php
namespace Bar;
/**
* @template T
* @param class-string<T> $expected
* @param mixed $actual
* @psalm-assert T $actual
*/
function assertInstanceOf($expected, $actual) : void {}
function bar(string $c, object $e) : void {
assertInstanceOf($c, $e);
echo $e->getCode();
}',
[],
['MixedArgument', 'MixedMethodCall', 'ArgumentTypeCoercion'],
],
'assertTemplatedTypeString' => [
'<?php
interface Foo {
function bat() : void;
}
/**
* @param mixed $value
* @param class-string $type
* @template T
* @template-typeof T $type
* @psalm-assert T $value
*/
function assertInstanceOf($value, string $type): void {
// some code
}
function getFoo() : Foo {
return new class implements Foo {
public function bat(): void {
echo "Hello";
}
};
}
$f = getFoo();
/**
* @var mixed
* @psalm-suppress MixedAssignment
*/
$class = "hello";
/** @psalm-suppress MixedArgument */
assertInstanceOf($f, $class);
$f->bat();',
[
'$f' => 'Foo',
]
],
'dontBleedBadAssertVarIntoContext' => [
'<?php
namespace Bar;

0 comments on commit b2fb809

Please sign in to comment.
You can’t perform that action at this time.