Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion stubs/CoreImmutableClasses.phpstub
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ class DateTimeZone
* @psalm-immutable
*
* @template-covariant Start of string|DateTimeInterface
* @implements Traversable<int, DateTimeInterface>
* @template-covariant TDate of DateTimeInterface
* @implements Traversable<int, TDate>
*/
class DatePeriod implements Traversable
{
Expand All @@ -123,6 +124,8 @@ class DatePeriod implements Traversable
* @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
*
* @psalm-this-out self<Start, (Start is string ? DateTime : Start)>
*/
public function __construct($start, $interval = 0, $end = 1, $options = 0) {}
}
Expand Down
7 changes: 5 additions & 2 deletions stubs/Php80.phpstub
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ class UnhandledMatchError extends Error {}
* @psalm-immutable
*
* @template-covariant Start of string|DateTimeInterface
* @implements IteratorAggregate<int, DateTimeInterface>
* @template-covariant TDate of DateTimeInterface
* @implements IteratorAggregate<int, TDate>
*/
class DatePeriod implements IteratorAggregate
{
Expand All @@ -222,10 +223,12 @@ class DatePeriod implements IteratorAggregate
* @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
*
* @psalm-this-out self<Start, (Start is string ? DateTime : Start)>
*/
public function __construct($start, $interval = 0, $end = 1, $options = 0) {}

/** @psalm-return (Start is string ? Iterator<int, DateTime> : Iterator<int, Start>) */
/** @psalm-return Iterator<int, TDate> */
public function getIterator(): Iterator {}
}

Expand Down
7 changes: 5 additions & 2 deletions stubs/Php82.phpstub
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ namespace {
* @psalm-immutable
*
* @template-covariant Start of string|DateTimeInterface
* @implements IteratorAggregate<int, DateTimeInterface>
* @template-covariant TDate of DateTimeInterface
* @implements IteratorAggregate<int, TDate>
*/
class DatePeriod implements IteratorAggregate
{
Expand All @@ -27,10 +28,12 @@ namespace {
* @param (Start is string ? int-mask<self::EXCLUDE_START_DATE, self::INCLUDE_END_DATE> : DateInterval) $interval
* @param (Start is string ? never : (DateTimeInterface|positive-int)) $end
* @param (Start is string ? never : int-mask<self::EXCLUDE_START_DATE, self::INCLUDE_END_DATE>) $options
*
* @psalm-this-out self<Start, (Start is string ? DateTime : Start)>
*/
public function __construct($start, $interval = 0, $end = 1, $options = 0) {}

/** @psalm-return (Start is string ? Iterator<int, DateTime> : Iterator<int, Start>) */
/** @psalm-return Iterator<int, TDate> */
public function getIterator(): Iterator {}
}

Expand Down
66 changes: 62 additions & 4 deletions tests/CoreStubsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ public function providerValidCodeParse(): iterable
echo $dt->format("Y-m-d");
}',
'assertions' => [
'$period' => 'DatePeriod<DateTimeImmutable>',
'$dt' => 'DateTimeInterface|null',
'$period' => 'DatePeriod<DateTimeImmutable, DateTimeImmutable>',
'$dt' => 'DateTimeImmutable|null',
],
'ignored_issues' => [],
'php_version' => '7.3',
Expand All @@ -71,7 +71,7 @@ public function providerValidCodeParse(): iterable
echo $dt->format("Y-m-d");
}',
'assertions' => [
'$period' => 'DatePeriod<DateTimeImmutable>',
'$period' => 'DatePeriod<DateTimeImmutable, DateTimeImmutable>',
'$dt' => 'DateTimeImmutable|null',
],
'ignored_issues' => [],
Expand All @@ -86,7 +86,7 @@ public function providerValidCodeParse(): iterable
echo $dt->format("Y-m-d");
}',
'assertions' => [
'$period' => 'DatePeriod<string>',
'$period' => 'DatePeriod<string, DateTime>',
'$dt' => 'DateTime|null',
],
'ignored_issues' => [],
Expand All @@ -110,6 +110,64 @@ public function providerValidCodeParse(): iterable
'ignored_issues' => ['RedundantCondition'],
'php_version' => '8.0',
];
yield 'DatePeriod with TDate template param does not trigger TooManyTemplateParams' => [
'code' => '<?php

/** @param DatePeriod<DateTimeImmutable, DateTimeImmutable> $period */
function foo(DatePeriod $period): void {
foreach ($period as $dt) {
echo $dt->format("Y-m-d");
}
}',
'assertions' => [],
'ignored_issues' => [],
'php_version' => '8.2',
];
yield 'DatePeriod with DateTime start binds TDate to DateTime' => [
'code' => '<?php

$period = new DatePeriod(
new DateTime("now"),
DateInterval::createFromDateString("1 day"),
new DateTime("+1 week")
);
$dt = null;
foreach ($period as $dt) {
echo $dt->format("Y-m-d");
}',
'assertions' => [
'$period' => 'DatePeriod<DateTime, DateTime>',
'$dt' => 'DateTime|null',
],
'ignored_issues' => [],
'php_version' => '8.2',
];
yield 'DatePeriod getIterator returns correctly typed Iterator' => [
'code' => '<?php

$period = new DatePeriod(
new DateTimeImmutable("now"),
DateInterval::createFromDateString("1 day"),
new DateTimeImmutable("+1 week")
);
$iterator = $period->getIterator();',
'assertions' => [
'$iterator' => 'Iterator<int, DateTimeImmutable>',
],
'ignored_issues' => [],
'php_version' => '8.2',
];
yield 'DatePeriod getIterator with ISO string returns Iterator of DateTime' => [
'code' => '<?php

$period = new DatePeriod("R4/2012-07-01T00:00:00Z/P7D");
$iterator = $period->getIterator();',
'assertions' => [
'$iterator' => 'Iterator<int, DateTime>',
],
'ignored_issues' => [],
'php_version' => '8.2',
];
yield 'sprintf yields a non-empty-string for non-empty-string value' => [
'code' => '<?php

Expand Down
Loading