From 481a5bd61d4ff63efb6b17a6b0e897efd73747ae Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Tue, 25 Apr 2023 11:41:39 +0200 Subject: [PATCH] Fix date return type provider --- .../DateReturnTypeProvider.php | 27 ++++++++++--------- tests/FunctionCallTest.php | 2 ++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/DateReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/DateReturnTypeProvider.php index 7fbfedf22..80be70826 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/DateReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/DateReturnTypeProvider.php @@ -8,10 +8,13 @@ use Psalm\Internal\Analyzer\StatementsAnalyzer; use Psalm\Plugin\EventHandler\Event\FunctionReturnTypeProviderEvent; use Psalm\Plugin\EventHandler\FunctionReturnTypeProviderInterface; use Psalm\Type; +use Psalm\Type\Atomic\TLiteralInt; +use Psalm\Type\Atomic\TLiteralString; use Psalm\Type\Union; use function array_values; -use function preg_match; +use function date; +use function is_numeric; /** * @internal @@ -35,21 +38,19 @@ class DateReturnTypeProvider implements FunctionReturnTypeProviderInterface $call_args = $event->getCallArgs(); + $format_type = Type::getString(); 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 ($type !== null + && $type->isSingleStringLiteral() + && is_numeric(date($type->getSingleStringLiteral()->value)) + ) { + $format_type = Type::getNumericString(); } } if (!isset($call_args[1])) { - return Type::getString(); + return $format_type; } $type = $source->node_data->getType($call_args[1]->value); @@ -57,10 +58,12 @@ class DateReturnTypeProvider implements FunctionReturnTypeProviderInterface $atomic_type = array_values($type->getAtomicTypes())[0]; if ($atomic_type instanceof Type\Atomic\TNumeric || $atomic_type instanceof Type\Atomic\TInt + || $atomic_type instanceof TLiteralInt + || ($atomic_type instanceof TLiteralString && is_numeric($atomic_type->value)) ) { - return Type::getString(); + return $format_type; } } - return Type::combineUnionTypes(Type::getString(), Type::getFalse()); + return Type::combineUnionTypes($format_type, Type::getFalse()); } } diff --git a/tests/FunctionCallTest.php b/tests/FunctionCallTest.php index 6429cf6a6..9342a63e5 100644 --- a/tests/FunctionCallTest.php +++ b/tests/FunctionCallTest.php @@ -1732,6 +1732,7 @@ class FunctionCallTest extends TestCase 'code' => ' [ '$y===' => 'numeric-string', '$ym===' => 'numeric-string', + '$y_m===' => 'string', '$m===' => 'numeric-string', '$F===' => 'string', '$y2===' => 'numeric-string',