1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Fix #2735 - interpret template check in context of class-string generation

This commit is contained in:
Matthew Brown 2020-02-02 10:51:18 -05:00
parent f0fc9cce5f
commit b67f661604
2 changed files with 47 additions and 1 deletions

View File

@ -817,9 +817,25 @@ abstract class Type
);
}
if ($t instanceof Atomic\TTemplateParam) {
$t_atomic_types = $t->as->getAtomicTypes();
$t_atomic_type = count($t_atomic_types) === 1 ? reset($t_atomic_types) : null;
if (!$t_atomic_type instanceof TNamedObject) {
$t_atomic_type = null;
}
return new Atomic\TTemplateParamClass(
$t->param_name,
$t_atomic_type ? $t_atomic_type->value : 'object',
$t_atomic_type,
$t->defining_class
);
}
if (!$t instanceof TNamedObject) {
throw new TypeParseTreeException(
'Invalid templated classname \'' . $t . '\''
'Invalid templated classname \'' . $t->getId() . '\''
);
}

View File

@ -589,6 +589,36 @@ class FunctionTemplateAssertTest extends TestCase
}
}'
],
'noCrashWhenAsserting' => [
'<?php
/**
* @psalm-template ExpectedClassType of object
* @psalm-param class-string<ExpectedClassType> $expectedType
* @psalm-assert class-string<ExpectedClassType> $actualType
*/
function assertIsA(string $expectedType, string $actualType): void {
\assert(\is_a($actualType, $expectedType, true));
}
class Foo {
/**
* @psalm-template OriginalClass of object
* @psalm-param class-string<OriginalClass> $originalClass
* @psalm-return class-string<OriginalClass>|null
*/
private function generateProxy(string $originalClass) : ?string {
$generatedClassName = self::class . \'\\\\\' . $originalClass;
if (class_exists($generatedClassName)) {
assertIsA($originalClass, $generatedClassName);
return $generatedClassName;
}
return null;
}
}',
],
];
}