Completed
Push — master ( 6be94d...a1eb14 )
by Jaap
06:00
created

AggregatedType::contains()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
/**
3
 * This file is part of phpDocumentor.
4
 *
5
 *  For the full copyright and license information, please view the LICENSE
6
 *  file that was distributed with this source code.
7
 *
8
 * @link      http://phpdoc.org
9
 */
10
11
declare(strict_types=1);
12
13
namespace phpDocumentor\Reflection\Types;
14
15
use ArrayIterator;
16
use IteratorAggregate;
17
use phpDocumentor\Reflection\Type;
18
use function array_key_exists;
19
use function implode;
20
21
/**
22
 * Base class for aggregated types like Compound and Intersection
23
 *
24
 * A Aggregated Type is not so much a special keyword or object reference but is a series of Types that are separated
25
 * using separator.
26
 *
27
 * @psalm-immutable
28
 * @template-implements IteratorAggregate<int, Type>
29
 */
30
abstract class AggregatedType implements Type, IteratorAggregate
31
{
32
    /**
33
     * @psalm-allow-private-mutation
34
     * @var array<int, Type>
35
     */
36
    private $types = [];
37
38
    /** @var string */
39
    private $token;
40
41
    /**
42
     * @param Type[] $types
43
     *
44
     * @phpstan-param list<Type> $types
45
     */
46
    public function __construct(array $types, string $token)
47
    {
48
        foreach ($types as $type) {
49
            $this->add($type);
50
        }
51
52
        $this->token = $token;
53
    }
54
55
    /**
56
     * Returns the type at the given index.
57
     */
58
    public function get(int $index) : ?Type
59
    {
60
        if (!$this->has($index)) {
61
            return null;
62
        }
63
64
        return $this->types[$index];
65
    }
66
67
    /**
68
     * Tests if this compound type has a type with the given index.
69
     */
70
    public function has(int $index) : bool
71
    {
72
        return array_key_exists($index, $this->types);
73
    }
74
75
    /**
76
     * Tests if this compound type contains the given type.
77
     */
78
    public function contains(Type $type) : bool
79
    {
80
        foreach ($this->types as $typePart) {
81
            // if the type is duplicate; do not add it
82
            if ((string) $typePart === (string) $type) {
83
                return true;
84
            }
85
        }
86
87
        return false;
88
    }
89
90
    /**
91
     * Returns a rendered output of the Type as it would be used in a DocBlock.
92
     */
93
    public function __toString() : string
94
    {
95
        return implode($this->token, $this->types);
96
    }
97
98
    /**
99
     * @return ArrayIterator<int, Type>
0 ignored issues
show
Documentation introduced by
The doc-type ArrayIterator<int, could not be parsed: Expected "|" or "end of type", but got "<" at position 13. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
100
     */
101
    public function getIterator() : ArrayIterator
102
    {
103
        return new ArrayIterator($this->types);
104
    }
105
106
    /**
107
     * @psalm-suppress ImpureMethodCall
108
     */
109
    private function add(Type $type) : void
110
    {
111
        if ($type instanceof self) {
112
            foreach ($type->getIterator() as $subType) {
113
                $this->add($subType);
114
            }
115
116
            return;
117
        }
118
119
        // if the type is duplicate; do not add it
120
        if ($this->contains($type)) {
121
            return;
122
        }
123
124
        $this->types[] = $type;
125
    }
126
}
127