Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
87.50% |
63 / 72 |
|
82.35% |
14 / 17 |
CRAP | |
0.00% |
0 / 1 |
DiscoveredSymbols | |
87.50% |
63 / 72 |
|
82.35% |
14 / 17 |
28.42 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
add | |
80.00% |
12 / 15 |
|
0.00% |
0 / 1 |
8.51 | |||
getSymbols | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
getConstants | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getNamespaces | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getNamespace | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getGlobalClasses | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
getAllClasses | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDiscoveredNamespaces | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
getDiscoveredClasses | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
getDiscoveredConstants | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
2 | |||
getDiscoveredFunctions | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getAll | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDiscoveredTraits | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDiscoveredInterfaces | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getClassmapSymbols | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
getNamespaceSymbolByString | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * @see \BrianHenryIE\Strauss\Pipeline\FileSymbolScanner |
4 | */ |
5 | |
6 | namespace BrianHenryIE\Strauss\Types; |
7 | |
8 | class DiscoveredSymbols |
9 | { |
10 | /** |
11 | * All discovered symbols, grouped by type, indexed by original name. |
12 | * |
13 | * @var array{T_NAME_QUALIFIED:array<string,NamespaceSymbol>, T_CONST:array<string,ConstantSymbol>, T_CLASS:array<string,ClassSymbol>} |
14 | */ |
15 | protected array $types = []; |
16 | |
17 | public function __construct() |
18 | { |
19 | $this->types = [ |
20 | T_CLASS => [], |
21 | T_CONST => [], |
22 | T_NAMESPACE => [], |
23 | T_FUNCTION => [], |
24 | T_TRAIT => [], |
25 | T_INTERFACE => [], |
26 | ]; |
27 | |
28 | $this->types[T_NAMESPACE]['\\'] = new NamespaceSymbol('\\', new \BrianHenryIE\Strauss\Files\File('')); |
29 | } |
30 | |
31 | /** |
32 | * @param DiscoveredSymbol $symbol |
33 | */ |
34 | public function add(DiscoveredSymbol $symbol): void |
35 | { |
36 | switch (get_class($symbol)) { |
37 | case NamespaceSymbol::class: |
38 | $type = T_NAMESPACE; |
39 | break; |
40 | case ConstantSymbol::class: |
41 | $type = T_CONST; |
42 | break; |
43 | case ClassSymbol::class: |
44 | $type = T_CLASS; |
45 | break; |
46 | case FunctionSymbol::class: |
47 | $type = T_FUNCTION; |
48 | break; |
49 | case InterfaceSymbol::class: |
50 | $type = T_INTERFACE; |
51 | break; |
52 | case TraitSymbol::class: |
53 | $type = T_TRAIT; |
54 | break; |
55 | default: |
56 | throw new \InvalidArgumentException('Unknown symbol type: ' . get_class($symbol)); |
57 | } |
58 | // TODO: This should merge the symbols instead of overwriting them. |
59 | $this->types[$type][$symbol->getOriginalSymbol()] = $symbol; |
60 | } |
61 | |
62 | /** |
63 | * @return DiscoveredSymbol[] |
64 | */ |
65 | public function getSymbols(): array |
66 | { |
67 | return array_merge( |
68 | array_values($this->getNamespaces()), |
69 | array_values($this->getGlobalClasses()), |
70 | array_values($this->getConstants()), |
71 | array_values($this->getDiscoveredFunctions()), |
72 | ); |
73 | } |
74 | |
75 | /** |
76 | * @return array<string, ConstantSymbol> |
77 | */ |
78 | public function getConstants() |
79 | { |
80 | return $this->types[T_CONST]; |
81 | } |
82 | |
83 | /** |
84 | * @return array<string, NamespaceSymbol> |
85 | */ |
86 | public function getNamespaces(): array |
87 | { |
88 | return $this->types[T_NAMESPACE]; |
89 | } |
90 | |
91 | public function getNamespace(string $namespace): ?NamespaceSymbol |
92 | { |
93 | return $this->types[T_NAMESPACE][$namespace] ?? null; |
94 | } |
95 | |
96 | /** |
97 | * @return array<string, ClassSymbol> |
98 | */ |
99 | public function getGlobalClasses(): array |
100 | { |
101 | return array_filter( |
102 | $this->types[T_CLASS], |
103 | fn($classSymbol) => '\\' === $classSymbol->getNamespace() |
104 | ); |
105 | } |
106 | |
107 | /** |
108 | * @return array<string, ClassSymbol> |
109 | */ |
110 | public function getAllClasses(): array |
111 | { |
112 | return $this->types[T_CLASS]; |
113 | } |
114 | |
115 | /** |
116 | * TODO: Order by longest string first. (or instead, record classnames with their namespaces) |
117 | * |
118 | * @return array<string, NamespaceSymbol> |
119 | */ |
120 | public function getDiscoveredNamespaces(?string $namespacePrefix = ''): array |
121 | { |
122 | $discoveredNamespaceReplacements = []; |
123 | |
124 | // When running subsequent times, try to discover the original namespaces. |
125 | // This is naive: it will not work where namespace replacement patterns have been used. |
126 | foreach ($this->getNamespaces() as $key => $value) { |
127 | $discoveredNamespaceReplacements[ $value->getOriginalSymbol() ] = $value; |
128 | } |
129 | |
130 | uksort($discoveredNamespaceReplacements, function ($a, $b) { |
131 | return strlen($a) <=> strlen($b); |
132 | }); |
133 | |
134 | unset($discoveredNamespaceReplacements['\\']); |
135 | |
136 | return $discoveredNamespaceReplacements; |
137 | } |
138 | |
139 | /** |
140 | * @return string[] |
141 | */ |
142 | public function getDiscoveredClasses(?string $classmapPrefix = ''): array |
143 | { |
144 | $discoveredClasses = $this->getGlobalClasses(); |
145 | |
146 | $discoveredClasses = array_filter( |
147 | array_keys($discoveredClasses), |
148 | function (string $replacement) use ($classmapPrefix) { |
149 | return empty($classmapPrefix) || ! str_starts_with($replacement, $classmapPrefix); |
150 | } |
151 | ); |
152 | |
153 | return $discoveredClasses; |
154 | } |
155 | |
156 | /** |
157 | * @return string[] |
158 | */ |
159 | public function getDiscoveredConstants(?string $constantsPrefix = ''): array |
160 | { |
161 | $discoveredConstants = $this->getConstants(); |
162 | $discoveredConstants = array_filter( |
163 | array_keys($discoveredConstants), |
164 | function (string $replacement) use ($constantsPrefix) { |
165 | return empty($constantsPrefix) || ! str_starts_with($replacement, $constantsPrefix); |
166 | } |
167 | ); |
168 | |
169 | return $discoveredConstants; |
170 | } |
171 | |
172 | public function getDiscoveredFunctions() |
173 | { |
174 | return $this->types[T_FUNCTION]; |
175 | } |
176 | |
177 | public function getAll(): array |
178 | { |
179 | return array_merge(...$this->types); |
180 | } |
181 | |
182 | public function getDiscoveredTraits(): array |
183 | { |
184 | return (array) $this->types[T_TRAIT]; |
185 | } |
186 | |
187 | public function getDiscoveredInterfaces(): array |
188 | { |
189 | return (array) $this->types[T_INTERFACE]; |
190 | } |
191 | |
192 | /** |
193 | * Get all discovered symbols that are classes, interfaces, or traits, i.e. only those that are autoloadable. |
194 | * |
195 | * @return array<DiscoveredSymbol> |
196 | */ |
197 | public function getClassmapSymbols(): array |
198 | { |
199 | return array_merge( |
200 | $this->getDiscoveredClasses(), |
201 | $this->getDiscoveredInterfaces(), |
202 | $this->getDiscoveredTraits(), |
203 | ); |
204 | } |
205 | |
206 | public function getNamespaceSymbolByString(string $namespace): ?NamespaceSymbol |
207 | { |
208 | return $this->types[T_NAMESPACE][$namespace] ?? null; |
209 | } |
210 | } |