Completed
Push — master ( d11bf8...9def24 )
by Alexey
02:13
created

Parser::getUseStatements()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 0
crap 3
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Reflection\ClassUseStatements;
6
7
/**
8
 * Class Parser
9
 * @package Reflection
10
 */
11
class Parser {
12
13
    /**
14
     * @const string
15
     */
16
    const USE_STATEMENT_TYPE = 'use';
17
18
    /**
19
     * @const string
20
     */
21
    const ALIAS_STATEMENT_TYPE = 'alias';
22
23
    /**
24
     * @var string
25
     */
26
    private $usesBlock;
27
28
    /**
29
     * @var UseStatements
30
     */
31
    private $useStatements;
32
33
    /**
34
     * @var boolean
35
     */
36
    private $isUseStatementBuilding = false;
37
38
    /**
39
     * @var string
40
     */
41
    private $useStatement = '';
42
43
    /**
44
     * @var string
45
     */
46
    private $committedUseStatement = '';
47
48
    /**
49
     * @var string
50
     */
51
    private $aliasStatement = '';
52
53
    /**
54
     * @var string
55
     */
56
    private $statementType = '';
57
58
    /**
59
     * @var bool
60
     */
61
    private $isBrace = false;
62
63
    /**
64
     * Parser constructor.
65
     * @param string $usesBlock
66
     */
67 1
    public function __construct(string $usesBlock) {
68 1
        $this->useStatements = new UseStatements();
69
70 1
        $this->setUsesBlock($usesBlock);
71 1
    }
72
73
    /**
74
     * @return string
75
     */
76 1
    public function getUsesBlock(): string {
77 1
        return $this->usesBlock;
78
    }
79
80
    /**
81
     * @param string $usesBlock
82
     * @return Parser
83
     */
84 1
    public function setUsesBlock(string $usesBlock): Parser {
85 1
        $this->usesBlock = $usesBlock;
86
87 1
        return $this;
88
    }
89
90
    /**
91
     * @param UseStatement $useStatement
92
     * @return Parser
93
     */
94 1
    private function addUseStatement(UseStatement $useStatement): Parser {
95 1
        $this->useStatements->add($useStatement);
96
97 1
        return $this;
98
    }
99
100
    /**
101
     * @return boolean
102
     */
103 1
    private function isUseStatementBuilding(): bool {
104 1
        return $this->isUseStatementBuilding;
105
    }
106
107
    /**
108
     * @return Parser
109
     */
110 1
    private function setUseStatementIsBuilding(): Parser {
111 1
        $this->isUseStatementBuilding = true;
112
        
113 1
        return $this;
114
    }
115
116
    /**
117
     * @return Parser
118
     */
119 1
    private function setUseStatementIsNotBuilding(): Parser {
120 1
        $this->isUseStatementBuilding = false;
121
122 1
        return $this;
123
    }
124
125
    /**
126
     * @return string
127
     */
128 1
    private function getUseStatement(): string {
129 1
        if ($this->isBrace()) {
130 1
            return $this->getCommittedUseStatement() . $this->useStatement;
131
        }
132
133 1
        return $this->useStatement;
134
    }
135
136
    /**
137
     * @param string $statement
138
     * @return Parser
139
     */
140 1
    private function setUseStatement(string $statement): Parser {
141 1
        $this->useStatement .= $statement;
142
        
143 1
        return $this;
144
    }
145
146
    /**
147
     * @return Parser
148
     */
149 1
    private function clearUseStatement(): Parser {
150 1
        $this->useStatement = '';
151
152 1
        return $this;
153
    }
154
155
    /**
156
     * @return string
157
     */
158 1
    private function getCommittedUseStatement(): string {
159 1
        return $this->committedUseStatement;
160
    }
161
162
    /**
163
     * @return Parser
164
     */
165 1
    private function commitUseStatement(): Parser {
166 1
        $this->committedUseStatement = $this->useStatement;
167
168 1
        return $this;
169
    }
170
171
    /**
172
     * @return string
173
     */
174 1
    private function getAliasStatement(): string {
175 1
        return $this->aliasStatement;
176
    }
177
178
    /**
179
     * @param string $statement
180
     * @return Parser
181
     */
182 1
    private function setAliasStatement(string $statement): Parser {
183 1
        $this->aliasStatement = $statement;
184
        
185 1
        return $this;
186
    }
187
188
    /**
189
     * @return string
190
     */
191 1
    private function getStatementType(): string {
192 1
        return $this->statementType;
193
    }
194
195
    /**
196
     * @param string $statementType
197
     * @return Parser
198
     */
199 1
    private function setStatementType(string $statementType): Parser {
200 1
        $this->statementType = $statementType;
201
        
202 1
        return $this;
203
    }
204
205
    /**
206
     * @return Parser
207
     */
208 1
    private function setIsBrace(): Parser {
209 1
        $this->isBrace = true;
210
211 1
        return $this->commitUseStatement()
212 1
            ->clearUseStatement();
213
    }
214
215
    /**
216
     * @return Parser
217
     */
218 1
    private function setIsNotBrace(): Parser {
219 1
        $this->isBrace = false;
220 1
        $this->committedUseStatement = '';
221
222 1
        return $this;
223
    }
224
225
    /**
226
     * @return bool
227
     */
228 1
    private function isBrace(): bool {
229 1
        return $this->isBrace;
230
    }
231
    
232
    /**
233
     * @return UseStatements
234
     */
235 1
    public function getUseStatements(): UseStatements {
236 1
        foreach ($this->getTokens() as $token) {
237 1
            if (is_array($token)) {
238 1
                $this->analyzeStatementToken($token);
239
            } else {
240 1
                $this->analyzeDelimiterToken($token);
241
            }
242
        }
243
244 1
        return $this->useStatements;
245
    }
246
    
247
    /**
248
     * @return array
249
     */
250 1
    private function getTokens(): array {
251 1
        return token_get_all($this->getUsesBlock());
252
    }
253
254
    /**
255
     * @uses \Reflection\ClassUseStatements\Parser::setUseStatement()
256
     * @uses \Reflection\ClassUseStatements\Parser::setAliasStatement()
257
     * @param string $value
258
     * @return Parser
259
     */
260 1
    private function setStatement(string $value): Parser {
261 1
        $type = $this->getStatementType();
262
263 1
        $setter = 'set' . ucfirst($type) . 'Statement';
264
265 1
        return $this->$setter($value);
266
    }
267
268
    /**
269
     * @return Parser
270
     */
271 1
    private function clearStatements(): Parser {
272 1
        return $this->clearUseStatement()
273 1
            ->setAliasStatement('');
274
    }
275
276
    /**
277
     * @param string $token
278
     * @return Parser
279
     */
280 1
    private function analyzeDelimiterToken(string $token): Parser {
281 1
        if (($token === ';' || $token === ',') && $this->isUseStatementBuilding()) {
282 1
            $this->addUseStatement(new UseStatement(
283 1
                $this->getUseStatement(),
284 1
                $this->getAliasStatement()
285
            ));
286
287 1
            $this->clearStatements();
288
289
            switch ($token) {
290 1
                case ';':
291 1
                    $this->setUseStatementIsNotBuilding();
292
293 1
                    break;
294 1
                case ',':
295 1
                    $this->setStatementType(self::USE_STATEMENT_TYPE);
296
297 1
                    break;
298
            }
299
        }
300
301 1
        return $this->updateBraceState($token);
302
    }
303
304
    /**
305
     * @param array $token
306
     * @return Parser
307
     */
308 1
    private function analyzeStatementToken(array $token): Parser {
309 1
        switch ($token[0]) {
310 1
            case T_USE:
311 1
                $this->setUseStatementIsBuilding()
312 1
                    ->setStatementType(self::USE_STATEMENT_TYPE);
313
314 1
                break;
315 1
            case T_AS:
316 1
                $this->setStatementType(self::ALIAS_STATEMENT_TYPE);
317
318 1
                break;
319
            default:
320 1
                if ($this->isUseStatementBuilding() && $this->getStatementType()) {
321 1
                    switch ($token[0]) {
322 1
                        case T_NS_SEPARATOR:
323 1
                        case T_STRING:
324 1
                            $this->setStatement($token[1]);
325
326 1
                            break;
327
                    }
328
                }
329
        }
330
331 1
        return $this;
332
    }
333
334
    /**
335
     * @param string $token
336
     * @return Parser
337
     */
338 1
    private function updateBraceState(string $token): Parser {
339
        switch ($token) {
340 1
            case '{':
341 1
                $this->setIsBrace();
342
343 1
                break;
344 1
            case ';':
345 1
                $this->setIsNotBrace();
346
347 1
                break;
348
        }
349
350 1
        return $this;
351
    }
352
    
353
}