@@ -16,7 +16,7 @@ class Index implements ReadableIndex, \Serializable
1616
1717 /**
1818 * An associative array that maps splitted fully qualified symbol names
19- * to definitions, eg :
19+ * to member definitions, eg :
2020 * [
2121 * 'Psr' => [
2222 * '\Log' => [
@@ -29,7 +29,23 @@ class Index implements ReadableIndex, \Serializable
2929 *
3030 * @var array
3131 */
32- private $ definitions = [];
32+ private $ memberDefinitions = [];
33+
34+ /**
35+ * An associative array that maps splitted fully qualified symbol names
36+ * to non member definitions, eg :
37+ * [
38+ * 'Psr' => [
39+ * '\Log' => [
40+ * '\LoggerInterface' => $definition,
41+ * ],
42+ * ],
43+ * ]
44+ *
45+ * @var array
46+ */
47+ private $ nonMemberDefinitions = [];
48+
3349
3450 /**
3551 * An associative array that maps fully qualified symbol names
@@ -108,7 +124,8 @@ public function getDefinitions(): \Generator
108124 // }
109125 // }
110126
111- yield from $ this ->generateDefinitionsRecursively ($ this ->definitions );
127+ yield from $ this ->yieldDefinitionsRecursively ($ this ->memberDefinitions );
128+ yield from $ this ->yieldDefinitionsRecursively ($ this ->nonMemberDefinitions );
112129 }
113130
114131 /**
@@ -124,12 +141,20 @@ public function getDefinitionsForFqn(string $fqn): \Generator
124141 // }
125142
126143 $ parts = $ this ->splitFqn ($ fqn );
127- $ result = $ this ->getIndexValue ($ parts , $ this ->definitions );
144+ $ result = $ this ->getIndexValue ($ parts , $ this ->memberDefinitions );
128145
129146 if ($ result instanceof Definition) {
130- yield $ fqn => $ definition ;
147+ yield $ fqn => $ result ;
131148 } elseif (is_array ($ result )) {
132- yield from $ this ->generateDefinitionsRecursively ($ result , $ fqn );
149+ yield from $ this ->yieldDefinitionsRecursively ($ result , $ fqn );
150+ } else {
151+ $ result = $ this ->getIndexValue ($ parts , $ this ->nonMemberDefinitions );
152+
153+ if ($ result instanceof Definition) {
154+ yield $ fqn => $ result ;
155+ } elseif (is_array ($ result )) {
156+ yield from $ this ->yieldDefinitionsRecursively ($ result , $ fqn );
157+ }
133158 }
134159 }
135160
@@ -156,9 +181,18 @@ public function getDefinition(string $fqn, bool $globalFallback = false)
156181 // }
157182
158183 $ parts = $ this ->splitFqn ($ fqn );
159- $ result = $ this ->getIndexValue ($ parts , $ this ->definitions );
184+ $ result = $ this ->getIndexValue ($ parts , $ this ->memberDefinitions );
160185
161- return $ result instanceof Definition ?? null ;
186+ if ($ result instanceof Definition) {
187+ return $ result ;
188+ }
189+
190+ $ result = $ this ->getIndexValue ($ parts , $ this ->nonMemberDefinitions );
191+
192+ return $ result instanceof Definition
193+ ? $ result
194+ : null
195+ ;
162196 }
163197
164198 /**
@@ -178,7 +212,12 @@ public function setDefinition(string $fqn, Definition $definition)
178212 // $this->fqnDefinitions[$namespacedFqn][$fqn] = $definition;
179213
180214 $ parts = $ this ->splitFqn ($ fqn );
181- $ this ->indexDefinition (0 , $ parts , $ this ->definitions , $ definition );
215+
216+ if ($ definition ->isMember ) {
217+ $ this ->indexDefinition (0 , $ parts , $ this ->memberDefinitions , $ definition );
218+ } else {
219+ $ this ->indexDefinition (0 , $ parts , $ this ->nonMemberDefinitions , $ definition );
220+ }
182221
183222 $ this ->emit ('definition-added ' );
184223 }
@@ -202,7 +241,10 @@ public function removeDefinition(string $fqn)
202241 // }
203242
204243 $ parts = $ this ->splitFqn ($ fqn );
205- $ this ->removeIndexedDefinition (0 , $ parts , $ this ->definitions );
244+
245+ if (true !== $ this ->removeIndexedDefinition (0 , $ parts , $ this ->memberDefinitions )) {
246+ $ this ->removeIndexedDefinition (0 , $ parts , $ this ->nonMemberDefinitions );
247+ }
206248
207249 unset($ this ->references [$ fqn ]);
208250 }
@@ -287,7 +329,8 @@ public function unserialize($serialized)
287329 public function serialize ()
288330 {
289331 return serialize ([
290- 'definitions ' => $ this ->definitions ,
332+ 'memberDefinitions ' => $ this ->memberDefinitions ,
333+ 'nonMemberDefinitions ' => $ this ->nonMemberDefinitions ,
291334 'references ' => $ this ->references ,
292335 'complete ' => $ this ->complete ,
293336 'staticComplete ' => $ this ->staticComplete
@@ -318,14 +361,13 @@ public function serialize()
318361 * @param string $prefix (optional)
319362 * @return \Generator
320363 */
321- private function generateDefinitionsRecursively (array &$ storage , string $ prefix = '' ): \Generator
364+ private function yieldDefinitionsRecursively (array &$ storage , string $ prefix = '' ): \Generator
322365 {
323366 foreach ($ storage as $ key => $ value ) {
324- $ prefix .= $ key ;
325367 if (!is_array ($ value )) {
326- yield $ prefix => $ value ;
368+ yield sprintf ( ' %s%s ' , $ prefix, $ key ) => $ value ;
327369 } else {
328- yield from generateDefinitionsRecursively ($ value , $ prefix );
370+ yield from $ this -> yieldDefinitionsRecursively ($ value , sprintf ( ' %s%s ' , $ prefix, $ key ) );
329371 }
330372 }
331373 }
@@ -346,7 +388,10 @@ private function splitFqn(string $fqn): array
346388
347389 // write back the backslach prefix to the first part if it was present
348390 if ('' === $ parts [0 ]) {
349- $ parts = array_slice ($ parts , 1 );
391+ if (count ($ parts ) > 1 ) {
392+ $ parts = array_slice ($ parts , 1 );
393+ }
394+
350395 $ parts [0 ] = sprintf ('\\%s ' , $ parts [0 ]);
351396 }
352397
@@ -394,7 +439,13 @@ private function getIndexValue(array $parts, array &$storage)
394439 return $ storage [$ part ];
395440 }
396441
397- return getIndexValue ($ parts , $ storage [$ part ]);
442+ if (!is_array ($ storage [$ part ]) && count ($ parts ) > 0 ) {
443+ // we're looking for a member definition in the non member index,
444+ // no matches can be found.
445+ return null ;
446+ }
447+
448+ return $ this ->getIndexValue ($ parts , $ storage [$ part ]);
398449 }
399450
400451 /**
@@ -420,6 +471,12 @@ private function indexDefinition(int $level, array $parts, array &$storage, Defi
420471 $ storage [$ part ] = [];
421472 }
422473
474+ if (!is_array ($ storage [$ part ])) {
475+ // it's a non member definition, we can't add it to the member
476+ // definitions index
477+ return ;
478+ }
479+
423480 $ this ->indexDefinition ($ level + 1 , $ parts , $ storage [$ part ], $ definition );
424481 }
425482
@@ -434,6 +491,7 @@ private function indexDefinition(int $level, array $parts, array &$storage, Defi
434491 * @param array $parts The splitted FQN
435492 * @param array &$storage The current array in which to remove data
436493 * @param array &$rootStorage The root storage array
494+ * @return boolean|null True when the definition has been found and removed, null otherwise.
437495 */
438496 private function removeIndexedDefinition (int $ level , array $ parts , array &$ storage , &$ rootStorage )
439497 {
@@ -446,16 +504,16 @@ private function removeIndexedDefinition(int $level, array $parts, array &$stora
446504 if (0 === $ level ) {
447505 // we're at root level, no need to check for parents
448506 // w/o children
449- return ;
507+ return true ;
450508 }
451509
452510 array_pop ($ parts );
453511 // parse again the definition tree to see if the parent
454512 // can be removed too if it has no more children
455- removeIndexedDefinition (0 , $ parts , $ rootStorage , $ rootStorage );
513+ return $ this -> removeIndexedDefinition (0 , $ parts , $ rootStorage , $ rootStorage );
456514 }
457515 } else {
458- removeIndexedDefinition ($ level + 1 , $ parts , $ storage [$ part ], $ rootStorage );
516+ return $ this -> removeIndexedDefinition ($ level + 1 , $ parts , $ storage [$ part ], $ rootStorage );
459517 }
460518 }
461519}
0 commit comments