1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

Merge pull request #8567 from nosnickid/fix-min-max-return-type

Fix MinMaxReturnTypeProvider when handling TDependentListKeys
This commit is contained in:
orklah 2022-10-11 19:09:17 +02:00 committed by GitHub
commit 7ec5ffbd5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 5 deletions

View File

@ -8,17 +8,16 @@ use Psalm\Internal\Type\ArrayType;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Atomic\TDependentListKey;
use Psalm\Type\Atomic\TInt;
use Psalm\Type\Atomic\TIntRange;
use Psalm\Type\Atomic\TLiteralInt;
use Psalm\Type\Atomic\TPositiveInt;
use Psalm\Type\Union;
use UnexpectedValueException;
use function array_filter;
use function assert;
use function count;
use function get_class;
use function in_array;
use function max;
use function min;
@ -72,11 +71,12 @@ class MinMaxReturnTypeProvider implements FunctionReturnTypeProviderInterface
} elseif ($atomic_type instanceof TPositiveInt) {
$min_bounds[] = 1;
$max_bounds[] = null;
} elseif (get_class($atomic_type) === TInt::class) {
} elseif ($atomic_type instanceof TDependentListKey) {
$min_bounds[] = 0;
$max_bounds[] = null;
} else {//already guarded by the `instanceof TInt` check above
$min_bounds[] = null;
$max_bounds[] = null;
} else {
throw new UnexpectedValueException('Unexpected type');
}
}
} else {

View File

@ -0,0 +1,53 @@
<?php
namespace Psalm\Tests\ReturnTypeProvider;
use Psalm\Tests\TestCase;
use Psalm\Tests\Traits\ValidCodeAnalysisTestTrait;
class MinMaxReturnTypeProviderTest extends TestCase
{
use ValidCodeAnalysisTestTrait;
public function providerValidCodeParse(): iterable
{
yield 'literalInt' => [
'<?php
$min = min(1, 2);
$max = max(3, 4);
',
[
'$min' => 'int',
'$max' => 'int',
],
];
yield 'nonInt' => [
'<?php
$min = min("a", "b");
$max = max("x", "y");
',
[
'$min' => 'string',
'$max' => 'string',
],
];
yield 'maxIntRange' => [
'<?php
$headers = fgetcsv(fopen("test.txt", "r"));
$h0 = $h1 = null;
foreach($headers as $i => $v) {
if ($v === "") $h0 = $i;
if ($v === "") $h1 = $i;
}
if ($h0 === null || $h1 === null) throw new \Exception();
$min = min($h0, $h1);
$max = max($h0, $h1);
',
[
'$min' => 'int<0, max>',
'$max' => 'int<0, max>',
],
];
}
}