@@ -287,29 +287,55 @@ module.exports = {
287
287
return result ;
288
288
} ,
289
289
read_types ( ) {
290
+ const MODE_UNSET = "unset" ;
291
+ const MODE_UNION = "union" ;
292
+ const MODE_INTERSECTION = "intersection" ;
293
+
290
294
const types = [ ] ;
291
- let isIntersection = false ;
295
+ let mode = MODE_UNSET ;
292
296
const type = this . read_type ( ) ;
293
297
if ( ! type ) return null ;
298
+
299
+ // we have matched a single type
294
300
types . push ( type ) ;
301
+
302
+ // is the current token a:
303
+ // - | for union type
304
+ // - & for intersection type (> php 8.1)
295
305
while ( this . token === "|" || ( this . version >= 801 && this . token === "&" ) ) {
296
- if ( this . token === "&" ) {
297
- isIntersection = true ;
298
- const nextToken = this . peek ( ) ;
306
+ const nextToken = this . peek ( ) ;
307
+
308
+ if (
309
+ nextToken === this . tok . T_ELLIPSIS ||
310
+ nextToken === this . tok . T_VARIABLE
311
+ ) {
312
+ // the next token is part of the variable (or the variable itself),
313
+ // we're not gonna match anymore types
314
+ break ;
315
+ }
316
+
317
+ if ( mode === MODE_UNSET ) {
318
+ // are we in union or intersection "mode"
319
+ mode = this . token === "|" ? MODE_UNION : MODE_INTERSECTION ;
320
+ } else {
321
+ // it is not possible to mix "modes"
299
322
if (
300
- nextToken === this . tok . T_ELLIPSIS ||
301
- nextToken === this . tok . T_VARIABLE
323
+ ( mode === MODE_UNION && this . token !== "|" ) ||
324
+ ( mode === MODE_INTERSECTION && this . token !== "&" )
302
325
) {
303
- break ;
326
+ this . raiseError (
327
+ 'Unexpect token "' + this . token + '", "|" and "&" can not be mixed'
328
+ ) ;
304
329
}
305
330
}
331
+
306
332
this . next ( ) ;
307
333
types . push ( this . read_type ( ) ) ;
308
334
}
309
335
if ( types . length === 1 ) {
310
336
return types [ 0 ] ;
311
337
} else {
312
- return isIntersection
338
+ return mode === MODE_INTERSECTION
313
339
? this . node ( "intersectiontype" ) ( types )
314
340
: this . node ( "uniontype" ) ( types ) ;
315
341
}
0 commit comments