Skip to content

Commit c089469

Browse files
rvanvelzenondrejmirtes
authored andcommitted
Support multiline callable syntax
Closes #46. Tests are basically copied and modified from #44
1 parent ad95bff commit c089469

File tree

3 files changed

+185
-0
lines changed

3 files changed

+185
-0
lines changed

src/Parser/TypeParser.php

+7
Original file line numberDiff line numberDiff line change
@@ -240,12 +240,19 @@ public function parseGeneric(TokenIterator $tokens, Ast\Type\IdentifierTypeNode
240240
private function parseCallable(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $identifier): Ast\Type\TypeNode
241241
{
242242
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES);
243+
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
243244

244245
$parameters = [];
245246
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) {
246247
$parameters[] = $this->parseCallableParameter($tokens);
248+
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
247249
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) {
250+
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
251+
if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) {
252+
break;
253+
}
248254
$parameters[] = $this->parseCallableParameter($tokens);
255+
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
249256
}
250257
}
251258

tests/PHPStan/Parser/PhpDocParserTest.php

+83
Original file line numberDiff line numberDiff line change
@@ -3492,6 +3492,89 @@ public function provideRealWorldExampleData(): Iterator
34923492
),
34933493
]),
34943494
];
3495+
3496+
yield [
3497+
'multiline callable types',
3498+
'/**' . PHP_EOL .
3499+
' * @param callable(' . PHP_EOL .
3500+
' * A, B' . PHP_EOL .
3501+
' * ): void $foo' . PHP_EOL .
3502+
' */',
3503+
new PhpDocNode([
3504+
new PhpDocTagNode(
3505+
'@param',
3506+
new ParamTagValueNode(
3507+
new CallableTypeNode(
3508+
new IdentifierTypeNode('callable'),
3509+
[
3510+
new CallableTypeParameterNode(new IdentifierTypeNode('A'), false, false, '', false),
3511+
new CallableTypeParameterNode(new IdentifierTypeNode('B'), false, false, '', false),
3512+
],
3513+
new IdentifierTypeNode('void')
3514+
),
3515+
false,
3516+
'$foo',
3517+
''
3518+
)
3519+
),
3520+
]),
3521+
];
3522+
3523+
yield [
3524+
'multiline callable types - leading comma',
3525+
'/**' . PHP_EOL .
3526+
' * @param callable(' . PHP_EOL .
3527+
' * A' . PHP_EOL .
3528+
' * , B' . PHP_EOL .
3529+
' * ): void $foo' . PHP_EOL .
3530+
' */',
3531+
new PhpDocNode([
3532+
new PhpDocTagNode(
3533+
'@param',
3534+
new ParamTagValueNode(
3535+
new CallableTypeNode(
3536+
new IdentifierTypeNode('callable'),
3537+
[
3538+
new CallableTypeParameterNode(new IdentifierTypeNode('A'), false, false, '', false),
3539+
new CallableTypeParameterNode(new IdentifierTypeNode('B'), false, false, '', false),
3540+
],
3541+
new IdentifierTypeNode('void')
3542+
),
3543+
false,
3544+
'$foo',
3545+
''
3546+
)
3547+
),
3548+
]),
3549+
];
3550+
3551+
yield [
3552+
'multiline callable types - traling comma',
3553+
'/**' . PHP_EOL .
3554+
' * @param callable(' . PHP_EOL .
3555+
' * A,' . PHP_EOL .
3556+
' * B,' . PHP_EOL .
3557+
' * ): void $foo' . PHP_EOL .
3558+
' */',
3559+
new PhpDocNode([
3560+
new PhpDocTagNode(
3561+
'@param',
3562+
new ParamTagValueNode(
3563+
new CallableTypeNode(
3564+
new IdentifierTypeNode('callable'),
3565+
[
3566+
new CallableTypeParameterNode(new IdentifierTypeNode('A'), false, false, '', false),
3567+
new CallableTypeParameterNode(new IdentifierTypeNode('B'), false, false, '', false),
3568+
],
3569+
new IdentifierTypeNode('void')
3570+
),
3571+
false,
3572+
'$foo',
3573+
''
3574+
)
3575+
),
3576+
]),
3577+
];
34953578
}
34963579

