Passed
Push — master ( dec0a2...7eed57 )
by William
13:36 queued 10:52
created

TokensList::offsetGet()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 2
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin\SqlParser;
6
7
use ArrayAccess;
8
9
use function count;
10
use function is_array;
11
use function is_string;
12
13
/**
14
 * Defines an array of tokens and utility functions to iterate through it.
15
 *
16
 * A structure representing a list of tokens.
17
 *
18
 * @implements ArrayAccess<int, Token>
19
 */
20
class TokensList implements ArrayAccess
21
{
22
    /**
23
     * The array of tokens.
24
     *
25
     * @var Token[]
26
     */
27
    public $tokens = [];
28
29
    /**
30
     * The count of tokens.
31
     *
32
     * @var int
33
     */
34
    public $count = 0;
35
36
    /**
37
     * The index of the next token to be returned.
38
     *
39
     * @var int
40
     */
41
    public $idx = 0;
42
43
    /**
44
     * @param Token[] $tokens the initial array of tokens
45
     * @param int     $count  the count of tokens in the initial array
46
     */
47 2388
    public function __construct(array $tokens = [], $count = -1)
48
    {
49 2388
        if (empty($tokens)) {
50 2364
            return;
51
        }
52
53 124
        $this->tokens = $tokens;
54 124
        $this->count = $count === -1 ? count($tokens) : $count;
55 62
    }
56
57
    /**
58
     * Builds an array of tokens by merging their raw value.
59
     *
60
     * @param string|Token[]|TokensList $list the tokens to be built
61
     *
62
     * @return string
63
     */
64 44
    public static function build($list)
65
    {
66 44
        if (is_string($list)) {
67 4
            return $list;
68
        }
69
70 40
        if ($list instanceof self) {
71 4
            $list = $list->tokens;
72
        }
73
74 40
        $ret = '';
75 40
        if (is_array($list)) {
0 ignored issues
show
introduced by
The condition is_array($list) is always true.
Loading history...
76 40
            foreach ($list as $tok) {
77 36
                $ret .= $tok->token;
78
            }
79
        }
80
81 40
        return $ret;
82
    }
83
84
    /**
85
     * Adds a new token.
86
     *
87
     * @param Token $token token to be added in list
88
     *
89
     * @return void
90
     */
91 4
    public function add(Token $token)
92
    {
93 4
        $this->tokens[$this->count++] = $token;
94 2
    }
95
96
    /**
97
     * Gets the next token. Skips any irrelevant token (whitespaces and
98
     * comments).
99
     *
100
     * @return Token|null
101
     */
102 848
    public function getNext()
103
    {
104 848
        for (; $this->idx < $this->count; ++$this->idx) {
105
            if (
106 844
                ($this->tokens[$this->idx]->type !== Token::TYPE_WHITESPACE)
107 844
                && ($this->tokens[$this->idx]->type !== Token::TYPE_COMMENT)
108
            ) {
109 844
                return $this->tokens[$this->idx++];
110
            }
111
        }
112
113 8
        return null;
114
    }
115
116
    /**
117
     * Gets the previous token. Skips any irrelevant token (whitespaces and
118
     * comments).
119
     */
120 844
    public function getPrevious(): ?Token
121
    {
122 844
        for (; $this->idx > 0; --$this->idx) {
123
            if (
124 836
                ($this->tokens[$this->idx]->type !== Token::TYPE_WHITESPACE)
125 836
                && ($this->tokens[$this->idx]->type !== Token::TYPE_COMMENT)
126
            ) {
127 700
                return $this->tokens[$this->idx--];
128
            }
129
        }
130
131 400
        return null;
132
    }
133
134
    /**
135
     * Gets the next token.
136
     *
137
     * @param int $type the type
138
     *
139
     * @return Token|null
140
     */
141 236
    public function getNextOfType($type)
142
    {
143 236
        for (; $this->idx < $this->count; ++$this->idx) {
144 236
            if ($this->tokens[$this->idx]->type === $type) {
145 236
                return $this->tokens[$this->idx++];
146
            }
147
        }
148
149 16
        return null;
150
    }
151
152
    /**
153
     * Gets the next token.
154
     *
155
     * @param int    $type  the type of the token
156
     * @param string $value the value of the token
157
     *
158
     * @return Token|null
159
     */
160 2348
    public function getNextOfTypeAndValue($type, $value)
161
    {
162 2348
        for (; $this->idx < $this->count; ++$this->idx) {
163 2348
            if (($this->tokens[$this->idx]->type === $type) && ($this->tokens[$this->idx]->value === $value)) {
164 432
                return $this->tokens[$this->idx++];
165
            }
166
        }
167
168 2348
        return null;
169
    }
170
171
    /**
172
     * Gets the next token.
173
     *
174
     * @param int $type the type of the token
175
     * @param int $flag the flag of the token
176
     */
177 2348
    public function getNextOfTypeAndFlag(int $type, int $flag): ?Token
178
    {
179 2348
        for (; $this->idx < $this->count; ++$this->idx) {
180 2348
            if (($this->tokens[$this->idx]->type === $type) && ($this->tokens[$this->idx]->flags === $flag)) {
181 292
                return $this->tokens[$this->idx++];
182
            }
183
        }
184
185 2348
        return null;
186
    }
187
188
    /**
189
     * Sets an value inside the container.
190
     *
191
     * @param int|null $offset the offset to be set
192
     * @param Token    $value  the token to be saved
193
     *
194
     * @return void
195
     */
196 1
    #[\ReturnTypeWillChange]
197 3
    public function offsetSet($offset, $value)
198
    {
199 4
        if ($offset === null) {
200 4
            $this->tokens[$this->count++] = $value;
201
        } else {
202 4
            $this->tokens[$offset] = $value;
203
        }
204 2
    }
205
206
    /**
207
     * Gets a value from the container.
208
     *
209
     * @param int $offset the offset to be returned
210
     *
211
     * @return Token|null
212
     */
213 7
    #[\ReturnTypeWillChange]
214 21
    public function offsetGet($offset)
215
    {
216 28
        return $offset < $this->count ? $this->tokens[$offset] : null;
217
    }
218
219
    /**
220
     * Checks if an offset was previously set.
221
     *
222
     * @param int $offset the offset to be checked
223
     *
224
     * @return bool
225
     */
226 1
    #[\ReturnTypeWillChange]
227 3
    public function offsetExists($offset)
228
    {
229 4
        return $offset < $this->count;
230
    }
231
232
    /**
233
     * Unsets the value of an offset.
234
     *
235
     * @param int $offset the offset to be unset
236
     *
237
     * @return void
238
     */
239 1
    #[\ReturnTypeWillChange]
240 3
    public function offsetUnset($offset)
241
    {
242 4
        unset($this->tokens[$offset]);
243 4
        --$this->count;
244 4
        for ($i = $offset; $i < $this->count; ++$i) {
245 4
            $this->tokens[$i] = $this->tokens[$i + 1];
246
        }
247
248 4
        unset($this->tokens[$this->count]);
249 2
    }
250
}
251