From cff97e916b8e3f0b1731046242f6074721e43de7 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 24 Apr 2023 17:06:14 +0200 Subject: [PATCH] Missing attributes for array shapes --- src/Parser/TypeParser.php | 26 +++++++++++++-- tests/PHPStan/Parser/TypeParserTest.php | 42 +++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/src/Parser/TypeParser.php b/src/Parser/TypeParser.php index 3e7f48fd..127f7c47 100644 --- a/src/Parser/TypeParser.php +++ b/src/Parser/TypeParser.php @@ -611,6 +611,8 @@ private function parseArrayShape(TokenIterator $tokens, Ast\Type\TypeNode $type, /** @phpstan-impure */ private function parseArrayShapeItem(TokenIterator $tokens): Ast\Type\ArrayShapeItemNode { + $startLine = $tokens->currentTokenLine(); + $startIndex = $tokens->currentTokenIndex(); try { $tokens->pushSavePoint(); $key = $this->parseArrayShapeKey($tokens); @@ -619,12 +621,22 @@ private function parseArrayShapeItem(TokenIterator $tokens): Ast\Type\ArrayShape $value = $this->parse($tokens); $tokens->dropSavePoint(); - return new Ast\Type\ArrayShapeItemNode($key, $optional, $value); + return $this->enrichWithAttributes( + $tokens, + new Ast\Type\ArrayShapeItemNode($key, $optional, $value), + $startLine, + $startIndex + ); } catch (ParserException $e) { $tokens->rollback(); $value = $this->parse($tokens); - return new Ast\Type\ArrayShapeItemNode(null, false, $value); + return $this->enrichWithAttributes( + $tokens, + new Ast\Type\ArrayShapeItemNode(null, false, $value), + $startLine, + $startIndex + ); } } @@ -634,6 +646,9 @@ private function parseArrayShapeItem(TokenIterator $tokens): Ast\Type\ArrayShape */ private function parseArrayShapeKey(TokenIterator $tokens) { + $startIndex = $tokens->currentTokenIndex(); + $startLine = $tokens->currentTokenLine(); + if ($tokens->isCurrentTokenType(Lexer::TOKEN_INTEGER)) { $key = new Ast\ConstExpr\ConstExprIntegerNode($tokens->currentTokenValue()); $tokens->next(); @@ -660,7 +675,12 @@ private function parseArrayShapeKey(TokenIterator $tokens) $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); } - return $key; + return $this->enrichWithAttributes( + $tokens, + $key, + $startLine, + $startIndex + ); } /** diff --git a/tests/PHPStan/Parser/TypeParserTest.php b/tests/PHPStan/Parser/TypeParserTest.php index 2b29c4a4..663daf38 100644 --- a/tests/PHPStan/Parser/TypeParserTest.php +++ b/tests/PHPStan/Parser/TypeParserTest.php @@ -2069,6 +2069,48 @@ static function (TypeNode $typeNode): TypeNode { ], ], ]; + + yield [ + 'array{foo: int}', + [ + [ + static function (TypeNode $typeNode): TypeNode { + return $typeNode; + }, + 'array{foo: int}', + 1, + 1, + 0, + 6, + ], + [ + static function (ArrayShapeNode $typeNode): TypeNode { + return $typeNode->items[0]; + }, + 'foo: int', + 1, + 1, + 2, + 5, + ], + ], + ]; + + yield [ + 'array{}', + [ + [ + static function (TypeNode $typeNode): TypeNode { + return $typeNode; + }, + 'array{}', + 1, + 1, + 0, + 2, + ], + ], + ]; } /**