Skip to content

Commit 45ba7f4

Browse files
authored
Merge pull request #173 from boesing/bugfix/remove-purity
Remove purity of provided callbacks
2 parents 34c5f65 + a539007 commit 45ba7f4

8 files changed

+163
-48
lines changed

src/ArrayInterface.php

+4-4
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

+13-1
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

+52-6
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

+16-16
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)