Skip to content

Commit 3cdf16e

Browse files
committed
fixed static typing when working with transforming methods
1 parent 7a31b60 commit 3cdf16e

File tree

5 files changed

+121
-69
lines changed

5 files changed

+121
-69
lines changed

src/Types/AbstractCypherSequence.php

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,24 @@
2323
/**
2424
* Abstract immutable sequence with basic functional methods.
2525
*
26-
* @template TKey of array-key
2726
* @template TValue
27+
* @template TKey of array-key
2828
*
2929
* @extends AbstractCypherObject<TKey, TValue>
3030
*
3131
* @psalm-immutable
32+
*
33+
* @psalm-suppress UnsafeInstantiation
3234
*/
3335
abstract class AbstractCypherSequence extends AbstractCypherObject implements Countable
3436
{
3537
/** @var array<TKey, TValue> */
36-
protected array $sequence;
38+
protected array $sequence = [];
3739

3840
/**
39-
* Creates a new instance from the given iterable.
40-
*
41-
* @template Value
42-
*
43-
* @param iterable<Value> $iterable
44-
*
45-
* @return static
46-
*
47-
* @pure
41+
* @param iterable<TKey, TValue> $iterable
4842
*/
49-
abstract public static function fromIterable(iterable $iterable): self;
43+
abstract public function __construct(iterable $iterable);
5044

5145
final public function count(): int
5246
{
@@ -56,14 +50,14 @@ final public function count(): int
5650
/**
5751
* Copies the sequence.
5852
*
59-
* @return static
53+
* @return static<TValue, TKey>
6054
*/
6155
final public function copy(): self
6256
{
6357
// Make sure the sequence is actually copied by reassigning it.
6458
$map = $this->sequence;
6559

66-
return $this::fromIterable($map);
60+
return new static($map);
6761
}
6862

6963
/**
@@ -89,7 +83,7 @@ final public function toArray(): array
8983
*
9084
* @param iterable<array-key, TValue> $values
9185
*
92-
* @return static
86+
* @return static<TValue, TKey>
9387
*/
9488
abstract public function merge(iterable $values): self;
9589

@@ -116,48 +110,50 @@ final public function hasValue($value): bool
116110
/**
117111
* Creates a filtered the sequence with the provided callback.
118112
*
119-
* @param pure-callable(TValue, TKey):bool $callback
113+
* @param callable(TValue, TKey):bool $callback
120114
*
121-
* @return static
115+
* @return static<TValue, TKey>
122116
*/
123117
final public function filter(callable $callback): self
124118
{
119+
/** @var array<TKey, TValue> $tbr */
125120
$tbr = [];
126121
foreach ($this->sequence as $key => $value) {
127122
if ($callback($value, $key)) {
128123
$tbr[$key] = $value;
129124
}
130125
}
131126

132-
return $this::fromIterable($tbr);
127+
return new static($tbr);
133128
}
134129

135130
/**
136131
* Maps the values of this sequence to a new one with the provided callback.
137132
*
138-
* @template U
133+
* @template ReturnType
139134
*
140-
* @param pure-callable(TValue, TKey):U $callback
135+
* @param callable(TValue, TKey):ReturnType $callback
141136
*
142-
* @return static
137+
* @return static<ReturnType, TKey>
143138
*/
144139
final public function map(callable $callback): self
145140
{
141+
/** @var array<TKey, ReturnType> $tbr */
146142
$tbr = [];
147143
foreach ($this->sequence as $key => $value) {
148144
$tbr[$key] = $callback($value, $key);
149145
}
150146

151-
return $this::fromIterable($tbr);
147+
return new static($tbr);
152148
}
153149

154150
/**
155151
* Reduces this sequence with the given callback.
156152
*
157153
* @template TInitial
158154
*
159-
* @param pure-callable(TInitial|null, TValue, TKey):TInitial $callback
160-
* @param TInitial|null $initial
155+
* @param callable(TInitial|null, TValue, TKey):TInitial $callback
156+
* @param TInitial|null $initial
161157
*
162158
* @return TInitial
163159
*/
@@ -185,24 +181,24 @@ final public function find($value)
185181
/**
186182
* Creates a reversed sequence.
187183
*
188-
* @return static
184+
* @return static<TValue, TKey>
189185
*/
190186
abstract public function reversed(): self;
191187

192188
/**
193189
* Slices a new sequence starting from the given offset with a certain length.
194190
* If the length is null it will slice the entire remainder starting from the offset.
195191
*
196-
* @return static
192+
* @return static<TValue, TKey>
197193
*/
198194
abstract public function slice(int $offset, int $length = null): self;
199195

200196
/**
201197
* Creates a sorted sequence. If the compoarator is null it will use natural ordering.
202198
*
203-
* @param (pure-callable(TValue, TValue):int)|null $comparator
199+
* @param (callable(TValue, TValue):int)|null $comparator
204200
*
205-
* @return static
201+
* @return static<TValue, TKey>
206202
*/
207203
abstract public function sorted(?callable $comparator = null): self;
208204

src/Types/ArrayList.php

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,16 @@
2929
*
3030
* @template TValue
3131
*
32-
* @extends AbstractCypherSequence<int, TValue>
32+
* @extends AbstractCypherSequence<TValue, int>
3333
*
3434
* @psalm-immutable
35+
*
36+
* @psalm-suppress UnsafeGenericInstantiation
3537
*/
3638
class ArrayList extends AbstractCypherSequence
3739
{
3840
/**
39-
* @param iterable<TValue> $iterable
41+
* @param iterable<mixed, TValue> $iterable
4042
*/
4143
final public function __construct(iterable $iterable = [])
4244
{
@@ -92,27 +94,27 @@ public function merge($values): ArrayList
9294
$tbr[] = $value;
9395
}
9496

95-
return static::fromIterable($tbr);
97+
return new static($tbr);
9698
}
9799

98100
/**
99101
* @return static<TValue>
100102
*/
101103
public function reversed(): ArrayList
102104
{
103-
return static::fromIterable(array_reverse($this->sequence));
105+
return new static(array_reverse($this->sequence));
104106
}
105107

106108
/**
107109
* @return static<TValue>
108110
*/
109111
public function slice(int $offset, int $length = null): ArrayList
110112
{
111-
return static::fromIterable(array_slice($this->sequence, $offset, $length));
113+
return new static(array_slice($this->sequence, $offset, $length));
112114
}
113115

114116
/**
115-
* @param (pure-callable(TValue, TValue):int)|null $comparator
117+
* @param (callable(TValue, TValue):int)|null $comparator
116118
*
117119
* @return static<TValue>
118120
*/
@@ -122,18 +124,11 @@ public function sorted(callable $comparator = null): ArrayList
122124
if ($comparator === null) {
123125
sort($tbr);
124126
} else {
127+
/** @psalm-suppress ImpureFunctionCall */
125128
usort($tbr, $comparator);
126129
}
127130

128-
return static::fromIterable($tbr);
129-
}
130-
131-
/**
132-
* @pure
133-
*/
134-
public static function fromIterable(iterable $iterable): AbstractCypherSequence
135-
{
136-
return new static($iterable);
131+
return new static($tbr);
137132
}
138133

139134
/**
@@ -235,7 +230,7 @@ public function getAsMap(int $key): Map
235230
throw new RuntimeTypeException($value, Map::class);
236231
}
237232

238-
return Map::fromIterable($value);
233+
return new Map($value);
239234
}
240235

241236
/**
@@ -248,6 +243,21 @@ public function getAsArrayList(int $key): ArrayList
248243
throw new RuntimeTypeException($value, ArrayList::class);
249244
}
250245

251-
return ArrayList::fromIterable($value);
246+
return new ArrayList($value);
247+
}
248+
249+
/**
250+
* @template Value
251+
*
252+
* @param iterable<Value> $iterable
253+
*
254+
* @return static<Value>
255+
*
256+
* @pure
257+
*/
258+
public static function fromIterable(iterable $iterable): ArrayList
259+
{
260+
/** @psalm-suppress UnsafeGenericInstantiation */
261+
return new static($iterable);
252262
}
253263
}

0 commit comments

Comments
 (0)