@@ -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,113 @@ 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 a key/value array of the alias => namespace.
219218 *
220219 * @return array
221220 */
222- private function extractUseStatement (\ArrayIterator $ tokens )
221+ private function extractUseStatements (\ArrayIterator $ tokens )
223222 {
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 [] = '' ;
223+ $ extractedUseStatements = [];
224+ $ groupedNs = '' ;
225+ $ currentNs = '' ;
226+ $ currentAlias = null ;
227+ $ state = "start " ;
228+
229+ $ i = 0 ;
230+ while ($ tokens ->valid ()) {
231+ $ i += 1 ;
232+ $ currentToken = $ tokens ->current ();
233+ $ tokenId = is_string ($ currentToken ) ? $ currentToken : $ currentToken [0 ];
234+ $ tokenValue = is_string ($ currentToken ) ? null : $ currentToken [1 ];
235+ switch ($ state ) {
236+ case "start " :
237+ switch ($ tokenId ) {
238+ case T_STRING :
239+ case T_NS_SEPARATOR :
240+ $ currentNs .= $ tokenValue ;
241+ break ;
242+ case T_CURLY_OPEN :
243+ case '{ ' :
244+ $ state = 'grouped ' ;
245+ $ groupedNs = $ currentNs ;
246+ break ;
247+ case T_AS :
248+ $ state = 'start-alias ' ;
249+ break ;
250+ case self ::T_LITERAL_USE_SEPARATOR :
251+ case self ::T_LITERAL_END_OF_USE :
252+ $ state = 'end ' ;
253+ break ;
254+ default :
255+ break ;
256+ }
257+ break ;
258+ case "start-alias " :
259+ switch ($ tokenId ) {
260+ case T_STRING :
261+ $ currentAlias .= $ tokenValue ;
262+ break ;
263+ case self ::T_LITERAL_USE_SEPARATOR :
264+ case self ::T_LITERAL_END_OF_USE :
265+ $ state = 'end ' ;
266+ break ;
267+ default :
268+ break ;
269+ }
270+ break ;
271+ case "grouped " :
272+ switch ($ tokenId ) {
273+ case T_STRING :
274+ case T_NS_SEPARATOR :
275+ $ currentNs .= $ tokenValue ;
276+ break ;
277+ case T_AS :
278+ $ state = 'grouped-alias ' ;
279+ break ;
280+ case self ::T_LITERAL_USE_SEPARATOR :
281+ $ state = 'grouped ' ;
282+ $ extractedUseStatements [$ currentAlias ?: $ currentNs ] = $ currentNs ;
283+ $ currentNs = $ groupedNs ;
284+ $ currentAlias = null ;
285+ break ;
286+ case self ::T_LITERAL_END_OF_USE :
287+ $ state = 'end ' ;
288+ break ;
289+ default :
290+ break ;
291+ }
292+ break ;
293+ case "grouped-alias " :
294+ switch ($ tokenId ) {
295+ case T_STRING :
296+ $ currentAlias .= $ tokenValue ;
297+ break ;
298+ case self ::T_LITERAL_USE_SEPARATOR :
299+ $ state = 'grouped ' ;
300+ $ extractedUseStatements [$ currentAlias ?: $ currentNs ] = $ currentNs ;
301+ $ currentNs = $ groupedNs ;
302+ $ currentAlias = null ;
303+ break ;
304+ case self ::T_LITERAL_END_OF_USE :
305+ $ state = 'end ' ;
306+ break ;
307+ default :
308+ break ;
309+ }
231310 }
232311
233- if ($ tokens -> current ()[ 0 ] === T_STRING || $ tokens -> current ()[ 0 ] === T_NS_SEPARATOR ) {
234- $ result [ count ( $ result ) - 1 ] .= $ tokens -> current ()[ 1 ] ;
312+ if ($ state == " end " ) {
313+ break ;
235314 }
236315
237316 $ tokens ->next ();
238317 }
239318
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- }
319+ if ($ groupedNs != $ currentNs ) {
320+ $ extractedUseStatements [$ currentAlias ?: $ currentNs ] = $ currentNs ;
248321 }
249322
250- return array_reverse ($ result );
323+
324+ return $ extractedUseStatements ;
251325 }
252326}
0 commit comments