Skip to content

Commit

Permalink
Merge pull request #8567 from nosnickid/fix-min-max-return-type
Browse files Browse the repository at this point in the history
Fix MinMaxReturnTypeProvider when handling TDependentListKeys
  • Loading branch information
orklah committed Oct 11, 2022
2 parents e440b34 + 68f6ba8 commit 7ec5ffb
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
Expand Up @@ -8,17 +8,16 @@
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;
Expand Down Expand Up @@ -72,11 +71,12 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev
} 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 {
Expand Down
53 changes: 53 additions & 0 deletions tests/ReturnTypeProvider/MinMaxReturnTypeProviderTest.php
@@ -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>',
],
];
}
}

0 comments on commit 7ec5ffb

Please sign in to comment.