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

Fix #3453 - allow conditional return types on instance methods

This commit is contained in:
Brown 2020-05-25 09:39:30 -04:00
parent 3416e33348
commit be847472a2
4 changed files with 48 additions and 3 deletions

View File

@ -141,7 +141,10 @@ class MethodCallReturnTypeFetcher
) {
if ($template_type->param_name === 'TFunctionArgCount') {
$template_result->upper_bounds[$template_type->param_name] = [
'fn-' . $method_id => [Type::getInt(false, \count($stmt->args)), 0]
'fn-' . strtolower((string) $method_id) => [
Type::getInt(false, \count($stmt->args)),
0
]
];
} else {
$template_result->upper_bounds[$template_type->param_name] = [

View File

@ -911,7 +911,10 @@ class StaticCallAnalyzer extends \Psalm\Internal\Analyzer\Statements\Expression\
)) {
if ($template_type->param_name === 'TFunctionArgCount') {
$template_result->upper_bounds[$template_type->param_name] = [
'fn-' . $method_id => [Type::getInt(false, count($stmt->args)), 0]
'fn-' . strtolower((string) $method_id) => [
Type::getInt(false, count($stmt->args)),
0
]
];
} else {
$template_result->upper_bounds[$template_type->param_name] = [

View File

@ -1,6 +1,7 @@
<?php
namespace Psalm\Internal\TypeVisitor;
use Psalm\Type\Atomic\TConditional;
use Psalm\Type\Atomic\TTemplateParam;
use Psalm\Type\Atomic\TTemplateParamClass;
use Psalm\Type\TypeNode;
@ -26,6 +27,12 @@ class TemplateTypeCollector extends NodeVisitor
$extends ? new Union([$extends]) : \Psalm\Type::getMixed(),
$type->defining_class
);
} elseif ($type instanceof TConditional) {
$this->template_types[] = new TTemplateParam(
$type->param_name,
\Psalm\Type::getMixed(),
$type->defining_class
);
}
return null;

View File

@ -474,7 +474,9 @@ class ConditionalReturnTypeTest extends TestCase
}
return $s;
}',
}
$a = zeroArgsFalseOneArgString("hello");',
],
'nullableReturnType' => [
'<?php
@ -488,6 +490,36 @@ class ConditionalReturnTypeTest extends TestCase
return null;
}'
],
'conditionalOrDefault' => [
'<?php
/**
* @template TKey
* @template TValue
*/
interface C {
/**
* @template TDefault
* @param TKey $key
* @param TDefault $default
* @return (
* func_num_args() is 1
* ? TValue
* : TValue|TDefault
* )
*/
public function get($key, $default = null);
}
/** @param C<string, DateTime> $c */
function getDateTime(C $c) : DateTime {
return $c->get("t");
}
/** @param C<string, DateTime> $c */
function getNullableDateTime(C $c) : ?DateTime {
return $c->get("t", null);
}'
],
];
}
}