Skip to content

Commit

Permalink
implement DateIntervalDynamicReturnTypeExtension
Browse files Browse the repository at this point in the history
  • Loading branch information
verfriemelt-dot-org committed Dec 12, 2022
1 parent 94ca7b2 commit 7b4b767
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
5 changes: 5 additions & 0 deletions conf/config.neon
Expand Up @@ -1320,6 +1320,11 @@ services:
tags:
- phpstan.dynamicStaticMethodThrowTypeExtension

-
class: PHPStan\Type\Php\DateIntervalDynamicReturnTypeExtension
tags:
- phpstan.broker.dynamicStaticMethodReturnTypeExtension

-
class: PHPStan\Type\Php\DateTimeCreateDynamicReturnTypeExtension
tags:
Expand Down
2 changes: 1 addition & 1 deletion resources/functionMap.php
Expand Up @@ -1583,7 +1583,7 @@
'DateInterval::__construct' => ['void', 'spec'=>'string'],
'DateInterval::__set_state' => ['DateInterval', 'array'=>'array'],
'DateInterval::__wakeup' => ['void'],
'DateInterval::createFromDateString' => ['DateInterval', 'time'=>'string'],
'DateInterval::createFromDateString' => ['DateInterval|false', 'time'=>'string'],
'DateInterval::format' => ['string', 'format'=>'string'],
'DatePeriod::__construct' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'recur'=>'int', 'options='=>'int'],
'DatePeriod::__construct\'1' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'end'=>'DateTimeInterface', 'options='=>'int'],
Expand Down
45 changes: 45 additions & 0 deletions src/Type/Php/DateIntervalDynamicReturnTypeExtension.php
@@ -0,0 +1,45 @@
<?php declare(strict_types = 1);

namespace PHPStan\Type\Php;

use DateInterval;
use PhpParser\Node\Expr\StaticCall;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\DynamicStaticMethodReturnTypeExtension;
use PHPStan\Type\ObjectType;

class DateIntervalDynamicReturnTypeExtension implements DynamicStaticMethodReturnTypeExtension
{
public function getClass(): string
{
return DateInterval::class;
}

public function isStaticMethodSupported(MethodReflection $methodReflection): bool
{
return $methodReflection->getName() === 'createFromDateString';
}

public function getTypeFromStaticMethodCall( MethodReflection $methodReflection, StaticCall $methodCall, Scope $scope ): ?\PHPStan\Type\Type
{
$defaultReturnType = ParametersAcceptorSelector::selectFromArgs(
$scope,
$methodCall->getArgs(),
$methodReflection->getVariants(),
)->getReturnType();

$dateTimeString = $scope->getType($methodCall->getArgs()[0]->value);

if (!($dateTimeString instanceof ConstantStringType)) {
return $defaultReturnType;
}

$isValid = DateInterval::createFromDateString($dateTimeString->getValue()) !== false;

return $isValid ? new ObjectType(DateInterval::class) : new ConstantBooleanType(false);
}
}

0 comments on commit 7b4b767

Please sign in to comment.