Skip to content

Commit a539007

Browse files
committed
qa: remove purity of provided callbacks
It is almost impossible to ensure purity and in some cases that also makes no sense. Especially when it comes to mappings, purity is impossible and therefore, dropping this in a bugfix release might suffice. Signed-off-by: Maximilian Bösing <[email protected]>
1 parent 34c5f65 commit a539007

File tree

8 files changed

+163
-48
lines changed

8 files changed

+163
-48
lines changed

src/ArrayInterface.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ public function isEmpty(): bool;
5151
/**
5252
* Tests if all elements satisfy the given predicate.
5353
*
54-
* @psalm-param pure-callable(TValue):bool $callback
54+
* @psalm-param callable(TValue):bool $callback
5555
*/
5656
public function allSatisfy(callable $callback): bool;
5757

5858
/**
5959
* Tests for the existence of an element that satisfies the given predicate.
6060
*
61-
* @psalm-param pure-callable(TValue):bool $callback
61+
* @psalm-param callable(TValue):bool $callback
6262
*/
6363
public function exists(callable $callback): bool;
6464

@@ -71,8 +71,8 @@ public function count(): int;
7171

7272
/**
7373
* @template TReducedValue
74-
* @param pure-callable(TReducedValue,TValue):TReducedValue $callback
75-
* @param TReducedValue $initial
74+
* @param callable(TReducedValue,TValue):TReducedValue $callback
75+
* @param TReducedValue $initial
7676
* @return TReducedValue
7777
*/
7878
public function reduce(callable $callback, $initial);

