Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e0e5c18

Browse files
Fix parsing of [] in various cases - closes #36
* Array shapes * Generics * $this * Nullables
1 parent 1a80f73 commit e0e5c18

File tree

2 files changed

+107
-3
lines changed

2 files changed

+107
-3
lines changed

‎src/Parser/TypeParser.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,22 @@ private function parseAtomic(TokenIterator $tokens): Ast\Type\TypeNode
3737
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
3838
$type = $this->tryParseArray($tokens, $type);
3939
}
40-
4140
} elseif ($tokens->tryConsumeTokenType(Lexer::TOKEN_THIS_VARIABLE)) {
42-
return new Ast\Type\ThisTypeNode();
41+
$type = new Ast\Type\ThisTypeNode();
4342

43+
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
44+
$type = $this->tryParseArray($tokens, $type);
45+
}
4446
} else {
4547
$type = new Ast\Type\IdentifierTypeNode($tokens->currentTokenValue());
4648
$tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER);
4749

4850
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) {
4951
$type = $this->parseGeneric($tokens, $type);
5052

53+
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
54+
$type = $this->tryParseArray($tokens, $type);
55+
}
5156
} elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) {
5257
$type = $this->tryParseCallable($tokens, $type);
5358

@@ -56,6 +61,10 @@ private function parseAtomic(TokenIterator $tokens): Ast\Type\TypeNode
5661

5762
} elseif ($type->name === 'array' && $tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET) && !$tokens->isPrecededByHorizontalWhitespace()) {
5863
$type = $this->parseArrayShape($tokens, $type);
64+
65+
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
66+
$type = $this->tryParseArray($tokens, $type);
67+
}
5968
}
6069
}
6170

@@ -101,6 +110,10 @@ private function parseNullable(TokenIterator $tokens): Ast\Type\TypeNode
101110
$type = $this->parseArrayShape($tokens, $type);
102111
}
103112

113+
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
114+
$type = $this->tryParseArray($tokens, $type);
115+
}
116+
104117
return new Ast\Type\NullableTypeNode($type);
105118
}
106119

@@ -179,6 +192,10 @@ private function parseCallableReturnType(TokenIterator $tokens): Ast\Type\TypeNo
179192
}
180193
}
181194

195+
if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) {
196+
$type = $this->tryParseArray($tokens, $type);
197+
}
198+
182199
return $type;
183200
}
184201

@@ -218,7 +235,7 @@ private function tryParseArray(TokenIterator $tokens, Ast\Type\TypeNode $type):
218235
}
219236

220237

221-
private function parseArrayShape(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode
238+
private function parseArrayShape(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\ArrayShapeNode
222239
{
223240
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET);
224241
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);

‎tests/PHPStan/Parser/TypeParserTest.php

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,93 @@ public function provideParseData(): array
711711
new IdentifierTypeNode("\xA009")
712712
),
713713
],
714+
[
715+
'Collection<array-key, int>[]',
716+
new ArrayTypeNode(
717+
new GenericTypeNode(
718+
new IdentifierTypeNode('Collection'),
719+
[
720+
new IdentifierTypeNode('array-key'),
721+
new IdentifierTypeNode('int'),
722+
]
723+
)
724+
),
725+
],
726+
[
727+
'int | Collection<array-key, int>[]',
728+
new UnionTypeNode([
729+
new IdentifierTypeNode('int'),
730+
new ArrayTypeNode(
731+
new GenericTypeNode(
732+
new IdentifierTypeNode('Collection'),
733+
[
734+
new IdentifierTypeNode('array-key'),
735+
new IdentifierTypeNode('int'),
736+
]
737+
)
738+
),
739+
]),
740+
],
741+
[
742+
'array{foo: int}[]',
743+
new ArrayTypeNode(
744+
new ArrayShapeNode([
745+
new ArrayShapeItemNode(
746+
new IdentifierTypeNode('foo'),
747+
false,
748+
new IdentifierTypeNode('int')
749+
),
750+
])
751+
),
752+
],
753+
[
754+
'int | array{foo: int}[]',
755+
new UnionTypeNode([
756+
new IdentifierTypeNode('int'),
757+
new ArrayTypeNode(
758+
new ArrayShapeNode([
759+
new ArrayShapeItemNode(
760+
new IdentifierTypeNode('foo'),
761+
false,
762+
new IdentifierTypeNode('int')
763+
),
764+
])
765+
),
766+
]),
767+
],
768+
[
769+
'$this[]',
770+
new ArrayTypeNode(
771+
new ThisTypeNode()
772+
),
773+
],
774+
[
775+
'int | $this[]',
776+
new UnionTypeNode([
777+
new IdentifierTypeNode('int'),
778+
new ArrayTypeNode(
779+
new ThisTypeNode()
780+
),
781+
]),
782+
],
783+
[
784+
'callable(): int[]',
785+
new CallableTypeNode(
786+
new IdentifierTypeNode('callable'),
787+
[],
788+
new ArrayTypeNode(
789+
new IdentifierTypeNode('int')
790+
)
791+
),
792+
],
793+
[
794+
'?int[]',
795+
new NullableTypeNode(
796+
new ArrayTypeNode(
797+
new IdentifierTypeNode('int')
798+
)
799+
),
800+
],
714801
];
715802
}
716803

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /