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

Add stub for DatePeriod #8312

Merged
merged 3 commits into from Jul 25, 2022
Merged

Conversation

fluffycondor
Copy link
Contributor

Fixes #5954

Actually I'd like to mark the returned Iterator as a non-empty one, it always yields at least one value (and 50 and 63 lines in the test actually should be non-nullable).
But I don't know how to do that :)

@AndrolGenhald
Copy link
Collaborator

Actually I'd like to mark the returned Iterator as a non-empty one, it always yields at least one value (and 50 and 63 lines in the test actually should be non-nullable).

I don't think that's possible unfortunately, and the only way I can think of to do it would be to add a template, which would make all other iterators more annoying to deal with.

@AndrolGenhald
Copy link
Collaborator

Per this comment it looks like we might need to have it implement Traversable instead and add the IteratorAggregate part in Php80.phpstub. It would be good to add a test for PHP 7.4 and 8.0 for that as well.

@fluffycondor
Copy link
Contributor Author

it looks like we might need to have it implement Traversable instead and add the IteratorAggregate part in Php80.phpstub

Unfortunately, looks like I can't use a conditional @implements :(
It doesn't work whatever I try:
https://psalm.dev/r/f606edbe51
https://psalm.dev/r/46f7c9b9b4

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/f606edbe51
<?php
/**
 * @psalm-immutable
 *
 * @template-covariant Start of string|DateTimeInterface
 * @implements (Start is string ? Traversable<int, DateTime> : Traversable<int, Start>)
 */
class DatePeriod implements Traversable
{
    const EXCLUDE_START_DATE = 1;
    /**
     * @param Start $start
     * @param (Start is string ? 0|self::EXCLUDE_START_DATE : DateInterval) $interval
     * @param (Start is string ? never : DateTimeInterface|positive-int) $end
     * @param (Start is string ? never : 0|self::EXCLUDE_START_DATE) $options
     */
    public function __construct($start, $interval = 0, $end = 1, $options = 0) {}
}
Psalm output (using commit 4b2935f):

ERROR: InvalidDocblock - 8:1 - @template-implements has invalid class (Start is string ? Traversable<int, DateTime> : Traversable<int, Start:DatePeriod as DateTimeInterface|string>)

ERROR: MissingTemplateParam - 8:29 - DatePeriod has missing template params when extending Traversable, expecting 2

ERROR: InvalidTraversableImplementation - 8:7 - Traversable should be implemented by implementing IteratorAggregate or Iterator
https://psalm.dev/r/46f7c9b9b4
<?php
/**
 * @psalm-immutable
 *
 * @template-covariant Start of string|DateTimeInterface
 * @implements Traversable<int, (Start is string ? DateTime : Start)>
 */
class DatePeriod implements Traversable
{
    const EXCLUDE_START_DATE = 1;
    /**
     * @param Start $start
     * @param (Start is string ? 0|self::EXCLUDE_START_DATE : DateInterval) $interval
     * @param (Start is string ? never : DateTimeInterface|positive-int) $end
     * @param (Start is string ? never : 0|self::EXCLUDE_START_DATE) $options
     */
    public function __construct($start, $interval = 0, $end = 1, $options = 0) {}
}

$period = new DatePeriod("R4/2012-07-01T00:00:00Z/P7D");
foreach ($period as $dt) {
    echo $dt->format("Y-m-d");
}
Psalm output (using commit 4b2935f):

ERROR: InvalidMethodCall - 22:15 - Cannot call method on (Start is string ? DateTime : Start:DatePeriod as DateTimeInterface|string) variable $dt

INFO: MixedArgument - 22:10 - Argument 1 of echo cannot be mixed, expecting string

ERROR: InvalidTraversableImplementation - 8:7 - Traversable should be implemented by implementing IteratorAggregate or Iterator

@AndrolGenhald
Copy link
Collaborator

@fluffycondor It looks like you must have branched from your fork's 4.x branch, which is quite a bit behind. Could you rebase on the current 4.x? I think that should fix the test-with-real-projects PHPUnit test.

@AndrolGenhald AndrolGenhald added the release:fix The PR will be included in 'Fixes' section of the release notes label Jul 25, 2022
@AndrolGenhald AndrolGenhald merged commit 0b482ac into vimeo:4.x Jul 25, 2022
@AndrolGenhald
Copy link
Collaborator

Thanks!

fluffycondor added a commit to fluffycondor/psalm-1 that referenced this pull request Aug 19, 2022
I wrote them in a wrong way in vimeo#8312, so they are rewritten now as @AndrolGenhald advised in vimeo#8327
fluffycondor added a commit to fluffycondor/psalm-1 that referenced this pull request Aug 19, 2022
I wrote them in a wrong way in vimeo#8312, so they are rewritten now as @AndrolGenhald advised in vimeo#8327
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release:fix The PR will be included in 'Fixes' section of the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Iterating over \DatePeriod objects does not automatically yields \DateTimeInterface typed values
2 participants