@@ -193,8 +193,7 @@ private function parseUseStatement(\ArrayIterator $tokens)
193193 while ($ continue ) {
194194 $ this ->skipToNextStringOrNamespaceSeparator ($ tokens );
195195
196- list ($ alias , $ fqnn ) = $ this ->extractUseStatement ($ tokens );
197- $ uses [$ alias ] = $ fqnn ;
196+ $ uses = array_merge ($ uses , $ this ->extractUseStatements ($ tokens ));
198197 if ($ tokens ->current ()[0 ] === self ::T_LITERAL_END_OF_USE ) {
199198 $ continue = false ;
200199 }
@@ -215,38 +214,114 @@ private function skipToNextStringOrNamespaceSeparator(\ArrayIterator $tokens)
215214
216215 /**
217216 * Deduce the namespace name and alias of an import when we are at the T_USE token or have not reached the end of
218- * a USE statement yet.
217+ * a USE statement yet. This will return an array of tuples where the element is the full namespace and the second is an
218+ * optional alias.
219219 *
220220 * @return array
221221 */
222- private function extractUseStatement (\ArrayIterator $ tokens )
222+ private function extractUseStatements (\ArrayIterator $ tokens )
223223 {
224- $ result = ['' ];
225- while ($ tokens ->valid ()
226- && ($ tokens ->current ()[0 ] !== self ::T_LITERAL_USE_SEPARATOR )
227- && ($ tokens ->current ()[0 ] !== self ::T_LITERAL_END_OF_USE )
228- ) {
229- if ($ tokens ->current ()[0 ] === T_AS ) {
230- $ result [] = '' ;
224+ $ extractedUseStatements = [];
225+ $ groupedNs = '' ;
226+ $ currentNs = '' ;
227+ $ currentAlias = null ;
228+ $ state = "start " ;
229+
230+ $ i = 0 ;
231+ while ($ tokens ->valid ()) {
232+ $ i += 1 ;
233+ $ currentToken = $ tokens ->current ();
234+ $ tokenId = is_string ($ currentToken ) ? $ currentToken : $ currentToken [0 ];
235+ $ tokenValue = is_string ($ currentToken ) ? null : $ currentToken [1 ];
236+ switch ($ state ) {
237+ case "start " :
238+ switch ($ tokenId ) {
239+ case T_STRING :
240+ case T_NS_SEPARATOR :
241+ $ currentNs .= $ tokenValue ;
242+ break ;
243+ case T_CURLY_OPEN :
244+ case '{ ' :
245+ $ state = 'grouped ' ;
246+ $ groupedNs = $ currentNs ;
247+ break ;
248+ case T_AS :
249+ $ state = 'start-alias ' ;
250+ break ;
251+ case self ::T_LITERAL_USE_SEPARATOR :
252+ case self ::T_LITERAL_END_OF_USE :
253+ $ state = 'end ' ;
254+ break ;
255+ default :
256+ break ;
257+ }
258+ break ;
259+ case "start-alias " :
260+ switch ($ tokenId ) {
261+ case T_STRING :
262+ $ currentAlias .= $ tokenValue ;
263+ break ;
264+ case self ::T_LITERAL_USE_SEPARATOR :
265+ case self ::T_LITERAL_END_OF_USE :
266+ $ state = 'end ' ;
267+ break ;
268+ default :
269+ break ;
270+ }
271+ break ;
272+ case "grouped " :
273+ switch ($ tokenId ) {
274+ case T_STRING :
275+ case T_NS_SEPARATOR :
276+ $ currentNs .= $ tokenValue ;
277+ break ;
278+ case T_AS :
279+ $ state = 'grouped-alias ' ;
280+ break ;
281+ case self ::T_LITERAL_USE_SEPARATOR :
282+ $ state = 'grouped ' ;
283+ $ extractedUseStatements [$ currentAlias ?: $ currentNs ] = $ currentNs ;
284+ $ currentNs = $ groupedNs ;
285+ $ currentAlias = null ;
286+ break ;
287+ case self ::T_LITERAL_END_OF_USE :
288+ $ state = 'end ' ;
289+ break ;
290+ default :
291+ break ;
292+ }
293+ break ;
294+ case "grouped-alias " :
295+ switch ($ tokenId ) {
296+ case T_STRING :
297+ $ currentAlias .= $ tokenValue ;
298+ break ;
299+ case self ::T_LITERAL_USE_SEPARATOR :
300+ $ state = 'grouped ' ;
301+ $ extractedUseStatements [$ currentAlias ?: $ currentNs ] = $ currentNs ;
302+ $ currentNs = $ groupedNs ;
303+ $ currentAlias = null ;
304+ break ;
305+ case self ::T_LITERAL_END_OF_USE :
306+ $ state = 'end ' ;
307+ break ;
308+ default :
309+ break ;
310+ }
231311 }
232312
233- if ($ tokens -> current ()[ 0 ] === T_STRING || $ tokens -> current ()[ 0 ] === T_NS_SEPARATOR ) {
234- $ result [ count ( $ result ) - 1 ] .= $ tokens -> current ()[ 1 ] ;
313+ if ($ state == " end " ) {
314+ break ;
235315 }
236316
237317 $ tokens ->next ();
238318 }
239319
240- if (count ($ result ) === 1 ) {
241- $ backslashPos = strrpos ($ result [0 ], '\\' );
242-
243- if (false !== $ backslashPos ) {
244- $ result [] = substr ($ result [0 ], $ backslashPos + 1 );
245- } else {
246- $ result [] = $ result [0 ];
247- }
320+ if ($ groupedNs != $ currentNs ) {
321+ $ extractedUseStatements [$ currentAlias ?: $ currentNs ] = $ currentNs ;
248322 }
249323
250- return array_reverse ($ result );
324+
325+ return $ extractedUseStatements ;
251326 }
252327}
0 commit comments