@@ -193,8 +193,7 @@ private function parseUseStatement(\ArrayIterator $tokens)
193
193
while ($ continue ) {
194
194
$ this ->skipToNextStringOrNamespaceSeparator ($ tokens );
195
195
196
- list ($ alias , $ fqnn ) = $ this ->extractUseStatement ($ tokens );
197
- $ uses [$ alias ] = $ fqnn ;
196
+ $ uses = array_merge ($ uses , $ this ->extractUseStatements ($ tokens ));
198
197
if ($ tokens ->current ()[0 ] === self ::T_LITERAL_END_OF_USE ) {
199
198
$ continue = false ;
200
199
}
@@ -215,38 +214,114 @@ private function skipToNextStringOrNamespaceSeparator(\ArrayIterator $tokens)
215
214
216
215
/**
217
216
* 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.
219
219
*
220
220
* @return array
221
221
*/
222
- private function extractUseStatement (\ArrayIterator $ tokens )
222
+ private function extractUseStatements (\ArrayIterator $ tokens )
223
223
{
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
+ }
231
311
}
232
312
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 ;
235
315
}
236
316
237
317
$ tokens ->next ();
238
318
}
239
319
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 ;
248
322
}
249
323
250
- return array_reverse ($ result );
324
+
325
+ return $ extractedUseStatements ;
251
326
}
252
327
}
0 commit comments