GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 9c20fb...b12bea )
by Baptiste
05:26
created

Stream   C

Complexity

Total Complexity 53

Size/Duplication

Total Lines 506
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 141
dl 0
loc 506
ccs 184
cts 184
cp 1
rs 6.96
c 0
b 0
f 0
wmc 53

46 Methods

Rating   Name   Duplication   Size   Complexity  
A validate() 0 5 2
A indices() 0 3 1
A join() 0 3 1
A key() 0 3 1
A partition() 0 21 3
A of() 0 9 1
A current() 0 3 1
A append() 0 10 1
A splitAt() 0 10 1
A reverse() 0 6 1
A equals() 0 6 1
A map() 0 9 1
A groupBy() 0 32 5
A filter() 0 6 1
A count() 0 3 1
A offsetSet() 0 3 1
A diff() 0 10 1
A indexOf() 0 3 1
A get() 0 3 1
A drop() 0 6 1
A last() 0 3 1
A valid() 0 3 1
A distinct() 0 6 1
A type() 0 3 1
A next() 0 3 1
A offsetExists() 0 3 1
A size() 0 3 1
A slice() 0 6 1
A __construct() 0 5 1
A toPrimitive() 0 3 1
A sort() 0 6 1
A add() 0 8 1
A foreach() 0 5 1
A offsetUnset() 0 3 1
A rewind() 0 3 1
A intersect() 0 10 1
A dropEnd() 0 6 1
A offsetGet() 0 3 1
A pad() 0 8 1
A takeEnd() 0 6 1
A reduce() 0 3 1
A clear() 0 6 1
A contains() 0 3 1
A first() 0 3 1
A take() 0 6 1
A empty() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Stream often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Stream, and based on these observations, apply Extract Interface, too.

1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Immutable;
5
6
use Innmind\Immutable\Exception\{
7
    LogicException,
8
    GroupEmptySequenceException,
9
    InvalidArgumentException
10
};
11
12
/**
13
 * {@inheritdoc}
14
 */
