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