1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00

Add more standard iterators (#4320)

* Add CachingIterator, LimitIterator, InfiniteIterator, CallbackFilterIterator, NoRewindIterator.

Signed-off-by: Pol Dellaiera <pol.dellaiera@protonmail.com>

* Add related Iterator tests.

Signed-off-by: Pol Dellaiera <pol.dellaiera@protonmail.com>
This commit is contained in:
Pol Dellaiera 2020-10-13 17:35:49 +02:00 committed by Daniil Gentili
parent 399a7bfd11
commit 2b437ad672
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
2 changed files with 208 additions and 0 deletions

View File

@ -205,6 +205,134 @@ class FilterIterator extends IteratorIterator {
}
/**
* @template-covariant TKey
* @template-covariant TValue
*
* @template-implements OuterIterator<TKey, TValue>
* @template-implements ArrayAccess<TKey, TValue>
*
* @template-extends IteratorIterator<TKey, TValue>
*/
class CachingIterator extends IteratorIterator implements OuterIterator , ArrayAccess , Countable {
/**
* @param Iterator<TKey, TValue> $iterator
*/
public function __construct(Iterator $iterator) {}
/** @return bool */
public function hasNext () {}
/**
* @return TValue Can return any type.
*/
public function current() {}
/**
* @return TKey scalar on success, or null on failure.
*/
public function key() {}
}
/**
* @template-covariant TKey
* @template-covariant TValue
*
* @template-implements OuterIterator<TKey, TValue>
*
* @template-extends IteratorIterator<TKey, TValue>
*/
class InfiniteIterator extends IteratorIterator implements OuterIterator {
/**
* @param Iterator<TKey, TValue> $iterator
*/
public function __construct(Iterator $iterator) {}
/**
* @return TValue Can return any type.
*/
public function current() {}
/**
* @return TKey scalar on success, or null on failure.
*/
public function key() {}
}
/**
* @template-covariant TKey
* @template-covariant TValue
*
* @template-implements OuterIterator<TKey, TValue>
*
* @template-extends IteratorIterator<TKey, TValue>
*/
class LimitIterator extends IteratorIterator implements OuterIterator {
/**
* @param Iterator<TKey, TValue> $iterator
*/
public function __construct(Iterator $iterator, int $offset = 0, int $count = -1) {}
/**
* @return TValue Can return any type.
*/
public function current() {}
/**
* @return TKey scalar on success, or null on failure.
*/
public function key() {}
}
/**
* @template-covariant TKey
* @template-covariant TValue
*
* @template-implements OuterIterator<TKey, TValue>
*
* @template-extends FilterIterator<TKey, TValue>
*/
class CallbackFilterIterator extends FilterIterator implements OuterIterator {
/**
* @param Iterator<TKey, TValue> $iterator
* @param callable(TValue, TKey, Iterator<TKey, TValue>): bool $callback
*/
public function __construct(Iterator $iterator, callable $callback) {}
/**
* @return TValue Can return any type.
*/
public function current() {}
/**
* @return TKey scalar on success, or null on failure.
*/
public function key() {}
}
/**
* @template-covariant TKey
* @template-covariant TValue
*
* @template-extends IteratorIterator<TKey, TValue>
*/
class NoRewindIterator extends IteratorIterator {
/**
* @param Iterator<TKey, TValue> $iterator
*/
public function __construct(Iterator $iterator) {}
/**
* @return TValue Can return any type.
*/
public function current() {}
/**
* @return TKey scalar on success, or null on failure.
*/
public function key() {}
}
/**
* @template-covariant TKey
* @template-covariant TValue

View File

@ -16,6 +16,86 @@ class ClassTemplateTest extends TestCase
public function providerValidCodeParse(): iterable
{
return [
'cachingIterator' => [
'<?php
$input = range("a", "z");
$arrayIterator = new ArrayIterator($input);
$decoratorIterator = new CachingIterator($arrayIterator);
$next = $decoratorIterator->hasNext();
$key = $decoratorIterator->key();
$value = $decoratorIterator->current();
',
'assertions' => [
'$key' => 'int',
'$value' => 'string',
'$next' => 'bool',
],
],
'infiniteIterator' => [
'<?php
$input = range("a", "z");
$arrayIterator = new ArrayIterator($input);
$decoratorIterator = new InfiniteIterator($arrayIterator);
$key = $decoratorIterator->key();
$value = $decoratorIterator->current();
',
'assertions' => [
'$key' => 'int',
'$value' => 'string',
],
],
'limitIterator' => [
'<?php
$input = range("a", "z");
$arrayIterator = new ArrayIterator($input);
$decoratorIterator = new LimitIterator($arrayIterator, 1, 1);
$key = $decoratorIterator->key();
$value = $decoratorIterator->current();
',
'assertions' => [
'$key' => 'int',
'$value' => 'string',
],
],
'callbackFilterIterator' => [
'<?php
$input = range("a", "z");
$arrayIterator = new ArrayIterator($input);
$decoratorIterator = new CallbackFilterIterator(
$arrayIterator,
static function (string $value): bool {return "a" === $value;}
);
$key = $decoratorIterator->key();
$value = $decoratorIterator->current();
',
'assertions' => [
'$key' => 'int',
'$value' => 'string',
],
],
'noRewindIterator' => [
'<?php
$input = range("a", "z");
$arrayIterator = new ArrayIterator($input);
$decoratorIterator = new NoRewindIterator($arrayIterator);
$key = $decoratorIterator->key();
$value = $decoratorIterator->current();
',
'assertions' => [
'$key' => 'int',
'$value' => 'string',
],
],
'classTemplate' => [
'<?php
class A {}