Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DatePeriod::getEndDate can be null #5953

Closed
Alban-io opened this issue Nov 8, 2021 · 6 comments · Fixed by phpstan/phpstan-src#958
Closed

DatePeriod::getEndDate can be null #5953

Alban-io opened this issue Nov 8, 2021 · 6 comments · Fixed by phpstan/phpstan-src#958

Comments

@Alban-io
Copy link

Alban-io commented Nov 8, 2021

Bug report

Code snippet that reproduces the problem

https://phpstan.org/r/1f444637-6319-49d9-be32-fcabb3f7c84e

Expected output

17    Cannot call method format() on DateTimeInterface|null.

DatePeriod::getEndDate return DateTimeInterface when __construct has for 3rd argument a DateTimeInterface.

'DatePeriod::__construct' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'recur'=>'int', 'options='=>'int'],
'DatePeriod::__construct\'1' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'end'=>'DateTimeInterface', 'options='=>'int'],
'DatePeriod::__construct\'2' => ['void', 'iso'=>'string', 'options='=>'int'],

PHP doc : public DatePeriod::getEndDate(): ?DateTimeInterface
PHPStan : 'DatePeriod::getEndDate' => ['DateTimeInterface'],

<?php declare(strict_types=1);

$start = new DateTime('2012-07-01');
$interval = new DateInterval('P7D');
$end = new DateTime('2012-07-31');
$recurrences = 4;
$iso = 'R4/2012-07-01T00:00:00Z/P7D';

var_dump([
    (new DatePeriod($start, $interval, $recurrences))->getEndDate(), // null
    (new DatePeriod($start, $interval, $end))->getEndDate(),         // DateTime
    (new DatePeriod($iso))->getEndDate(),                            // null
]);

Did PHPStan help you today? Did it make you happy in any way?

PHPStan is one of the best things that happened in PHP ❤️
Thank Ondřej & contributors 👏

@herndlm
Copy link
Contributor

herndlm commented Nov 8, 2021

This looks like a perfect first contribution - do you want to fix it yourself? :)

@Alban-io
Copy link
Author

Alban-io commented Nov 8, 2021

do you want to fix it yourself? :)

It depends on the desired fix :

  • make the return type nullable DatePeriod::getEndDate' => ['?DateTimeInterface']
  • make the return type variable based on the constructor call

To implement the second I will need a similar case in the codebase 😉

@herndlm
Copy link
Contributor

herndlm commented Nov 9, 2021

Right, I did overlook that this is a bit more complex. And I'm still lacking phpstan internal knowledge, but maybe @staabm knows which kind of extension this needs?

@staabm
Copy link
Contributor

staabm commented Nov 9, 2021

usually you would need a DynamicMethodReturnTypeExtension extension - find other examples in the phpstan-src codebase

I am not 100% sure, but I guess in the extension you may check with getRecurrences what was passed in as 3rd construct arg

@Alban-io
Copy link
Author

Alban-io commented Nov 9, 2021

Thank @staabm I will try to make the PR

@github-actions
Copy link

github-actions bot commented Mar 3, 2022

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 3, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
3 participants