Skip to content

Commit

Permalink
Retain int specificity when $baseTimestamp is passed in as it appears…
Browse files Browse the repository at this point in the history
… unable to cause a false return
  • Loading branch information
Seldaek committed Mar 4, 2022
1 parent 9372dc6 commit 494a7f8
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
15 changes: 12 additions & 3 deletions src/Type/Php/StrtotimeFunctionReturnTypeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
use PHPStan\Type\IntegerRangeType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeUtils;
Expand All @@ -31,7 +32,7 @@ public function isFunctionSupported(FunctionReflection $functionReflection): boo
public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type
{
$defaultReturnType = ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType();
if (count($functionCall->getArgs()) !== 1) { // strtotime() & 2nd param baseTimestamp are both unsupported use cases
if (count($functionCall->getArgs()) === 0) {
return $defaultReturnType;
}
$argType = $scope->getType($functionCall->getArgs()[0]->value);
Expand All @@ -49,9 +50,17 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
return new ConstantBooleanType(false);
}

$results = array_map('intval', $results);
// 2nd param $baseTimestamp is too non-deterministic so simply return int
if (count($functionCall->getArgs()) > 1) {
return new IntegerType();
}

// if it is positive we can narrow down to positive-int as long as time flows forward
if (min(array_map('intval', $results)) > 0) {
return IntegerRangeType::createAllGreaterThan(0);
}

return IntegerRangeType::createAllGreaterThan(min($results));
return new IntegerType();
}

}
10 changes: 5 additions & 5 deletions tests/PHPStan/Analyser/data/strtotime-return-type-extensions.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

use function PHPStan\Testing\assertType;

$strtotimeNow = strtotime('2022-03-03 12:00:00 UTC');
assertType('int<1646308801, max>', $strtotimeNow);
$strtotimeNow = strtotime('now');
assertType('positive-int', $strtotimeNow);

$strtotimeInvalid = strtotime('4 qm');
assertType('false', $strtotimeInvalid);
Expand All @@ -20,10 +20,10 @@
assertType('int|false', $strtotimeCrash);

$strtotimeWithBase = strtotime('+2 days', time());
assertType('int|false', $strtotimeWithBase);
assertType('int', $strtotimeWithBase);

$strtotimePositiveInt = strtotime('1990-01-01 12:00:00 UTC');
assertType('int<631195201, max>', $strtotimePositiveInt);
assertType('positive-int', $strtotimePositiveInt);

$strtotimeNegativeInt = strtotime('1969-12-31 12:00:00 UTC');
assertType('int<-43199, max>', $strtotimeNegativeInt);
assertType('int', $strtotimeNegativeInt);

0 comments on commit 494a7f8

Please sign in to comment.