15
class Stream implements StreamInterface
16
{
17
    private $type;
18
    private $spec;
19
    private $values;
20
21 306
    public function __construct(string $type)
22
    {
23 306
        $this->type = new Str($type);
24 306
        $this->spec = Type::of($type);
25 306
        $this->values = new Sequence;
26 306
    }
27
28 90
    public static function of(string $type, ...$values): self
29
    {
30 90
        $self = new self($type);
31 90
        $self->values = new Sequence(...$values);
32 90
        $self->values->foreach(static function($element) use ($self): void {
33 72
            $self->spec->validate($element);
34 90
        });
35
36 90
        return $self;
37
    }
38
39
    /**
40
     * {@inheritdoc}
41
     */
42 102
    public function type(): Str
43
    {
44 102
        return $this->type;
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 46
    public function size(): int
51
    {
52 46
        return $this->values->size();
53
    }
54
55
    /**
56
     * {@inheritdoc}
57
     */
58 10
    public function count(): int
59
    {
60 10
        return $this->values->size();
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 136
    public function toPrimitive()
67
    {
68 136
        return $this->values->toPrimitive();
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74 78
    public function current()
75
    {
76 78
        return $this->values->current();
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82 62
    public function key()
83
    {
84 62
        return $this->values->key();
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90 74
    public function next()
91
    {
92 74
        $this->values->next();
93 74
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98 78
    public function rewind()
99
    {
100 78
        $this->values->rewind();
101 78
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106 78
    public function valid()
107
    {
108 78
        return $this->values->valid();
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114 2
    public function offsetExists($offset): bool
115
    {
116 2
        return $this->values->offsetExists($offset);
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122 18
    public function offsetGet($offset)
123
    {
124 18
        return $this->get($offset);
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130 2
    public function offsetSet($offset, $value)
131
    {
132 2
        throw new LogicException('You can\'t modify a stream');
133
    }
134
135
    /**
136
     * {@inheritdoc}
137
     */
138 2
    public function offsetUnset($offset)
139
    {
140 2
        throw new LogicException('You can\'t modify a stream');
141
    }
142
143
    /**
144
     * {@inheritdoc}
145
     */
146 56
    public function get(int $index)
147
    {
148 56
        return $this->values->get($index);
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154 4
    public function diff(StreamInterface $stream): StreamInterface
155
    {
156 4
        $this->validate($stream);
157
158 4
        $newStream = clone $this;
159 4
        $newStream->values = $this->values->diff(
160 4
            new Sequence(...$stream)
161
        );
162
163 4
        return $newStream;
164
    }
165
166
    /**
167
     * {@inheritdoc}
168
     */
169 62
    public function distinct(): StreamInterface
170
    {
171 62
        $stream = clone $this;
172 62
        $stream->values = $this->values->distinct();
173
174 62
        return $stream;
175
    }
176
177
    /**
178
     * {@inheritdoc}
179
     */
180 8
    public function drop(int $size): StreamInterface
181
    {
182 8
        $stream = clone $this;
183 8
        $stream->values = $this->values->drop($size);
184
185 8
        return $stream;
186
    }
187
188
    /**
189
     * {@inheritdoc}
190
     */
191 2
    public function dropEnd(int $size): StreamInterface
192
    {
193 2
        $stream = clone $this;
194 2
        $stream->values = $this->values->dropEnd($size);
195
196 2
        return $stream;
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     */
202 14
    public function equals(StreamInterface $stream): bool
203
    {
204 14
        $this->validate($stream);
205
206 12
        return $this->values->equals(
207 12
            new Sequence(...$stream)
208
        );
209
    }
210
211
    /**
212
     * {@inheritdoc}
213
     */
214 4
    public function filter(callable $predicate): StreamInterface
215
    {
216 4
        $stream = clone $this;
217 4
        $stream->values = $this->values->filter($predicate);
218
219 4
        return $stream;
220
    }
221
222
    /**
223
     * {@inheritdoc}
224
     */
225 4
    public function foreach(callable $function): StreamInterface
226
    {
227 4
        $this->values->foreach($function);
228
229 4
        return $this;
230
    }
231
232
    /**
233
     * {@inheritdoc}
234
     */
235 6
    public function groupBy(callable $discriminator): MapInterface
236
    {
237 6
        if ($this->size() === 0) {
238 2
            throw new GroupEmptySequenceException;
239
        }
240
241 4
        $map = null;
242
243 4
        foreach ($this->values as $value) {
244 4
            $key = $discriminator($value);
245
246 4
            if ($map === null) {
247 4
                $map = new Map(
248 4
                    Type::determine($key),
249 4
                    StreamInterface::class
250
                );
251
            }
252
253 4
            if ($map->contains($key)) {
254 4
                $map = $map->put(
255 4
                    $key,
256 4
                    $map->get($key)->add($value)
257
                );
258
            } else {
259 4
                $map = $map->put(
260 4
                    $key,
261 4
                    (new self((string) $this->type))->add($value)
262
                );
263
            }
264
        }
265
266 4
        return $map;
267
    }
268
269
    /**
270
     * {@inheritdoc}
271
     */
272 4
    public function first()
273
    {
274 4
        return $this->values->first();
275
    }
276
277
    /**
278
     * {@inheritdoc}
279
     */
280 4
    public function last()
281
    {
282 4
        return $this->values->last();
283
    }
284
285
    /**
286
     * {@inheritdoc}
287
     */
288 116
    public function contains($element): bool
289
    {
290 116
        return $this->values->contains($element);
291
    }
292
293
    /**
294
     * {@inheritdoc}
295
     */
296 38
    public function indexOf($element): int
297
    {
298 38
        return $this->values->indexOf($element);
299
    }
300
301
    /**
302
     * {@inheritdoc}
303
     */
304 4
    public function indices(): StreamInterface
305
    {
306 4
        return $this->values->indices();
307
    }
308
309
    /**
310
     * {@inheritdoc}
311
     */
312 6
    public function map(callable $function): StreamInterface
313
    {
314 6
        $self = clone $this;
315 6
        $self->values = $this->values->map($function);
316 6
        $self->values->foreach(function($element): void {
317 6
            $this->spec->validate($element);
318 6
        });
319
320 4
        return $self;
321
    }
322
323
    /**
324
     * {@inheritdoc}
325
     */
326 4
    public function pad(int $size, $element): StreamInterface
327
    {
328 4
        $this->spec->validate($element);
329
330 2
        $stream = clone $this;
331 2
        $stream->values = $this->values->pad($size, $element);
332
333 2
        return $stream;
334
    }
335
336
    /**
337
     * {@inheritdoc}
338
     */
339 4
    public function partition(callable $predicate): MapInterface
340
    {
341 4
        $truthy = [];
342 4
        $falsy = [];
343
344 4
        foreach ($this->values as $value) {
345 4
            if ($predicate($value) === true) {
346 4
                $truthy[] = $value;
347
            } else {
348 4
                $falsy[] = $value;
349
            }
350
        }
351
352 4
        $true = $this->clear();
353 4
        $true->values = new Sequence(...$truthy);
354 4
        $false = $this->clear();
355 4
        $false->values = new Sequence(...$falsy);
356
357 4
        return Map::of('bool', StreamInterface::class)
358 4
            (true, $true)
359 4
            (false, $false);
360
    }
361
362
    /**
363
     * {@inheritdoc}
364
     */
365 6
    public function slice(int $from, int $until): StreamInterface
366
    {
367 6
        $stream = clone $this;
368 6
        $stream->values = $this->values->slice($from, $until);
369
370 6
        return $stream;
371
    }
372
373
    /**
374
     * {@inheritdoc}
375
     */
376 2
    public function splitAt(int $position): StreamInterface
377
    {
378 2
        $stream = new self(StreamInterface::class);
379 2
        $splitted = $this->values->splitAt($position);
380 2
        $first = new self((string) $this->type);
381 2
        $second = new self((string) $this->type);
382 2
        $first->values = $splitted->first();
383 2
        $second->values = $splitted->last();
384
385 2
        return $stream->add($first)->add($second);
386
    }
387
388
    /**
389
     * {@inheritdoc}
390
     */
391 8
    public function take(int $size): StreamInterface
392
    {
393 8
        $stream = clone $this;
394 8
        $stream->values = $this->values->take($size);
395
396 8
        return $stream;
397
    }
398
399
    /**
400
     * {@inheritdoc}
401
     */
402 2
    public function takeEnd(int $size): StreamInterface
403
    {
404 2
        $stream = clone $this;
405 2
        $stream->values = $this->values->takeEnd($size);
406
407 2
        return $stream;
408
    }
409
410
    /**
411
     * {@inheritdoc}
412
     */
413 14
    public function append(StreamInterface $stream): StreamInterface
414
    {
415 14
        $this->validate($stream);
416
417 12
        $self = clone $this;
418 12
        $self->values = $this->values->append(
419 12
            new Sequence(...$stream)
420
        );
421
422 12
        return $self;
423
    }
424
425
    /**
426
     * {@inheritdoc}
427
     */
428 24
    public function intersect(StreamInterface $stream): StreamInterface
429
    {
430 24
        $this->validate($stream);
431
432 22
        $self = clone $this;
433 22
        $self->values = $this->values->intersect(
434 22
            new Sequence(...$stream)
435
        );
436
437 22
        return $self;
438
    }
439
440
    /**
441
     * {@inheritdoc}
442
     */
443 20
    public function join(string $separator): Str
444
    {
445 20
        return new Str((string) $this->values->join($separator));
446
    }
447
448
    /**
449
     * {@inheritdoc}
450
     */
451 216
    public function add($element): StreamInterface
452
    {
453 216
        $this->spec->validate($element);
454
455 214
        $stream = clone $this;
456 214
        $stream->values = $this->values->add($element);
457
458 214
        return $stream;
459
    }
460
461
    /**
462
     * {@inheritdoc}
463
     */
464 4
    public function sort(callable $function): StreamInterface
465
    {
466 4
        $stream = clone $this;
467 4
        $stream->values = $this->values->sort($function);
468
469 4
        return $stream;
470
    }
471
472
    /**
473
     * {@inheritdoc}
474
     */
475 10
    public function reduce($carry, callable $reducer)
476
    {
477 10
        return $this->values->reduce($carry, $reducer);
478
    }
479
480
    /**
481
     * {@inheritdoc}
482
     */
483 28
    public function clear(): StreamInterface
484
    {
485 28
        $self = clone $this;
486 28
        $self->values = new Sequence;
487
488 28
        return $self;
489
    }
490
491
    /**
492
     * {@inheritdoc}
493
     */
494 4
    public function reverse(): StreamInterface
495
    {
496 4
        $self = clone $this;
497 4
        $self->values = $this->values->reverse();
498
499 4
        return $self;
500
    }
501
502 6
    public function empty(): bool
503
    {
504 6
        return $this->values->empty();
505
    }
506
507
    /**
508
     * Make sure the stream is compatible with the current one
509
     *
510
     * @param StreamInterface $stream
511
     *
512
     * @throws InvalidArgumentException
513
     *
514
     * @return void
515
     */
516 52
    private function validate(StreamInterface $stream)
517
    {
518 52
        if (!$stream->type()->equals($this->type)) {
519 6
            throw new InvalidArgumentException(
520 6
                'The 2 streams does not reference the same type'
521
            );
522
        }
523 46
    }
524
}
525