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 — develop ( e3dec6...8399e0 )
by Baptiste
03:10
created

Sequence   B

Complexity

Total Complexity 49

Size/Duplication

Total Lines 387
Duplicated Lines 3.88 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 97.54%
Metric Value
wmc 49
lcom 1
cbo 6
dl 15
loc 387
ccs 119
cts 122
cp 0.9754
rs 8.5454

38 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A size() 0 4 1
A count() 0 4 1
A current() 0 4 1
A key() 0 4 1
A next() 0 4 1
A rewind() 0 4 1
A valid() 0 4 1
A offsetExists() 0 4 1
A offsetGet() 0 11 2
A offsetSet() 0 4 1
A offsetUnset() 0 4 1
A toPrimitive() 0 4 1
A get() 0 8 2
A diff() 0 9 1
A distinct() 0 4 1
A drop() 0 4 1
A dropEnd() 0 4 1
A equals() 0 4 1
A filter() 0 7 1
A foreach() 0 8 2
B groupBy() 15 31 6
A first() 0 4 1
A last() 0 4 1
A contains() 0 4 1
A indexOf() 0 10 2
A indices() 0 4 1
A map() 0 4 1
A pad() 0 4 1
A partition() 0 18 3
A slice() 0 8 1
A splitAt() 0 7 1
A take() 0 4 1
A takeEnd() 0 4 1
A append() 0 4 1
A intersect() 0 4 1
A join() 0 4 1
A add() 0 7 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Sequence 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 Sequence, 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\{
7
    Exception\OutOfBoundException,
8
    Exception\LogicException,
9
    Exception\ElementNotFoundException
10
};
11
12
/**
13
 * A defined set of ordered elements
14
 */