34973580
public function provideDescriptionWithOrWithoutHtml(): Iterator

tests/PHPStan/Parser/TypeParserTest.php

+95
Original file line numberDiff line numberDiff line change
@@ -1004,6 +1004,101 @@ public function provideParseData(): array
10041004
'int|array{}',
10051005
new UnionTypeNode([new IdentifierTypeNode('int'), new ArrayShapeNode([])]),
10061006
],
1007+
[
1008+
'callable(' . PHP_EOL .
1009+
' Foo' . PHP_EOL .
1010+
'): void',
1011+
new CallableTypeNode(
1012+
new IdentifierTypeNode('callable'),
1013+
[
1014+
new CallableTypeParameterNode(new IdentifierTypeNode('Foo'), false, false, '', false),
1015+
],
1016+
new IdentifierTypeNode('void')
1017+
),
1018+
],
1019+
[
1020+
'callable(' . PHP_EOL .
1021+
' Foo,' . PHP_EOL .
1022+
' Bar' . PHP_EOL .
1023+
'): void',
1024+
new CallableTypeNode(
1025+
new IdentifierTypeNode('callable'),
1026+
[
1027+
new CallableTypeParameterNode(new IdentifierTypeNode('Foo'), false, false, '', false),
1028+
new CallableTypeParameterNode(new IdentifierTypeNode('Bar'), false, false, '', false),
1029+
],
1030+
new IdentifierTypeNode('void')
1031+
),
1032+
],
1033+
[
1034+
'callable(' . PHP_EOL .
1035+
' Foo, Bar' . PHP_EOL .
1036+
'): void',
1037+
new CallableTypeNode(
1038+
new IdentifierTypeNode('callable'),
1039+
[
1040+
new CallableTypeParameterNode(new IdentifierTypeNode('Foo'), false, false, '', false),
1041+
new CallableTypeParameterNode(new IdentifierTypeNode('Bar'), false, false, '', false),
1042+
],
1043+
new IdentifierTypeNode('void')
1044+
),
1045+
],
1046+
[
1047+
'callable(' . PHP_EOL .
1048+
' Foo,' . PHP_EOL .
1049+
' callable(' . PHP_EOL .
1050+
' Bar' . PHP_EOL .
1051+
' ): void' . PHP_EOL .
1052+
'): void',
1053+
new CallableTypeNode(
1054+
new IdentifierTypeNode('callable'),
1055+
[
1056+
new CallableTypeParameterNode(new IdentifierTypeNode('Foo'), false, false, '', false),
1057+
new CallableTypeParameterNode(
1058+
new CallableTypeNode(
1059+
new IdentifierTypeNode('callable'),
1060+
[
1061+
new CallableTypeParameterNode(new IdentifierTypeNode('Bar'), false, false, '', false),
1062+
],
1063+
new IdentifierTypeNode('void')
1064+
),
1065+
false,
1066+
false,
1067+
'',
1068+
false
1069+
),
1070+
],
1071+
new IdentifierTypeNode('void')
1072+
),
1073+
],
1074+
[
1075+
'callable(' . PHP_EOL .
1076+
' Foo,' . PHP_EOL .
1077+
' callable(' . PHP_EOL .
1078+
' Bar,' . PHP_EOL .
1079+
' ): void' . PHP_EOL .
1080+
'): void',
1081+
new CallableTypeNode(
1082+
new IdentifierTypeNode('callable'),
1083+
[
1084+
new CallableTypeParameterNode(new IdentifierTypeNode('Foo'), false, false, '', false),
1085+
new CallableTypeParameterNode(
1086+
new CallableTypeNode(
1087+
new IdentifierTypeNode('callable'),
1088+
[
1089+
new CallableTypeParameterNode(new IdentifierTypeNode('Bar'), false, false, '', false),
1090+
],
1091+
new IdentifierTypeNode('void')
1092+
),
1093+
false,
1094+
false,
1095+
'',
1096+
false
1097+
),
1098+
],
1099+
new IdentifierTypeNode('void')
1100+
),
1101+
],
10071102
];
10081103
}
10091104

0 commit comments

Comments
 (0)