Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 813296e

Browse files
Merge remote-tracking branch 'origin/1.5.x' into 2.0.x
2 parents f36d43f + 4e9c77f commit 813296e

File tree

8 files changed

+236
-1
lines changed

8 files changed

+236
-1
lines changed

‎extension.neon‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ parameters:
3232
- stubs/Persistence/ObjectRepository.stub
3333
- stubs/RepositoryFactory.stub
3434
- stubs/Collections/ArrayCollection.stub
35-
- stubs/Collections/ReadableCollection.stub
3635
- stubs/Collections/Selectable.stub
3736
- stubs/ORM/AbstractQuery.stub
3837
- stubs/ORM/Exception/ORMException.stub

‎src/Stubs/Doctrine/StubFilesExtensionLoader.php‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@ public function getFiles(): array
6363
$collectionVersion = null;
6464
}
6565
if ($collectionVersion !== null && strpos($collectionVersion, '1.') === 0) {
66+
$files[] = $stubsDir . '/Collections/ReadableCollection1.stub';
6667
$files[] = $stubsDir . '/Collections/Collection1.stub';
6768
} else {
69+
$files[] = $stubsDir . '/Collections/ReadableCollection.stub';
6870
$files[] = $stubsDir . '/Collections/Collection.stub';
6971
}
7072

‎stubs/Collections/ArrayCollection.stub‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Doctrine\Common\Collections;
44

5+
use Closure;
6+
57
/**
68
* @template TKey of array-key
79
* @template T
@@ -11,4 +13,33 @@ namespace Doctrine\Common\Collections;
1113
class ArrayCollection implements Collection, Selectable
1214
{
1315

16+
/**
17+
* @param-immediately-invoked-callable $p
18+
*
19+
* @param Closure(T, TKey):bool $p
20+
*
21+
* @return static<TKey, T>
22+
*/
23+
public function filter(Closure $p);
24+
25+
/**
26+
* @param-immediately-invoked-callable $func
27+
*
28+
* @param Closure(T):U $func
29+
*
30+
* @return static<TKey, U>
31+
*
32+
* @template U
33+
*/
34+
public function map(Closure $func);
35+
36+
/**
37+
* @param-immediately-invoked-callable $p
38+
*
39+
* @param Closure(TKey, T):bool $p
40+
*
41+
* @return array{0: static<TKey, T>, 1: static<TKey, T>}
42+
*/
43+
public function partition(Closure $p);
44+
1445
}

‎stubs/Collections/Collection.stub‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Doctrine\Common\Collections;
44

55
use ArrayAccess;
6+
use Closure;
67
use Countable;
78
use IteratorAggregate;
89

@@ -43,4 +44,33 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess, Readable
4344
*/
4445
public function removeElement($element) {}
4546

47+
/**
48+
* @param-immediately-invoked-callable $p
49+
*
50+
* @param Closure(T, TKey):bool $p
51+
*
52+
* @return Collection<TKey, T>
53+
*/
54+
public function filter(Closure $p);
55+
56+
/**
57+
* @param-immediately-invoked-callable $func
58+
*
59+
* @param Closure(T):U $func
60+
*
61+
* @return Collection<TKey, U>
62+
*
63+
* @template U
64+
*/
65+
public function map(Closure $func);
66+
67+
/**
68+
* @param-immediately-invoked-callable $p
69+
*
70+
* @param Closure(TKey, T):bool $p
71+
*
72+
* @return array{0: Collection<TKey, T>, 1: Collection<TKey, T>}
73+
*/
74+
public function partition(Closure $p);
75+
4676
}

‎stubs/Collections/Collection1.stub‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Doctrine\Common\Collections;
44

55
use ArrayAccess;
6+
use Closure;
67
use Countable;
78
use IteratorAggregate;
89

@@ -43,4 +44,33 @@ interface Collection extends Countable, IteratorAggregate, ArrayAccess, Readable
4344
*/
4445
public function removeElement($element) {}
4546

