Passed
Pull Request — master (#34)
by Evgeniy
02:28
created

UseStatementParser   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Test Coverage

Coverage 94%

Importance

Changes 5
Bugs 1 Features 0
Metric Value
eloc 50
c 5
b 1
f 0
dl 0
loc 96
ccs 47
cts 50
cp 0.94
rs 10
wmc 25

3 Methods

Rating   Name   Duplication   Size   Complexity  
A replaceAliases() 0 14 3
A fromFile() 0 18 4
D normalizeUse() 0 46 18
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\VarDumper;
6
7
use function defined;
8
9
/**
10
 * UseStatementParser given a PHP file, returns a set of `use` statements from the code.
11
 */
12
final class UseStatementParser
13
{
14
    /**
15
     * @param string $file File to read.
16
     *
17
     * @return array Use statements data.
18
     */
19 44
    public function fromFile(string $file): array
20
    {
21 44
        $tokens = token_get_all(file_get_contents($file));
22 44
        array_shift($tokens);
23
24 44
        $uses = [];
25 44
        foreach ($tokens as $i => $token) {
26 44
            if (!isset($token[0])) {
27
                continue;
28
            }
29
30 44
            if ($token[0] === T_USE) {
31 44
                $uses = array_merge($uses, $this->normalizeUse(array_slice($tokens, $i + 1)));
32 44
                continue;
33
            }
34
        }
35
36 44
        return $uses;
37
    }
38
39
    /**
40
     * Normalizes raw tokens into uniform use statement data.
41
     *
42
     * @param array $tokens Raw tokens.
43
     *
44
     * @return array Normalized use statement data.
45
     */
46 44
    private function normalizeUse(array $tokens): array
47
    {
48 44
        $commonNamespace = '\\';
49 44
        $current = '';
50 44
        $alias = null;
51 44
        $uses = [];
52
53 44
        foreach ($tokens as $token) {
54 44
            if (!isset($token[0])) {
55
                continue;
56
            }
57
58
            if (
59 44
                $token[0] === T_STRING
60 44
                || $token[0] === T_NS_SEPARATOR
61 44
                || (defined('T_NAME_QUALIFIED') && $token[0] === T_NAME_QUALIFIED)
62 44
                || (defined('T_NAME_FULLY_QUALIFIED') && $token[0] === T_NAME_FULLY_QUALIFIED)
63 44
                || (defined('T_NAME_RELATIVE') && $token[0] === T_NAME_RELATIVE)
64
            ) {
65 44
                $current .= $token[1];
66 44
                continue;
67
            }
68 44
            if ($token === ',' || $token === ';') {
69 44
                if ($current !== '') {
70 44
                    if ($alias === null) {
71 44
                        $uses[] = $commonNamespace . $current;
72
                    } else {
73
                        $uses[$alias] = $commonNamespace . $current;
74
                    }
75 44
                    $current = '';
76
                }
77
            }
78 44
            if ($token === ';') {
79 44
                break;
80
            }
81 44
            if ($token === '{') {
82 1
                $commonNamespace .= $current;
83 1
                $current = '';
84 1
                continue;
85
            }
86 44
            if ($token[0] === T_AS) {
87 41
                $current .= '@';
88
            }
89
        }
90
91 44
        return $this->replaceAliases($uses);
92
    }
93
94 44
    private function replaceAliases(array $uses): array
95
    {
96 44
        $result = [];
97 44
        foreach ($uses as $use) {
98 44
            $delimiterPosition = strpos($use, '@');
99 44
            if ($delimiterPosition !== false) {
100 41
                $alias = mb_substr($use, $delimiterPosition + 1);
101 41
                $result[$alias] = mb_substr($use, 0, $delimiterPosition);
102
            } else {
103 42
                $result[substr(strrchr($use, '\\'), 1)] = $use;
104
            }
105
        }
106
107 44
        return $result;
108
    }
109
}
110