1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Fix templating class-string unions

This commit is contained in:
Matthew Brown 2020-02-01 15:02:39 -05:00
parent e48dc2d158
commit 6dbb911da1
2 changed files with 44 additions and 9 deletions

View File

@ -578,19 +578,30 @@ class UnionTemplateHandler
}
}
$generic_param = null;
if ($valid_input_atomic_types) {
$generic_param = new Union($valid_input_atomic_types);
$generic_param->setFromDocblock();
} elseif ($was_single) {
$generic_param = \Psalm\Type::getMixed();
}
if ($generic_param) {
if (isset($template_result->generic_params[$atomic_type->param_name][$atomic_type->defining_class])) {
$template_result->generic_params[$atomic_type->param_name][$atomic_type->defining_class] = [
\Psalm\Type::combineUnionTypes(
$generic_param,
$template_result->generic_params[$atomic_type->param_name][$atomic_type->defining_class][0]
),
$depth
];
} else {
$template_result->generic_params[$atomic_type->param_name][$atomic_type->defining_class] = [
$generic_param,
$depth,
];
} elseif ($was_single) {
$template_result->generic_params[$atomic_type->param_name][$atomic_type->defining_class] = [
\Psalm\Type::getMixed(),
$depth,
];
}
}
}

View File

@ -585,6 +585,30 @@ class FunctionClassStringTemplateTest extends TestCase
throw new \Exception();
}',
],
'templateFromDifferentClassStrings' => [
'<?php
class A {}
class B extends A {}
class C extends A {}
/**
* @template T of A
* @param class-string<T> $a1
* @param class-string<T> $a2
* @return T
*/
function test(string $a1, string $a2) {
if (rand(0, 1)) return new $a1();
return new $a2();
}
$b_or_c = test(B::class, C::class);',
[
'$b_or_c' => 'B|C',
]
],
];
}