Skip to content

Commit 97a0114

Browse files
committed
Array shapes - support single-quoted and double-quoted strings
1 parent 9285b87 commit 97a0114

File tree

3 files changed

+48
-15
lines changed

3 files changed

+48
-15
lines changed

src/Ast/Type/ArrayShapeItemNode.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
namespace PHPStan\PhpDocParser\Ast\Type;
44

55
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
6+
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
67

78
class ArrayShapeItemNode implements TypeNode
89
{
910

10-
/** @var ConstExprIntegerNode|IdentifierTypeNode|null */
11+
/** @var ConstExprIntegerNode|ConstExprStringNode|IdentifierTypeNode|null */
1112
public $keyName;
1213

1314
/** @var bool */
@@ -17,7 +18,7 @@ class ArrayShapeItemNode implements TypeNode
1718
public $valueType;
1819

1920
/**
20-
* @param ConstExprIntegerNode|IdentifierTypeNode|null $keyName
21+
* @param ConstExprIntegerNode|ConstExprStringNode|IdentifierTypeNode|null $keyName
2122
*/
2223
public function __construct($keyName, bool $optional, TypeNode $valueType)
2324
{

src/Parser/TypeParser.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,14 +280,22 @@ private function parseArrayShapeItem(TokenIterator $tokens): Ast\Type\ArrayShape
280280
}
281281

282282
/**
283-
* @return Ast\ConstExpr\ConstExprIntegerNode|Ast\Type\IdentifierTypeNode
283+
* @return Ast\ConstExpr\ConstExprIntegerNode|Ast\ConstExpr\ConstExprStringNode|Ast\Type\IdentifierTypeNode
284284
*/
285285
private function parseArrayShapeKey(TokenIterator $tokens)
286286
{
287287
if ($tokens->isCurrentTokenType(Lexer::TOKEN_INTEGER)) {
288288
$key = new Ast\ConstExpr\ConstExprIntegerNode($tokens->currentTokenValue());
289289
$tokens->next();
290290

291+
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_SINGLE_QUOTED_STRING)) {
292+
$key = new Ast\ConstExpr\ConstExprStringNode(trim($tokens->currentTokenValue(), "'"));
293+
$tokens->next();
294+
295+
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_QUOTED_STRING)) {
296+
$key = new Ast\ConstExpr\ConstExprStringNode(trim($tokens->currentTokenValue(), '"'));
297+
$tokens->next();
298+
291299
} else {
292300
$key = new Ast\Type\IdentifierTypeNode($tokens->currentTokenValue());
293301
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);

tests/PHPStan/Parser/TypeParserTest.php

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace PHPStan\PhpDocParser\Parser;
44

55
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
6+
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
67
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeItemNode;
78
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeNode;
89
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
@@ -51,6 +52,7 @@ public function testParse(string $input, $expectedResult, int $nextTokenType = L
5152
$typeNode = $this->typeParser->parse($tokens);
5253

5354
$this->assertSame((string) $expectedResult, (string) $typeNode);
55+
$this->assertInstanceOf(get_class($expectedResult), $typeNode);
5456
$this->assertEquals($expectedResult, $typeNode);
5557
$this->assertSame($nextTokenType, $tokens->currentTokenType());
5658
}
@@ -449,21 +451,43 @@ public function provideParseData(): array
449451
],
450452
[
451453
'array{"a": int}',
452-
new \PHPStan\PhpDocParser\Parser\ParserException(
453-
'"a"',
454-
Lexer::TOKEN_DOUBLE_QUOTED_STRING,
455-
6,
456-
Lexer::TOKEN_IDENTIFIER
457-
),
454+
new ArrayShapeNode([
455+
new ArrayShapeItemNode(
456+
new ConstExprStringNode('a'),
457+
false,
458+
new IdentifierTypeNode('int')
459+
),
460+
]),
458461
],
459462
[
460463
'array{\'a\': int}',
461-
new \PHPStan\PhpDocParser\Parser\ParserException(
462-
'\'a\'',
463-
Lexer::TOKEN_SINGLE_QUOTED_STRING,
464-
6,
465-
Lexer::TOKEN_IDENTIFIER
466-
),
464+
new ArrayShapeNode([
465+
new ArrayShapeItemNode(
466+
new ConstExprStringNode('a'),
467+
false,
468+
new IdentifierTypeNode('int')
469+
),
470+
]),
471+
],
472+
[
473+
'array{\'$ref\': int}',
474+
new ArrayShapeNode([
475+
new ArrayShapeItemNode(
476+
new ConstExprStringNode('$ref'),
477+
false,
478+
new IdentifierTypeNode('int')
479+
),
480+
]),
481+
],
482+
[
483+
'array{"$ref": int}',
484+
new ArrayShapeNode([
485+
new ArrayShapeItemNode(
486+
new ConstExprStringNode('$ref'),
487+
false,
488+
new IdentifierTypeNode('int')
489+
),
490+
]),
467491
],
468492
[
469493
'array{

0 commit comments

Comments
 (0)