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

Use conditional return type for range

This commit is contained in:
Brown 2020-04-07 19:59:20 -04:00
parent 69045daea9
commit a79122256c
3 changed files with 26 additions and 83 deletions

View File

@ -49,7 +49,6 @@ class FunctionReturnTypeProvider
$this->registerClass(ReturnTypeProvider\FilterVarReturnTypeProvider::class);
$this->registerClass(ReturnTypeProvider\IteratorToArrayReturnTypeProvider::class);
$this->registerClass(ReturnTypeProvider\ParseUrlReturnTypeProvider::class);
$this->registerClass(ReturnTypeProvider\RangeReturnTypeProvider::class);
$this->registerClass(ReturnTypeProvider\StrReplaceReturnTypeProvider::class);
$this->registerClass(ReturnTypeProvider\VersionCompareReturnTypeProvider::class);
$this->registerClass(ReturnTypeProvider\MktimeReturnTypeProvider::class);

View File

@ -1,82 +0,0 @@
<?php
namespace Psalm\Internal\Provider\ReturnTypeProvider;
use PhpParser;
use Psalm\CodeLocation;
use Psalm\Context;
use Psalm\StatementsSource;
use Psalm\Type;
class RangeReturnTypeProvider implements \Psalm\Plugin\Hook\FunctionReturnTypeProviderInterface
{
public static function getFunctionIds() : array
{
return ['range'];
}
/**
* @param array<PhpParser\Node\Arg> $call_args
*/
public static function getFunctionReturnType(
StatementsSource $statements_source,
string $function_id,
array $call_args,
Context $context,
CodeLocation $code_location
) : Type\Union {
if (!$statements_source instanceof \Psalm\Internal\Analyzer\StatementsAnalyzer) {
return Type::getMixed();
}
$all_ints = true;
$all_strings = true;
$all_floats = true;
$all_numbers = true;
foreach ($call_args as $call_arg) {
$is_int = false;
$is_float = false;
$is_string = false;
if ($call_arg_type = $statements_source->node_data->getType($call_arg->value)) {
if ($call_arg_type->isInt()) {
$is_int = true;
} elseif ($call_arg_type->isFloat()) {
$is_float = true;
} elseif ($call_arg_type->isString()) {
$is_string = true;
}
}
$all_ints = $all_ints && $is_int;
$all_floats = $all_floats && $is_float;
$all_strings = $all_strings && $is_string;
$all_numbers = $all_numbers && ($is_int || $is_float);
}
if ($all_ints) {
return new Type\Union([new Type\Atomic\TList(new Type\Union([new Type\Atomic\TInt]))]);
}
if ($all_strings) {
return new Type\Union([new Type\Atomic\TList(new Type\Union([new Type\Atomic\TString]))]);
}
if ($all_floats) {
return new Type\Union([new Type\Atomic\TList(new Type\Union([new Type\Atomic\TFloat]))]);
}
if ($all_numbers) {
return new Type\Union([new Type\Atomic\TList(
new Type\Union([new Type\Atomic\TInt, new Type\Atomic\TFloat])
)]);
}
return new Type\Union([new Type\Atomic\TList(
new Type\Union([new Type\Atomic\TInt, new Type\Atomic\TFloat, new Type\Atomic\TString])
)]);
}
}

View File

@ -369,3 +369,29 @@ function gettimeofday(bool $return_float = false) {}
* @return ($number is int ? int : ($number is float ? float : int|float))
*/
function abs($number) {}
/**
* @template T as string|int|float
* @template TStep as int|float
* @param T $start
* @param T $end
* @param TStep $step
* @return (
* T is int
* ? (TStep is int ? list<int> : list<int|float>)
* : (
* T is float
* ? list<float>
* : (
* T is string
* ? list<string>
* : (
* T is int|float
* ? list<int|float>
* : list<int|float|string>
* )
* )
* )
* )
*/
function range($start, $end, $step = 1) {}