@@ -16,36 +16,21 @@ class Index implements ReadableIndex, \Serializable
1616
1717 /**
1818 * An associative array that maps splitted fully qualified symbol names
19- * to member definitions, eg :
19+ * to definitions, eg :
2020 * [
2121 * 'Psr' => [
2222 * '\Log' => [
2323 * '\LoggerInterface' => [
24- * '->log()' => $definition,
24+ * '' => $def1, // definition for 'Psr\Log\LoggerInterface' which is non-member
25+ * '->log()' => $def2, // definition for 'Psr\Log\LoggerInterface->log()' which is a member definition
2526 * ],
2627 * ],
2728 * ],
2829 * ]
2930 *
3031 * @var array
3132 */
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-
33+ private $ definitions = [];
4934
5035 /**
5136 * An associative array that maps fully qualified symbol names
@@ -124,8 +109,7 @@ public function getDefinitions(): \Generator
124109 // }
125110 // }
126111
127- yield from $ this ->yieldDefinitionsRecursively ($ this ->memberDefinitions );
128- yield from $ this ->yieldDefinitionsRecursively ($ this ->nonMemberDefinitions );
112+ yield from $ this ->yieldDefinitionsRecursively ($ this ->definitions );
129113 }
130114
131115 /**
@@ -141,20 +125,18 @@ public function getDefinitionsForFqn(string $fqn): \Generator
141125 // }
142126
143127 $ parts = $ this ->splitFqn ($ fqn );
144- $ result = $ this ->getIndexValue ($ parts , $ this ->memberDefinitions );
128+ if ('' === end ($ parts )) {
129+ // we want to return all the definitions in the given FQN, not only
130+ // the one matching exactly the FQN.
131+ array_pop ($ parts );
132+ }
133+
134+ $ result = $ this ->getIndexValue ($ parts , $ this ->definitions );
145135
146136 if ($ result instanceof Definition) {
147137 yield $ fqn => $ result ;
148138 } elseif (is_array ($ result )) {
149139 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- }
158140 }
159141 }
160142
@@ -181,18 +163,23 @@ public function getDefinition(string $fqn, bool $globalFallback = false)
181163 // }
182164
183165 $ parts = $ this ->splitFqn ($ fqn );
184- $ result = $ this ->getIndexValue ($ parts , $ this ->memberDefinitions );
166+ $ result = $ this ->getIndexValue ($ parts , $ this ->definitions );
185167
186168 if ($ result instanceof Definition) {
187169 return $ result ;
188170 }
189171
190- $ result = $ this ->getIndexValue ($ parts , $ this ->nonMemberDefinitions );
172+ if ($ globalFallback ) {
173+ $ parts = explode ('\\' , $ fqn );
174+ $ fqn = end ($ parts );
191175
192- return $ result instanceof Definition
193- ? $ result
194- : null
195- ;
176+ return $ this ->getDefinition ($ fqn );
177+ }
178+
179+ // return $result instanceof Definition
180+ // ? $result
181+ // : null
182+ // ;
196183 }
197184
198185 /**
@@ -212,12 +199,7 @@ public function setDefinition(string $fqn, Definition $definition)
212199 // $this->fqnDefinitions[$namespacedFqn][$fqn] = $definition;
213200
214201 $ parts = $ this ->splitFqn ($ fqn );
215-
216- if ($ definition ->isMember ) {
217- $ this ->indexDefinition (0 , $ parts , $ this ->memberDefinitions , $ definition );
218- } else {
219- $ this ->indexDefinition (0 , $ parts , $ this ->nonMemberDefinitions , $ definition );
220- }
202+ $ this ->indexDefinition (0 , $ parts , $ this ->definitions , $ definition );
221203
222204 $ this ->emit ('definition-added ' );
223205 }
@@ -242,9 +224,7 @@ public function removeDefinition(string $fqn)
242224
243225 $ parts = $ this ->splitFqn ($ fqn );
244226
245- if (true !== $ this ->removeIndexedDefinition (0 , $ parts , $ this ->memberDefinitions )) {
246- $ this ->removeIndexedDefinition (0 , $ parts , $ this ->nonMemberDefinitions );
247- }
227+ $ this ->removeIndexedDefinition (0 , $ parts , $ this ->definitions );
248228
249229 unset($ this ->references [$ fqn ]);
250230 }
@@ -317,6 +297,14 @@ public function unserialize($serialized)
317297 {
318298 $ data = unserialize ($ serialized );
319299
300+ if (isset ($ data ['definitions ' ])) {
301+ foreach ($ data ['definitions ' ] as $ fqn => $ definition ) {
302+ $ this ->setDefinition ($ fqn , $ definition );
303+ }
304+
305+ unset($ data ['definitions ' ]);
306+ }
307+
320308 foreach ($ data as $ prop => $ val ) {
321309 $ this ->$ prop = $ val ;
322310 }
@@ -329,8 +317,7 @@ public function unserialize($serialized)
329317 public function serialize ()
330318 {
331319 return serialize ([
332- 'memberDefinitions ' => $ this ->memberDefinitions ,
333- 'nonMemberDefinitions ' => $ this ->nonMemberDefinitions ,
320+ 'definitions ' => iterator_to_array ($ this ->getDefinitions (), true ),
334321 'references ' => $ this ->references ,
335322 'complete ' => $ this ->complete ,
336323 'staticComplete ' => $ this ->staticComplete
@@ -401,10 +388,12 @@ private function splitFqn(string $fqn): array
401388 }
402389
403390 // split the last part in 2 parts at the operator
391+ $ hasOperator = false ;
404392 $ lastPart = end ($ parts );
405393 foreach ([':: ' , '-> ' ] as $ operator ) {
406394 $ endParts = explode ($ operator , $ lastPart );
407395 if (count ($ endParts ) > 1 ) {
396+ $ hasOperator = true ;
408397 // replace the last part by its pieces
409398 array_pop ($ parts );
410399 $ parts [] = $ endParts [0 ];
@@ -413,6 +402,16 @@ private function splitFqn(string $fqn): array
413402 }
414403 }
415404
405+ if (!$ hasOperator ) {
406+ // add an empty part to store the non-member definition to avoid
407+ // definition collisions in the index array, eg
408+ // 'Psr\Log\LoggerInterface' will be stored at
409+ // ['Psr']['\Log']['\LoggerInterface'][''] to be able to also store
410+ // member definitions, ie 'Psr\Log\LoggerInterface->log()' will be
411+ // stored at ['Psr']['\Log']['\LoggerInterface']['->log()']
412+ $ parts [] = '' ;
413+ }
414+
416415 return $ parts ;
417416 }
418417
@@ -439,12 +438,6 @@ private function getIndexValue(array $parts, array &$storage)
439438 return $ storage [$ part ];
440439 }
441440
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-
448441 return $ this ->getIndexValue ($ parts , $ storage [$ part ]);
449442 }
450443
@@ -471,12 +464,6 @@ private function indexDefinition(int $level, array $parts, array &$storage, Defi
471464 $ storage [$ part ] = [];
472465 }
473466
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-
480467 $ this ->indexDefinition ($ level + 1 , $ parts , $ storage [$ part ], $ definition );
481468 }
482469
@@ -491,7 +478,6 @@ private function indexDefinition(int $level, array $parts, array &$storage, Defi
491478 * @param array $parts The splitted FQN
492479 * @param array &$storage The current array in which to remove data
493480 * @param array &$rootStorage The root storage array
494- * @return boolean|null True when the definition has been found and removed, null otherwise.
495481 */
496482 private function removeIndexedDefinition (int $ level , array $ parts , array &$ storage , &$ rootStorage )
497483 {
@@ -504,16 +490,16 @@ private function removeIndexedDefinition(int $level, array $parts, array &$stora
504490 if (0 === $ level ) {
505491 // we're at root level, no need to check for parents
506492 // w/o children
507- return true ;
493+ return ;
508494 }
509495
510496 array_pop ($ parts );
511497 // parse again the definition tree to see if the parent
512498 // can be removed too if it has no more children
513- return $ this ->removeIndexedDefinition (0 , $ parts , $ rootStorage , $ rootStorage );
499+ $ this ->removeIndexedDefinition (0 , $ parts , $ rootStorage , $ rootStorage );
514500 }
515501 } else {
516- return $ this ->removeIndexedDefinition ($ level + 1 , $ parts , $ storage [$ part ], $ rootStorage );
502+ $ this ->removeIndexedDefinition ($ level + 1 , $ parts , $ storage [$ part ], $ rootStorage );
517503 }
518504 }
519505}
0 commit comments