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:
commit
40d4e560bc
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -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' => [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user