Skip to content

Commit

Permalink
Fixed vimeo#6966
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardoboss committed Jan 16, 2022
1 parent 9190294 commit 2585404
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
@@ -0,0 +1,57 @@
<?php declare(strict_types=1);

namespace Psalm\Internal\Provider\ReturnTypeProvider;

use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;

use function array_values;
use function count;

class RoundReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
/**
* @return array<lowercase-string>
*/
public static function getFunctionIds(): array
{
return ['round'];
}

public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Type\Union
{
$call_args = $event->getCallArgs();
if (count($call_args) === 0) {
return null;
}

$statements_source = $event->getStatementsSource();
$nodeTypeProvider = $statements_source->getNodeTypeProvider();

$num_arg = $nodeTypeProvider->getType($call_args[0]->value);

if (count($call_args) > 1) {
$precision_val = $call_args[1]->value;
} else {
$precision_val = 0;
}

if ($num_arg !== null && $num_arg->isSingle()) {
$num_type = array_values($num_arg->getAtomicTypes())[0];
if ($num_type instanceof Type\Atomic\TFloat) {
if ($precision_val > 0) {
return new Type\Union([new Type\Atomic\TFloat()]);
}

return new Type\Union([new Type\Atomic\TInt()]);
}

if ($num_type instanceof Type\Atomic\TInt) {
return new Type\Union([new Type\Atomic\TInt()]);
}
}

return new Type\Union([new Type\Atomic\TInt(), new Type\Atomic\TFloat()]);
}
}
45 changes: 45 additions & 0 deletions tests/ReturnTypeProvider/RoundTest.php
@@ -0,0 +1,45 @@
<?php

namespace Psalm\Tests\ReturnTypeProvider;

use Psalm\Tests\TestCase;
use Psalm\Tests\Traits\ValidCodeAnalysisTestTrait;

class RoundTest extends TestCase
{
use ValidCodeAnalysisTestTrait;

public function providerValidCodeParse(): iterable
{
yield 'roundWithStrictReturnType' => [
'<?php
/**
* @param float $a
* @return int
*/
function f(float $a): int
{
return round($a);
}
/**
* @param float $a
* @return positive-int
*/
function g(float $a): int
{
return round($a, -1);
}
/**
* @param float $a
* @return float
*/
function h(float $a): int
{
return round($a, 2);
}
',
];
}
}

0 comments on commit 2585404

Please sign in to comment.