src/Array_.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ protected function valueComparator(): callable
107107
public function allSatisfy(callable $callback): bool
108108
{
109109
foreach ($this->data as $value) {
110+
/**
111+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
112+
* value here.
113+
*/
110114
if (! $callback($value)) {
111115
return false;
112116
}
@@ -118,6 +122,10 @@ public function allSatisfy(callable $callback): bool
118122
public function exists(callable $callback): bool
119123
{
120124
foreach ($this->data as $value) {
125+
/**
126+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
127+
* value here.
128+
*/
121129
if ($callback($value)) {
122130
return true;
123131
}
@@ -131,7 +139,11 @@ public function reduce(callable $callback, $initial)
131139
{
132140
$instance = clone $this;
133141

134-
/** @psalm-suppress MixedReturnStatement The return value of the callback ensures the return type. */
142+
/**
143+
* @psalm-suppress MixedReturnStatement The return value of the callback ensures the return type.
144+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
145+
* value here.
146+
*/
135147
return array_reduce($instance->data, $callback, $initial);
136148
}
137149
}

src/Map.php

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ public function sort(?callable $callback = null): MapInterface
7070
return $instance;
7171
}
7272

73+
/**
74+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
75+
* value here.
76+
*/
7377
uasort($data, $callback);
7478
$instance->data = $data;
7579

@@ -84,10 +88,14 @@ public function diffKeys(MapInterface $other, ?callable $keyComparator = null):
8488

8589
/**
8690
* @psalm-var array<TKey,TValue> $diff1
91+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
92+
* value here.
8793
*/
8894
$diff1 = array_diff_ukey($instance->data, $otherData, $keyComparator);
8995
/**
9096
* @psalm-var array<TKey,TValue> $diff2
97+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
98+
* value here.
9199
*/
92100
$diff2 = array_diff_ukey($otherData, $instance->data, $keyComparator);
93101
$merged = array_merge(
@@ -101,7 +109,7 @@ public function diffKeys(MapInterface $other, ?callable $keyComparator = null):
101109
}
102110

103111
/**
104-
* @psalm-return pure-callable(TKey,TKey):int
112+
* @psalm-return callable(TKey,TKey):int
105113
*/
106114
private function keyComparator(): callable
107115
{
@@ -118,6 +126,10 @@ public function toOrderedList(?callable $sorter = null): OrderedListInterface
118126

119127
$data = $this->data;
120128

129+
/**
130+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
131+
* value here.
132+
*/
121133
usort($data, $sorter);
122134

123135
return new GenericOrderedList($data);
@@ -128,6 +140,10 @@ public function filter(callable $callback): MapInterface
128140
$instance = clone $this;
129141
$filtered = [];
130142
foreach ($instance->data as $key => $value) {
143+
/**
144+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
145+
* value here.
146+
*/
131147
if (! $callback($value, $key)) {
132148
continue;
133149
}
@@ -179,8 +195,8 @@ public function intersect(MapInterface $other, ?callable $valueComparator = null
179195

180196
/**
181197
* @psalm-param MapInterface<TKey,TValue> $other
182-
* @psalm-param (pure-callable(TValue,TValue):int)|null $valueComparator
183-
* @psalm-param (pure-callable(TKey,TKey):int)|null $keyComparator
198+
* @psalm-param (callable(TValue,TValue):int)|null $valueComparator
199+
* @psalm-param (callable(TKey,TKey):int)|null $keyComparator
184200
* @psalm-return array<TKey,TValue>
185201
* @phpcsSuppress SlevomatCodingStandard.Classes.UnusedPrivateElements.UnusedMethod
186202
*/
@@ -189,6 +205,8 @@ private function intersection(MapInterface $other, ?callable $valueComparator, ?
189205
if ($valueComparator && $keyComparator) {
190206
/**
191207
* @psalm-var array<TKey,TValue> $intersection
208+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
209+
* value here.
192210
*/
193211
$intersection = array_uintersect_uassoc(
194212
$this->data,
@@ -203,6 +221,8 @@ private function intersection(MapInterface $other, ?callable $valueComparator, ?
203221
if ($keyComparator) {
204222
/**
205223
* @psalm-var array<TKey,TValue> $intersection
224+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
225+
* value here.
206226
*/
207227
$intersection = array_intersect_ukey($this->data, $other->toNativeArray(), $keyComparator);
208228

@@ -215,6 +235,8 @@ private function intersection(MapInterface $other, ?callable $valueComparator, ?
215235

216236
/**
217237
* @psalm-var array<TKey,TValue> $intersection
238+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
239+
* value here.
218240
*/
219241
$intersection = array_uintersect($this->data, $other->toNativeArray(), $valueComparator);
220242

@@ -252,6 +274,8 @@ public function diff(MapInterface $other, ?callable $valueComparator = null): Ma
252274
{
253275
/**
254276
* @psalm-var array<TKey,TValue> $diff1
277+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
278+
* value here.
255279
*/
256280
$diff1 = array_udiff(
257281
$this->toNativeArray(),
@@ -261,6 +285,8 @@ public function diff(MapInterface $other, ?callable $valueComparator = null): Ma
261285

262286
/**
263287
* @psalm-var array<TKey,TValue> $diff2
288+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
289+
* value here.
264290
*/
265291
$diff2 = array_udiff(
266292
$other->toNativeArray(),
@@ -303,13 +329,17 @@ public function removeElement($element): MapInterface
303329

304330
/**
305331
* @template TNewValue
306-
* @psalm-param pure-callable(TValue,TKey):TNewValue $callback
332+
* @psalm-param callable(TValue,TKey):TNewValue $callback
307333
* @psalm-return MapInterface<TKey,TNewValue>
308334
*/
309335
public function map(callable $callback): MapInterface
310336
{
311337
$data = [];
312338
foreach ($this->data as $key => $value) {
339+
/**
340+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
341+
* value here.
342+
*/
313343
$data[$key] = $callback($value, $key);
314344
}
315345

@@ -326,6 +356,10 @@ public function partition(callable $callback): array
326356
$filtered = $unfiltered = [];
327357

328358
foreach ($this->data as $key => $element) {
359+
/**
360+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
361+
* value here.
362+
*/
329363
if ($callback($element)) {
330364
$filtered[$key] = $element;
331365
continue;
@@ -344,7 +378,7 @@ public function partition(callable $callback): array
344378

345379
/**
346380
* @template TGroup of non-empty-string
347-
* @psalm-param pure-callable(TValue):TGroup $callback
381+
* @psalm-param callable(TValue):TGroup $callback
348382
*
349383
* @psalm-return MapInterface<TGroup,MapInterface<TKey,TValue>>
350384
*/
@@ -356,6 +390,10 @@ public function group(callable $callback): MapInterface
356390
$groups = new GenericMap([]);
357391

358392
foreach ($this->data as $key => $value) {
393+
/**
394+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
395+
* value here.
396+
*/
359397
$groupIdentifier = $callback($value);
360398
try {
361399
$group = $groups->get($groupIdentifier);
@@ -411,6 +449,10 @@ public function sortByKey(?callable $sorter = null): MapInterface
411449
$sorter = $sorter ?? $this->keyComparator();
412450
$data = $this->data;
413451
$instance = clone $this;
452+
/**
453+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
454+
* value here.
455+
*/
414456
uksort($data, $sorter);
415457
$instance->data = $data;
416458

@@ -429,7 +471,7 @@ public function join(string $separator = ''): string
429471

430472
/**
431473
* @template TNewKey of string
432-
* @param pure-callable(TKey,TValue):TNewKey $keyGenerator
474+
* @param callable(TKey,TValue):TNewKey $keyGenerator
433475
*
434476
* @return MapInterface<TNewKey,TValue>
435477
* @throws RuntimeException if a new key is being generated more than once.
@@ -440,6 +482,10 @@ public function keyExchange(callable $keyGenerator): MapInterface
440482
$exchanged = new GenericMap();
441483

442484
foreach ($this->data as $key => $value) {
485+
/**
486+
* @psalm-suppress ImpureFunctionCall Upstream projects have to ensure that they do not manipulate the
487+
* value here.
488+
*/
443489
$newKey = $keyGenerator($key, $value);
444490
if ($exchanged->has($newKey)) {
445491
throw new RuntimeException(sprintf(

src/MapInterface.php

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ interface MapInterface extends ArrayInterface, JsonSerializable
2020
* Filters out all values not matched by the callback.
2121
* This method is the equivalent of `array_filter`.
2222
*
23-
* @psalm-param pure-callable(TValue,TKey):bool $callback
23+
* @psalm-param callable(TValue,TKey):bool $callback
2424
* @psalm-return MapInterface<TKey,TValue>
2525
*/
2626
public function filter(callable $callback): MapInterface;
@@ -29,7 +29,7 @@ public function filter(callable $callback): MapInterface;
2929
* Sorts the items by using either the given callback or the native `SORT_NATURAL` logic of PHP.
3030
* This method is the equivalent of `sort`/`usort`.
3131
*
32-
* @psalm-param (pure-callable(TValue,TValue):int)|null $callback
32+
* @psalm-param (callable(TValue,TValue):int)|null $callback
3333
* @psalm-return MapInterface<TKey,TValue>
3434
*/
3535
public function sort(?callable $callback = null): MapInterface;
@@ -51,7 +51,7 @@ public function merge(MapInterface ...$stack): MapInterface;
5151
* This method is the equivalent of `array_diff`.
5252
*
5353
* @psalm-param MapInterface<TKey,TValue> $other
54-
* @psalm-param (pure-callable(TKey,TKey):int)|null $keyComparator
54+
* @psalm-param (callable(TKey,TKey):int)|null $keyComparator
5555
* @psalm-return MapInterface<TKey,TValue>
5656
*/
5757
public function diffKeys(MapInterface $other, ?callable $keyComparator = null): MapInterface;
@@ -61,7 +61,7 @@ public function diffKeys(MapInterface $other, ?callable $keyComparator = null):
6161
* This method is the equivalent of `array_map`.
6262
*
6363
* @template TNewValue
64-
* @psalm-param pure-callable(TValue,TKey):TNewValue $callback
64+
* @psalm-param callable(TValue,TKey):TNewValue $callback
6565
* @psalm-return MapInterface<TKey,TNewValue>
6666
*/
6767
public function map(callable $callback): MapInterface;
@@ -74,7 +74,7 @@ public function map(callable $callback): MapInterface;
7474
* This method is the equivalent of `array_intersect`.
7575
*
7676
* @psalm-param MapInterface<TKey,TValue> $other
77-
* @psalm-param (pure-callable(TValue,TValue):int)|null $valueComparator
77+
* @psalm-param (callable(TValue,TValue):int)|null $valueComparator
7878
* @psalm-return MapInterface<TKey,TValue>
7979
*/
8080
public function intersect(MapInterface $other, ?callable $valueComparator = null): MapInterface;
@@ -87,7 +87,7 @@ public function intersect(MapInterface $other, ?callable $valueComparator = null
8787
* This method is the equivalent of `array_diff`.
8888
*
8989
* @psalm-param MapInterface<TKey,TValue> $other
90-
* @psalm-param (pure-callable(TValue,TValue):int)|null $valueComparator
90+
* @psalm-param (callable(TValue,TValue):int)|null $valueComparator
9191
* @psalm-return MapInterface<TKey,TValue>
9292
*/
9393
public function diff(MapInterface $other, ?callable $valueComparator = null): MapInterface;
@@ -97,7 +97,7 @@ public function diff(MapInterface $other, ?callable $valueComparator = null): Ma
9797
* The items are being sorted by using the provided sorter. In case there is no sorter provided, the values
9898
* are just passed in the order they werestored in this map.
9999
*
100-
* @psalm-param (pure-callable(TValue,TValue):int)|null $sorter
100+
* @psalm-param (callable(TValue,TValue):int)|null $sorter
101101
* @psalm-return OrderedListInterface<TValue>
102102
*/
103103
public function toOrderedList(?callable $sorter = null): OrderedListInterface;
@@ -163,7 +163,7 @@ public function get(string $key);
163163
*
164164
* @psalm-param MapInterface<TKey,TValue> $other
165165
* @psalm-return MapInterface<TKey,TValue>
166-
* @psalm-param (pure-callable(TValue,TValue):int)|null $valueComparator
166+
* @psalm-param (callable(TValue,TValue):int)|null $valueComparator
167167
*/
168168
public function intersectAssoc(MapInterface $other, ?callable $valueComparator = null): MapInterface;
169169

@@ -174,7 +174,7 @@ public function intersectAssoc(MapInterface $other, ?callable $valueComparator =
174174
*
175175
* @psalm-param MapInterface<TKey,TValue> $other
176176
* @psalm-return MapInterface<TKey,TValue>
177-
* @psalm-param (pure-callable(TKey,TKey):int)|null $keyComparator
177+
* @psalm-param (callable(TKey,TKey):int)|null $keyComparator
178178
*/
179179
public function intersectUsingKeys(MapInterface $other, ?callable $keyComparator = null): MapInterface;
180180

@@ -186,8 +186,8 @@ public function intersectUsingKeys(MapInterface $other, ?callable $keyComparator
186186
* This method is the equivalent of `array_intersect_assoc`/`array_intersect_uassoc`/`array_intersect_key`/`array_intersect_ukey`.
187187
*
188188
* @psalm-param MapInterface<TKey,TValue> $other
189-
* @psalm-param (pure-callable(TValue,TValue):int)|null $valueComparator
190-
* @psalm-param (pure-callable(TKey,TKey):int)|null $keyComparator
189+
* @psalm-param (callable(TValue,TValue):int)|null $valueComparator
190+
* @psalm-param (callable(TKey,TKey):int)|null $keyComparator
191191
* @psalm-return MapInterface<TKey,TValue>
192192
*/
193193
public function intersectUserAssoc(
@@ -207,7 +207,7 @@ public function has(string $key): bool;
207207
/**
208208
* Partitions the current map into those items which are filtered by the callback and those which don't.
209209
*
210-
* @psalm-param pure-callable(TValue):bool $callback
210+
* @psalm-param callable(TValue):bool $callback
211211
* @psalm-return array{0:MapInterface<TKey,TValue>,1:MapInterface<TKey,TValue>}
212212
*/
213213
public function partition(callable $callback): array;
@@ -216,7 +216,7 @@ public function partition(callable $callback): array;
216216
* Groups the items of this object by using the callback.
217217
*
218218
* @template TGroup of non-empty-string
219-
* @psalm-param pure-callable(TValue):TGroup $callback
219+
* @psalm-param callable(TValue):TGroup $callback
220220
*
221221
* @psalm-return MapInterface<TGroup,MapInterface<TKey,TValue>>
222222
*/
@@ -235,15 +235,15 @@ public function slice(int $length): MapInterface;
235235
* After the method has been executed properly, an `MappedErrorCollection` is being thrown so one can
236236
* see what item key actually failed executing the callback.
237237
*
238-
* @param pure-callable(TValue,TKey):void $callback
238+
* @param callable(TValue,TKey):void $callback
239239
* @throws MappedErrorCollection If an error occured during execution.
240240
*/
241241
public function forAll(callable $callback): ForAllPromiseInterface;
242242

243243
/**
244244
* Sorts the map by sorting its keys.
245245
*
246-
* @param (pure-callable(TKey,TKey):int)|null $sorter
246+
* @param (callable(TKey,TKey):int)|null $sorter
247247
*
248248
* @psalm-return MapInterface<TKey,TValue>
249249
*/
@@ -261,7 +261,7 @@ public function join(string $separator = ''): string;
261261
* Creates a new map where the keys of items might have been exchanged with another key.
262262
*
263263
* @template TNewKey of string
264-
* @param pure-callable(TKey,TValue):TNewKey $keyGenerator
264+
* @param callable(TKey,TValue):TNewKey $keyGenerator
265265
*
266266
* @return MapInterface<TNewKey,TValue>
267267
* @throws RuntimeException if a new key is being generated more than once.

0 commit comments

Comments
 (0)