@@ -80,7 +80,7 @@ private function parseAtomic(TokenIterator $tokens): Ast\Type\TypeNode
8080 $ tokens ->consumeTokenType (Lexer::TOKEN_CLOSE_PARENTHESES );
8181
8282 if ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET )) {
83- return $ this ->tryParseArray ($ tokens , $ type );
83+ return $ this ->tryParseArrayOrOffsetAccess ($ tokens , $ type );
8484 }
8585
8686 return $ type ;
@@ -90,7 +90,7 @@ private function parseAtomic(TokenIterator $tokens): Ast\Type\TypeNode
9090 $ type = new Ast \Type \ThisTypeNode ();
9191
9292 if ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET )) {
93- return $ this ->tryParseArray ($ tokens , $ type );
93+ return $ this ->tryParseArrayOrOffsetAccess ($ tokens , $ type );
9494 }
9595
9696 return $ type ;
@@ -115,19 +115,19 @@ private function parseAtomic(TokenIterator $tokens): Ast\Type\TypeNode
115115 $ type = $ this ->parseGeneric ($ tokens , $ type );
116116
117117 if ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET )) {
118- $ type = $ this ->tryParseArray ($ tokens , $ type );
118+ $ type = $ this ->tryParseArrayOrOffsetAccess ($ tokens , $ type );
119119 }
120120 } elseif ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_PARENTHESES )) {
121121 $ type = $ this ->tryParseCallable ($ tokens , $ type );
122122
123123 } elseif ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET )) {
124- $ type = $ this ->tryParseArray ($ tokens , $ type );
124+ $ type = $ this ->tryParseArrayOrOffsetAccess ($ tokens , $ type );
125125
126126 } elseif ($ type ->name === 'array ' && $ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_CURLY_BRACKET ) && !$ tokens ->isPrecededByHorizontalWhitespace ()) {
127127 $ type = $ this ->parseArrayShape ($ tokens , $ type );
128128
129129 if ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET )) {
130- $ type = $ this ->tryParseArray ($ tokens , $ type );
130+ $ type = $ this ->tryParseArrayOrOffsetAccess ($ tokens , $ type );
131131 }
132132 }
133133
@@ -293,7 +293,7 @@ private function parseNullable(TokenIterator $tokens): Ast\Type\TypeNode
293293 }
294294
295295 if ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET )) {
296- $ type = $ this ->tryParseArray ($ tokens , $ type );
296+ $ type = $ this ->tryParseArrayOrOffsetAccess ($ tokens , $ type );
297297 }
298298
299299 return new Ast \Type \NullableTypeNode ($ type );
@@ -427,7 +427,7 @@ private function parseCallableReturnType(TokenIterator $tokens): Ast\Type\TypeNo
427427 }
428428
429429 if ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET )) {
430- $ type = $ this ->tryParseArray ($ tokens , $ type );
430+ $ type = $ this ->tryParseArrayOrOffsetAccess ($ tokens , $ type );
431431 }
432432
433433 return $ type ;
@@ -452,15 +452,25 @@ private function tryParseCallable(TokenIterator $tokens, Ast\Type\IdentifierType
452452
453453
454454 /** @phpstan-impure */
455- private function tryParseArray (TokenIterator $ tokens , Ast \Type \TypeNode $ type ): Ast \Type \TypeNode
455+ private function tryParseArrayOrOffsetAccess (TokenIterator $ tokens , Ast \Type \TypeNode $ type ): Ast \Type \TypeNode
456456 {
457457 try {
458458 while ($ tokens ->isCurrentTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET )) {
459459 $ tokens ->pushSavePoint ();
460+
461+ $ canBeOffsetAccessType = !$ tokens ->isPrecededByHorizontalWhitespace ();
460462 $ tokens ->consumeTokenType (Lexer::TOKEN_OPEN_SQUARE_BRACKET );
461- $ tokens ->consumeTokenType (Lexer::TOKEN_CLOSE_SQUARE_BRACKET );
462- $ tokens ->dropSavePoint ();
463- $ type = new Ast \Type \ArrayTypeNode ($ type );
463+
464+ if ($ canBeOffsetAccessType && !$ tokens ->isCurrentTokenType (Lexer::TOKEN_CLOSE_SQUARE_BRACKET )) {
465+ $ offset = $ this ->parse ($ tokens );
466+ $ tokens ->consumeTokenType (Lexer::TOKEN_CLOSE_SQUARE_BRACKET );
467+ $ tokens ->dropSavePoint ();
468+ $ type = new Ast \Type \OffsetAccessTypeNode ($ type , $ offset );
469+ } else {
470+ $ tokens ->consumeTokenType (Lexer::TOKEN_CLOSE_SQUARE_BRACKET );
471+ $ tokens ->dropSavePoint ();
472+ $ type = new Ast \Type \ArrayTypeNode ($ type );
473+ }
464474 }
465475
466476 } catch (ParserException $ e ) {
0 commit comments