mirror of
https://github.com/danog/psalm.git
synced 2024-12-02 09:37:59 +01:00
Merge pull request #10357 from robchett/inherit_conditional_function_templates
Inherit conditional returns
This commit is contained in:
commit
0e43c441d0
@ -577,7 +577,7 @@ final class MethodCallReturnTypeFetcher
|
||||
) {
|
||||
if ($template_type->param_name === 'TFunctionArgCount') {
|
||||
$template_result->lower_bounds[$template_type->param_name] = [
|
||||
'fn-' . strtolower((string) $method_id) => [
|
||||
'fn-' . $method_id->method_name => [
|
||||
new TemplateBound(
|
||||
Type::getInt(false, $arg_count),
|
||||
),
|
||||
@ -585,7 +585,7 @@ final class MethodCallReturnTypeFetcher
|
||||
];
|
||||
} elseif ($template_type->param_name === 'TPhpMajorVersion') {
|
||||
$template_result->lower_bounds[$template_type->param_name] = [
|
||||
'fn-' . strtolower((string) $method_id) => [
|
||||
'fn-' . $method_id->method_name => [
|
||||
new TemplateBound(
|
||||
Type::getInt(false, $codebase->getMajorAnalysisPhpVersion()),
|
||||
),
|
||||
@ -593,7 +593,7 @@ final class MethodCallReturnTypeFetcher
|
||||
];
|
||||
} elseif ($template_type->param_name === 'TPhpVersionId') {
|
||||
$template_result->lower_bounds[$template_type->param_name] = [
|
||||
'fn-' . strtolower((string) $method_id) => [
|
||||
'fn-' . $method_id->method_name => [
|
||||
new TemplateBound(
|
||||
Type::getInt(
|
||||
false,
|
||||
|
@ -629,7 +629,7 @@ final class ExistingAtomicStaticCallAnalyzer
|
||||
): array {
|
||||
if ($template_type->param_name === 'TFunctionArgCount') {
|
||||
return [
|
||||
'fn-' . strtolower((string)$method_id) => [
|
||||
'fn-' . $method_id->method_name => [
|
||||
new TemplateBound(
|
||||
Type::getInt(false, count($stmt->getArgs())),
|
||||
),
|
||||
@ -639,7 +639,7 @@ final class ExistingAtomicStaticCallAnalyzer
|
||||
|
||||
if ($template_type->param_name === 'TPhpMajorVersion') {
|
||||
return [
|
||||
'fn-' . strtolower((string)$method_id) => [
|
||||
'fn-' . $method_id->method_name => [
|
||||
new TemplateBound(
|
||||
Type::getInt(false, $codebase->getMajorAnalysisPhpVersion()),
|
||||
),
|
||||
@ -649,7 +649,7 @@ final class ExistingAtomicStaticCallAnalyzer
|
||||
|
||||
if ($template_type->param_name === 'TPhpVersionId') {
|
||||
return [
|
||||
'fn-' . strtolower((string) $method_id) => [
|
||||
'fn-' . $method_id->method_name => [
|
||||
new TemplateBound(
|
||||
Type::getInt(
|
||||
false,
|
||||
|
@ -512,9 +512,8 @@ final class FunctionLikeDocblockScanner
|
||||
|
||||
if ($token_body === 'func_num_args()') {
|
||||
$template_name = 'TFunctionArgCount';
|
||||
|
||||
$storage->template_types[$template_name] = [
|
||||
$template_function_id => Type::getInt(),
|
||||
'fn-' . strtolower($storage->cased_name ?? '') => Type::getInt(),
|
||||
];
|
||||
|
||||
$function_template_types[$template_name]
|
||||
@ -527,7 +526,7 @@ final class FunctionLikeDocblockScanner
|
||||
$template_name = 'TPhpMajorVersion';
|
||||
|
||||
$storage->template_types[$template_name] = [
|
||||
$template_function_id => Type::getInt(),
|
||||
'fn-' . strtolower($storage->cased_name ?? '') => Type::getInt(),
|
||||
];
|
||||
|
||||
$function_template_types[$template_name]
|
||||
@ -540,7 +539,7 @@ final class FunctionLikeDocblockScanner
|
||||
$template_name = 'TPhpVersionId';
|
||||
|
||||
$storage->template_types[$template_name] = [
|
||||
$template_function_id => Type::getInt(),
|
||||
'fn-' . strtolower($storage->cased_name ?? '') => Type::getInt(),
|
||||
];
|
||||
|
||||
$function_template_types[$template_name]
|
||||
|
@ -463,6 +463,31 @@ class ConditionalReturnTypeTest extends TestCase
|
||||
'$c' => 'string',
|
||||
],
|
||||
],
|
||||
'InheritFuncNumArgs' => [
|
||||
'code' => '<?php
|
||||
abstract class A
|
||||
{
|
||||
/**
|
||||
* @psalm-return (func_num_args() is 1 ? string : int)
|
||||
*/
|
||||
public static function get(bool $a, ?bool $b = null)
|
||||
{
|
||||
if ($b) {
|
||||
return 1;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A
|
||||
{
|
||||
|
||||
public static function getB(bool $a): int
|
||||
{
|
||||
return self::get($a, true);
|
||||
}
|
||||
}',
|
||||
],
|
||||
'namespaceFuncNumArgs' => [
|
||||
'code' => '<?php
|
||||
namespace Foo;
|
||||
@ -887,6 +912,39 @@ class ConditionalReturnTypeTest extends TestCase
|
||||
'ignored_issues' => [],
|
||||
'php_version' => '7.2',
|
||||
],
|
||||
'ineritedreturnTypeBasedOnPhpVersionId' => [
|
||||
'code' => '<?php
|
||||
class A {
|
||||
/**
|
||||
* @psalm-return (PHP_VERSION_ID is int<70300, max> ? string : int)
|
||||
*/
|
||||
function getSomething()
|
||||
{
|
||||
return mt_rand(1, 10) > 5 ? "a value" : 42;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-return (PHP_VERSION_ID is int<70100, max> ? string : int)
|
||||
*/
|
||||
function getSomethingElse()
|
||||
{
|
||||
return mt_rand(1, 10) > 5 ? "a value" : 42;
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A {}
|
||||
|
||||
$class = new B();
|
||||
$something = $class->getSomething();
|
||||
$somethingElse = $class->getSomethingElse();
|
||||
',
|
||||
'assertions' => [
|
||||
'$something' => 'int',
|
||||
'$somethingElse' => 'string',
|
||||
],
|
||||
'ignored_issues' => [],
|
||||
'php_version' => '7.2',
|
||||
],
|
||||
'ineritedConditionalTemplatedReturnType' => [
|
||||
'code' => '<?php
|
||||
/** @template InstanceType */
|
||||
|
Loading…
Reference in New Issue
Block a user