15
class Sequence implements SequenceInterface
16
{
17
    private $values;
18
    private $size;
19
20 62
    public function __construct(...$values)
21
    {
22 62
        $this->values = $values;
23 62
        $this->size = count($values);
24 62
    }
25
26
    /**
27
     * {@inheritdoc}
28
     */
29 23
    public function size(): int
30
    {
31 23
        return $this->size;
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37 1
    public function count(): int
38
    {
39 1
        return $this->size();
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45 6
    public function current()
46
    {
47 6
        return current($this->values);
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 8
    public function key()
54
    {
55 8
        return key($this->values);
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61 8
    public function next()
62
    {
63 8
        next($this->values);
64 8
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69 6
    public function rewind()
70
    {
71 6
        reset($this->values);
72 6
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77 6
    public function valid(): bool
78
    {
79 6
        return $this->key() !== null;
80
    }
81
82
    /**
83
     * {@inheritdoc}
84
     */
85 1
    public function offsetExists($offset): bool
86
    {
87 1
        return array_key_exists($offset, $this->values);
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93 1
    public function offsetGet($offset)
94
    {
95 1
        if (!$this->offsetExists($offset)) {
96
            throw new OutOfBoundException(sprintf(
97
                'Unknown index %s',
98
                $offset
99
            ));
100
        }
101
102 1
        return $this->values[$offset];
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108 1
    public function offsetSet($offset, $value)
109
    {
110 1
        throw new LogicException('You can\'t modify a sequence');
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116 1
    public function offsetUnset($offset)
117
    {
118 1
        throw new LogicException('You can\'t modify a sequence');
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124 25
    public function toPrimitive()
125
    {
126 25
        return $this->values;
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132 14
    public function get(int $index)
133
    {
134 14
        if ($index >= $this->size()) {
135 1
            throw new OutOfBoundException;
136
        }
137
138 13
        return $this->values[$index];
139
    }
140
141
    /**
142
     * {@inheritdoc}
143
     */
144 1
    public function diff(SequenceInterface $seq): SequenceInterface
145
    {
146 1
        return new self(
147 1
            ...array_diff(
148 1
                $this->values,
149 1
                $seq->toPrimitive()
150
            )
151
        );
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157 1
    public function distinct(): SequenceInterface
158
    {
159 1
        return new self(...array_unique($this->values));
160
    }
161
162
    /**
163
     * {@inheritdoc}
164
     */
165 5
    public function drop(int $size): SequenceInterface
166
    {
167 5
        return new self(...array_slice($this->values, $size));
168
    }
169
170
    /**
171
     * {@inheritdoc}
172
     */
173 2
    public function dropEnd(int $size): SequenceInterface
174
    {
175 2
        return new self(...array_slice($this->values, 0, $this->size() - $size));
176
    }
177
178
    /**
179
     * {@inheritdoc}
180
     */
181 3
    public function equals(SequenceInterface $seq): bool
182
    {
183 3
        return $this->values === $seq->toPrimitive();
184
    }
185
186
    /**
187
     * {@inheritdoc}
188
     */
189 1
    public function filter(\Closure $predicate): SequenceInterface
190
    {
191 1
        return new self(...array_filter(
192 1
            $this->values,
193
            $predicate
194
        ));
195
    }
196
197
    /**
198
     * {@inheritdoc}
199
     */
200 1
    public function foreach(\Closure $function): SequenceInterface
201
    {
202 1
        foreach ($this->values as $value) {
203 1
            $function($value);
204
        }
205
206 1
        return $this;
207
    }
208
209
    /**
210
     * {@inheritdoc}
211
     */
212 1
    public function groupBy(\Closure $discriminator): MapInterface
213
    {
214 1
        if ($this->size() === 0) {
215
            throw new GroupEmptySequenceException;
216
        }
217
218 1
        $map = null;
219
220 1
        foreach ($this->values as $value) {
221 1
            $key = $discriminator($value);
222
223 1 View Code Duplication
            if ($map === null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
224 1
                $type = gettype($key);
225 1
                $map = new Map(
226 1
                    $type === 'object' ? get_class($key) : $type,
227 1
                    SequenceInterface::class
228
                );
229
            }
230
231 1 View Code Duplication
            if ($map->contains($key)){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
232 1
                $map = $map->put(
233
                    $key,
234 1
                    $map->get($key)->add($value)
235
                );
236
            } else {
237 1
                $map = $map->put($key, new Sequence($value));
238
            }
239
        }
240
241 1
        return $map;
242
    }
243
244
    /**
245
     * {@inheritdoc}
246
     */
247 2
    public function first()
248
    {
249 2
        return $this->values[0];
250
    }
251
252
    /**
253
     * {@inheritdoc}
254
     */
255 2
    public function last()
256
    {
257 2
        return $this->values[$this->size() - 1];
258
    }
259
260
    /**
261
     * {@inheritdoc}
262
     */
263 25
    public function contains($element): bool
264
    {
265 25
        return in_array($element, $this->values, true);
266
    }
267
268
    /**
269
     * {@inheritdoc}
270
     */
271 9
    public function indexOf($element): int
272
    {
273 9
        $index = array_search($element, $this->values);
274
275 9
        if ($index === false) {
276 1
            throw new ElementNotFoundException;
277
        }
278
279 8
        return $index;
280
    }
281
282
    /**
283
     * {@inheritdoc}
284
     */
285 1
    public function indices(): SequenceInterface
286
    {
287 1
        return new self(...array_keys($this->values));
288
    }
289
290
    /**
291
     * {@inheritdoc}
292
     */
293 1
    public function map(\Closure $function): SequenceInterface
294
    {
295 1
        return new self(...array_map($function, $this->values));
296
    }
297
298
    /**
299
     * {@inheritdoc}
300
     */
301 1
    public function pad(int $size, $element): SequenceInterface
302
    {
303 1
        return new self(...array_pad($this->values, $size, $element));
304
    }
305
306
    /**
307
     * {@inheritdoc}
308
     */
309 1
    public function partition(\Closure $predicate): SequenceInterface
310
    {
311 1
        $truthy = [];
312 1
        $falsy = [];
313
314 1
        foreach ($this->values as $value) {
315 1
            if ($predicate($value) === true) {
316 1
                $truthy[] = $value;
317
            } else {
318 1
                $falsy[] = $value;
319
            }
320
        }
321
322 1
        return new self(
323 1
            new self(...$truthy),
324 1
            new self(...$falsy)
325
        );
326
    }
327
328
    /**
329
     * {@inheritdoc}
330
     */
331 9
    public function slice(int $from, int $until): SequenceInterface
332
    {
333 9
        return new self(...array_slice(
334 9
            $this->values,
335
            $from,
336 9
            $until - $from
337
        ));
338
    }
339
340
    /**
341
     * {@inheritdoc}
342
     */
343 1
    public function splitAt(int $index): SequenceInterface
344
    {
345 1
        return new self(
346 1
            $this->slice(0, $index),
347 1
            $this->slice($index, $this->size())
348
        );
349
    }
350
351
    /**
352
     * {@inheritdoc}
353
     */
354 5
    public function take(int $size): SequenceInterface
355
    {
356 5
        return $this->slice(0, $size);
357
    }
358
359
    /**
360
     * {@inheritdoc}
361
     */
362 2
    public function takeEnd(int $size): SequenceInterface
363
    {
364 2
        return $this->slice($this->size() - $size, $this->size());
365
    }
366
367
    /**
368
     * {@inheritdoc}
369
     */
370 4
    public function append(SequenceInterface $seq): SequenceInterface
371
    {
372 4
        return new self(...$this->values, ...$seq->toPrimitive());
373
    }
374
375
    /**
376
     * {@inheritdoc}
377
     */
378 1
    public function intersect(SequenceInterface $seq): SequenceInterface
379
    {
380 1
        return new self(...array_intersect($this->values, $seq->toPrimitive()));
381
    }
382
383
    /**
384
     * {@inheritdoc}
385
     */
386 2
    public function join(string $separator): StringPrimitive
387
    {
388 2
        return new StringPrimitive(implode($separator, $this->values));
389
    }
390
391
    /**
392
     * {@inheritdoc}
393
     */
394 23
    public function add($element): SequenceInterface
395
    {
396 23
        $values = $this->values;
397 23
        $values[] = $element;
398
399 23
        return new self(...$values);
400
    }
401
}
402