47+
/**
48+
* @param-immediately-invoked-callable $p
49+
*
50+
* @param Closure(T, TKey):bool $p
51+
*
52+
* @return Collection<TKey, T>
53+
*/
54+
public function filter(Closure $p);
55+
56+
/**
57+
* @param-immediately-invoked-callable $func
58+
*
59+
* @param Closure(T):U $func
60+
*
61+
* @return Collection<TKey, U>
62+
*
63+
* @template U
64+
*/
65+
public function map(Closure $func);
66+
67+
/**
68+
* @param-immediately-invoked-callable $p
69+
*
70+
* @param Closure(TKey, T):bool $p
71+
*
72+
* @return array{0: Collection<TKey, T>, 1: Collection<TKey, T>}
73+
*/
74+
public function partition(Closure $p);
75+
4676
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
namespace Doctrine\Common\Collections;
4+
5+
use Closure;
6+
use Countable;
7+
use IteratorAggregate;
8+
9+
/**
10+
* @template TKey of array-key
11+
* @template-covariant T
12+
* @extends IteratorAggregate<TKey, T>
13+
*/
14+
interface ReadableCollection extends Countable, IteratorAggregate
15+
{
16+
17+
/**
18+
* @param-immediately-invoked-callable $p
19+
*
20+
* @param Closure(TKey, T):bool $p
21+
*
22+
* @return bool
23+
*/
24+
public function exists(Closure $p);
25+
26+
/**
27+
* @param-immediately-invoked-callable $p
28+
*
29+
* @param Closure(T, TKey):bool $p
30+
*
31+
* @return ReadableCollection<TKey, T>
32+
*/
33+
public function filter(Closure $p);
34+
35+
/**
36+
* @param-immediately-invoked-callable $func
37+
*
38+
* @param Closure(T):U $func
39+
*
40+
* @return Collection<TKey, U>
41+
*
42+
* @template U
43+
*/
44+
public function map(Closure $func);
45+
46+
/**
47+
* @param-immediately-invoked-callable $p
48+
*
49+
* @param Closure(TKey, T):bool $p
50+
*
51+
* @return array{0: ReadableCollection<TKey, T>, 1: ReadableCollection<TKey, T>}
52+
*/
53+
public function partition(Closure $p);
54+
55+
/**
56+
* @param-immediately-invoked-callable $p
57+
*
58+
* @param Closure(TKey, T):bool $p
59+
*
60+
* @return bool TRUE, if the predicate yields TRUE for all elements, FALSE otherwise.
61+
*/
62+
public function forAll(Closure $p);
63+
64+
/**
65+
* @param-immediately-invoked-callable $p
66+
*
67+
* @param Closure(TKey, T):bool $p
68+
*
69+
* @return T|null
70+
*/
71+
public function findFirst(Closure $p);
72+
73+
/**
74+
* @param-immediately-invoked-callable $func
75+
*
76+
* @param Closure(TReturn|TInitial, T):TReturn $func
77+
* @param TInitial $initial
78+
*
79+
* @return TReturn|TInitial
80+
*
81+
* @template TReturn
82+
* @template TInitial
83+
*/
84+
public function reduce(Closure $func, mixed $initial = null);
85+
86+
}

‎tests/DoctrineIntegration/TypeInferenceTest.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public function dataFileAsserts(): iterable
1414
{
1515
yield from $this->gatherAssertTypes(__DIR__ . '/data/getRepository.php');
1616
yield from $this->gatherAssertTypes(__DIR__ . '/data/isEmpty.php');
17+
yield from $this->gatherAssertTypes(__DIR__ . '/data/Collection.php');
1718
}
1819

1920
/**
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace Bug621;
4+
5+
use Doctrine\Common\Collections\ArrayCollection;
6+
use Doctrine\Common\Collections\Collection;
7+
use function PHPStan\Testing\assertType;
8+
9+
class Foo
10+
{
11+
12+
/** @var Collection<int, Item> */
13+
private $items;
14+
15+
public function __construct()
16+
{
17+
/** @var ArrayCollection<int, int> $numbers */
18+
$numbers = new ArrayCollection([1, 2, 3]);
19+
20+
$filteredNumbers = $numbers->filter(function (int $number): bool {
21+
return $number % 2 === 1;
22+
});
23+
assertType('Doctrine\Common\Collections\ArrayCollection<int, int>', $filteredNumbers);
24+
25+
$items = $filteredNumbers->map(static function (int $number): Item {
26+
return new Item();
27+
});
28+
assertType('Doctrine\Common\Collections\ArrayCollection<int, Bug621\Item>', $items);
29+
30+
$this->items = $items;
31+
}
32+
33+
public function removeOdd(): void
34+
{
35+
$this->items = $this->items->filter(function (Item $item, int $idx): bool {
36+
return $idx % 2 === 1;
37+
});
38+
assertType('Doctrine\Common\Collections\Collection<int, Bug621\Item>', $this->items);
39+
}
40+
41+
public function __clone()
42+
{
43+
$this->items = $this->items->map(
44+
static function (Item $item): Item {
45+
return clone $item;
46+
}
47+
);
48+
assertType('Doctrine\Common\Collections\Collection<int, Bug621\Item>', $this->items);
49+
}
50+
51+
}
52+
53+
class Item
54+
{
55+
56+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /