1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 05:41:20 +01:00

Merge pull request #9691 from robchett/date_gmdate_return_type

Add return type provider for date/gmdate
This commit is contained in:
orklah 2023-04-21 11:33:02 +02:00 committed by GitHub
commit 40d4e560bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 12 deletions

View File

@ -23,6 +23,7 @@ use Psalm\Internal\Provider\ReturnTypeProvider\ArrayReverseReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArraySliceReturnTypeProvider; use Psalm\Internal\Provider\ReturnTypeProvider\ArraySliceReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\ArraySpliceReturnTypeProvider; use Psalm\Internal\Provider\ReturnTypeProvider\ArraySpliceReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\BasenameReturnTypeProvider; use Psalm\Internal\Provider\ReturnTypeProvider\BasenameReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\DateReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\DirnameReturnTypeProvider; use Psalm\Internal\Provider\ReturnTypeProvider\DirnameReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\FilterVarReturnTypeProvider; use Psalm\Internal\Provider\ReturnTypeProvider\FilterVarReturnTypeProvider;
use Psalm\Internal\Provider\ReturnTypeProvider\FirstArgStringReturnTypeProvider; use Psalm\Internal\Provider\ReturnTypeProvider\FirstArgStringReturnTypeProvider;
@ -101,6 +102,7 @@ class FunctionReturnTypeProvider
$this->registerClass(InArrayReturnTypeProvider::class); $this->registerClass(InArrayReturnTypeProvider::class);
$this->registerClass(RoundReturnTypeProvider::class); $this->registerClass(RoundReturnTypeProvider::class);
$this->registerClass(MbInternalEncodingReturnTypeProvider::class); $this->registerClass(MbInternalEncodingReturnTypeProvider::class);
$this->registerClass(DateReturnTypeProvider::class);
} }
/** /**

View File

@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace Psalm\Internal\Provider\ReturnTypeProvider;
use Psalm\Internal\Analyzer\StatementsAnalyzer;
use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent;
use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface;
use Psalm\Type;
use Psalm\Type\Union;
use function array_values;
use function preg_match;
/**
* @internal
*/
class DateReturnTypeProvider implements FunctionReturnTypeProviderInterface
{
/**
* @return array<lowercase-string>
*/
public static function getFunctionIds(): array
{
return ['date', 'gmdate'];
}
public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): ?Union
{
$source = $event->getStatementsSource();
if (!$source instanceof StatementsAnalyzer) {
return null;
}
$call_args = $event->getCallArgs();
if (isset($call_args[0])) {
$type = $source->node_data->getType($call_args[0]->value);
if ($type !== null && $type->isSingle()) {
$atomic_type = array_values($type->getAtomicTypes())[0];
if ($atomic_type instanceof Type\Atomic\TLiteralString
&& ($format_val = $atomic_type->value)
&& preg_match('/[djNwzWmntLoYyBgGhHisuvZUI]+/', $format_val)
) {
return Type::getNumericString();
}
}
}
if (!isset($call_args[1])) {
return Type::getString();
}
$type = $source->node_data->getType($call_args[1]->value);
if ($type !== null && $type->isSingle()) {
$atomic_type = array_values($type->getAtomicTypes())[0];
if ($atomic_type instanceof Type\Atomic\TNumeric
|| $atomic_type instanceof Type\Atomic\TInt
) {
return Type::getString();
}
}
return Type::combineUnionTypes(Type::getString(), Type::getFalse());
}
}

View File

@ -559,17 +559,6 @@ function abs($num) {}
*/ */
function range($start, $end, $step = 1) {} function range($start, $end, $step = 1) {}
/**
* @psalm-pure
*
* @return (
* $format is 'd'|'j'|'N'|'w'|'z'|'W'|'m'|'n'|'t'|'L'|'o'|'Y'|'y'|'B'|'g'|'G'|'h'|'H'|'i'|'s'|'u'|'v'|'Z'|'U'|'I'
* ? numeric-string
* : ($timestamp is numeric ? string : string|false)
* )
*/
function date(string $format, int $timestamp = 0) {}
/** /**
* @psalm-pure * @psalm-pure
* *

View File

@ -1731,19 +1731,36 @@ class FunctionCallTest extends TestCase
'dateTest' => [ 'dateTest' => [
'code' => '<?php 'code' => '<?php
$y = date("Y"); $y = date("Y");
$ym = date("Ym");
$m = date("m"); $m = date("m");
$F = date("F"); $F = date("F");
$y2 = date("Y", 10000); $y2 = date("Y", 10000);
$F2 = date("F", 10000); $F2 = date("F", 10000);
/** @psalm-suppress MixedArgument */ /** @psalm-suppress MixedArgument */
$F3 = date("F", $GLOBALS["F3"]);', $F3 = date("F", $GLOBALS["F3"]);
$gm_y = gmdate("Y");
$gm_ym = gmdate("Ym");
$gm_m = gmdate("m");
$gm_F = gmdate("F");
$gm_y2 = gmdate("Y", 10000);
$gm_F2 = gmdate("F", 10000);
/** @psalm-suppress MixedArgument */
$gm_F3 = gmdate("F", $GLOBALS["F3"]);',
'assertions' => [ 'assertions' => [
'$y===' => 'numeric-string', '$y===' => 'numeric-string',
'$ym===' => 'numeric-string',
'$m===' => 'numeric-string', '$m===' => 'numeric-string',
'$F===' => 'string', '$F===' => 'string',
'$y2===' => 'numeric-string', '$y2===' => 'numeric-string',
'$F2===' => 'string', '$F2===' => 'string',
'$F3===' => 'false|string', '$F3===' => 'false|string',
'$gm_y===' => 'numeric-string',
'$gm_ym===' => 'numeric-string',
'$gm_m===' => 'numeric-string',
'$gm_F===' => 'string',
'$gm_y2===' => 'numeric-string',
'$gm_F2===' => 'string',
'$gm_F3===' => 'false|string',
], ],
], ],
'sscanfReturnTypeWithTwoParameters' => [ 'sscanfReturnTypeWithTwoParameters' => [