-
Notifications
You must be signed in to change notification settings - Fork 653
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add dateTimeModify return type provider
- Loading branch information
1 parent
95bb71f
commit 32aedba
Showing
4 changed files
with
160 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
src/Psalm/Internal/Provider/ReturnTypeProvider/DateTimeModifyReturnTypeProvider.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?php | ||
|
||
namespace Psalm\Internal\Provider\ReturnTypeProvider; | ||
|
||
use Psalm\Internal\Analyzer\StatementsAnalyzer; | ||
use Psalm\Plugin\EventHandler\Event\MethodReturnTypeProviderEvent; | ||
use Psalm\Plugin\EventHandler\MethodReturnTypeProviderInterface; | ||
use Psalm\Type; | ||
use Psalm\Type\Atomic\TLiteralString; | ||
use Psalm\Type\Union; | ||
|
||
class DateTimeModifyReturnTypeProvider implements MethodReturnTypeProviderInterface | ||
{ | ||
public static function getClassLikeNames(): array | ||
{ | ||
return ['DateTime', 'DateTimeImmutable']; | ||
} | ||
|
||
public static function getMethodReturnType(MethodReturnTypeProviderEvent $event): ?Union | ||
{ | ||
$statements_source = $event->getSource(); | ||
$call_args = $event->getCallArgs(); | ||
$method_name_lowercase = $event->getMethodNameLowercase(); | ||
if ( | ||
!$statements_source instanceof StatementsAnalyzer | ||
|| $method_name_lowercase !== 'modify' | ||
|| !isset($call_args[0]) | ||
) { | ||
return null; | ||
} | ||
|
||
$first_arg = $call_args[0]->value; | ||
$first_arg_type = $statements_source->node_data->getType($first_arg); | ||
if (!$first_arg_type) { | ||
return null; | ||
} | ||
|
||
$has_date_time = false; | ||
$has_false = false; | ||
foreach ($first_arg_type->getAtomicTypes() as $type_part) { | ||
if (!$type_part instanceof TLiteralString) { | ||
return null; | ||
} | ||
|
||
if (@(new \DateTime())->modify($type_part->value) === false) { | ||
$has_false = true; | ||
} else { | ||
$has_date_time = true; | ||
} | ||
} | ||
|
||
if ($has_false && !$has_date_time) { | ||
return Type::getFalse(); | ||
} | ||
if ($has_date_time && !$has_false) { | ||
return Type::parseString($event->getFqClasslikeName()); | ||
} | ||
|
||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<?php | ||
|
||
namespace Psalm\Tests; | ||
|
||
use Psalm\Tests\Traits\ValidCodeAnalysisTestTrait; | ||
|
||
class DateTimeTest extends TestCase | ||
{ | ||
use ValidCodeAnalysisTestTrait; | ||
|
||
/** | ||
* @return iterable<string,array{string,assertions?:array<string,string>,error_levels?:string[]}> | ||
*/ | ||
public function providerValidCodeParse(): iterable | ||
{ | ||
return [ | ||
'modify' => [ | ||
'<?php | ||
function getString(): string | ||
{ | ||
return ""; | ||
} | ||
$datetime = new DateTime(); | ||
$dateTimeImmutable = new DateTimeImmutable(); | ||
$a = $datetime->modify(getString()); | ||
$b = $dateTimeImmutable->modify(getString()); | ||
', | ||
'assertions' => [ | ||
'$a' => 'DateTime|false', | ||
'$b' => 'DateTimeImmutable|false', | ||
], | ||
], | ||
'modifyWithValidConstant' => [ | ||
'<?php | ||
/** | ||
* @return "+1 day"|"+2 day" | ||
*/ | ||
function getString(): string | ||
{ | ||
return "+1 day"; | ||
} | ||
$datetime = new DateTime(); | ||
$dateTimeImmutable = new DateTimeImmutable(); | ||
$a = $datetime->modify(getString()); | ||
$b = $dateTimeImmutable->modify(getString()); | ||
', | ||
'assertions' => [ | ||
'$a' => 'DateTime', | ||
'$b' => 'DateTimeImmutable', | ||
], | ||
], | ||
'modifyWithInvalidConstant' => [ | ||
'<?php | ||
/** | ||
* @return "foo"|"bar" | ||
*/ | ||
function getString(): string | ||
{ | ||
return "foo"; | ||
} | ||
$datetime = new DateTime(); | ||
$dateTimeImmutable = new DateTimeImmutable(); | ||
$a = $datetime->modify(getString()); | ||
$b = $dateTimeImmutable->modify(getString()); | ||
', | ||
'assertions' => [ | ||
'$a' => 'false', | ||
'$b' => 'false', | ||
], | ||
], | ||
'modifyWithBothConstant' => [ | ||
'<?php | ||
/** | ||
* @return "+1 day"|"bar" | ||
*/ | ||
function getString(): string | ||
{ | ||
return "+1 day"; | ||
} | ||
$datetime = new DateTime(); | ||
$dateTimeImmutable = new DateTimeImmutable(); | ||
$a = $datetime->modify(getString()); | ||
$b = $dateTimeImmutable->modify(getString()); | ||
', | ||
'assertions' => [ | ||
'$a' => 'DateTime|false', | ||
'$b' => 'DateTimeImmutable|false', | ||
], | ||
], | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters