Skip to content

Commit 3eb61df

Browse files
Support constant fetch in array key
1 parent 0a8e718 commit 3eb61df

File tree

4 files changed

+32
-4
lines changed

4 files changed

+32
-4
lines changed

src/Ast/Type/ArrayShapeItemNode.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
66
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
7+
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstFetchNode;
78
use PHPStan\PhpDocParser\Ast\Node;
89
use PHPStan\PhpDocParser\Ast\NodeAttributes;
910
use function sprintf;
@@ -13,15 +14,15 @@ class ArrayShapeItemNode implements Node
1314

1415
use NodeAttributes;
1516

16-
/** @var ConstExprIntegerNode|ConstExprStringNode|IdentifierTypeNode|null */
17+
/** @var ConstExprIntegerNode|ConstExprStringNode|ConstFetchNode|IdentifierTypeNode|null */
1718
public $keyName;
1819

1920
public bool $optional;
2021

2122
public TypeNode $valueType;
2223

2324
/**
24-
* @param ConstExprIntegerNode|ConstExprStringNode|IdentifierTypeNode|null $keyName
25+
* @param ConstExprIntegerNode|ConstExprStringNode|ConstFetchNode|IdentifierTypeNode|null $keyName
2526
*/
2627
public function __construct($keyName, bool $optional, TypeNode $valueType)
2728
{

src/Parser/TypeParser.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ private function parseArrayShapeItem(TokenIterator $tokens): Ast\Type\ArrayShape
970970

971971
/**
972972
* @phpstan-impure
973-
* @return Ast\ConstExpr\ConstExprIntegerNode|Ast\ConstExpr\ConstExprStringNode|Ast\Type\IdentifierTypeNode
973+
* @return Ast\ConstExpr\ConstExprIntegerNode|Ast\ConstExpr\ConstExprStringNode|Ast\ConstExpr\ConstFetchNode|Ast\Type\IdentifierTypeNode
974974
*/
975975
private function parseArrayShapeKey(TokenIterator $tokens)
976976
{
@@ -991,8 +991,17 @@ private function parseArrayShapeKey(TokenIterator $tokens)
991991
$tokens->next();
992992

993993
} else {
994-
$key = new Ast\Type\IdentifierTypeNode($tokens->currentTokenValue());
994+
$identifier = $tokens->currentTokenValue();
995995
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
996+
997+
if ($tokens->tryConsumeTokenType(Lexer::TOKEN_DOUBLE_COLON)) {
998+
$classConstantName = $tokens->currentTokenValue();
999+
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
1000+
1001+
$key = new Ast\ConstExpr\ConstFetchNode($identifier, $classConstantName);
1002+
} else {
1003+
$key = new Ast\Type\IdentifierTypeNode($identifier);
1004+
}
9961005
}
9971006

9981007
return $this->enrichWithAttributes(

tests/PHPStan/Ast/ToString/TypeToStringTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
77
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprNullNode;
88
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprStringNode;
9+
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstFetchNode;
910
use PHPStan\PhpDocParser\Ast\Node;
1011
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeItemNode;
1112
use PHPStan\PhpDocParser\Ast\Type\ArrayShapeNode;
@@ -75,6 +76,13 @@ public static function provideArrayCases(): Generator
7576
new ArrayShapeItemNode(new ConstExprIntegerNode('1'), false, new IdentifierTypeNode('Baz')),
7677
]),
7778
],
79+
[
80+
'array{Foo::BAR: Foo, Bar::FOO?: Bar}',
81+
ArrayShapeNode::createSealed([
82+
new ArrayShapeItemNode(new ConstFetchNode('Foo', 'BAR'), false, new IdentifierTypeNode('Foo')),
83+
new ArrayShapeItemNode(new ConstFetchNode('Bar', 'FOO'), true, new IdentifierTypeNode('Bar')),
84+
]),
85+
],
7886
['list{}', ArrayShapeNode::createSealed([], 'list')],
7987
['list{...}', ArrayShapeNode::createUnsealed([], null, 'list')],
8088
[

tests/PHPStan/Parser/TypeParserTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3041,6 +3041,16 @@ public function provideParseData(): array
30413041
new IdentifierTypeNode('MongoCollection'),
30423042
Lexer::TOKEN_OPEN_ANGLE_BRACKET,
30433043
],
3044+
[
3045+
'array{Foo::BAR: int}',
3046+
ArrayShapeNode::createSealed([
3047+
new ArrayShapeItemNode(
3048+
new ConstFetchNode('Foo', 'BAR'),
3049+
false,
3050+
new IdentifierTypeNode('int'),
3051+
),
3052+
]),
3053+
],
30443054
];
30453055
}
30463056

0 commit comments

Comments
 (0)