Support multiline callable syntax

Closes #46. Tests are basically copied and modified from #44
This commit is contained in:
Richard van Velzen 2022-03-28 09:06:49 +02:00 committed by Ondřej Mirtes
parent ad95bffa0d
commit c08946968b
3 changed files with 185 additions and 0 deletions

View File

@ -240,12 +240,19 @@ class TypeParser
private function parseCallable(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $identifier): Ast\Type\TypeNode
{
$tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES);
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
$parameters = [];
if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) {
$parameters[] = $this->parseCallableParameter($tokens);
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) {
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
if ($tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) {
break;
}
$parameters[] = $this->parseCallableParameter($tokens);
$tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL);
}
}

View File

@ -3492,6 +3492,89 @@ Finder::findFiles('*.php')
),
]),
];
yield [
'multiline callable types',
'/**' . PHP_EOL .
' * @param callable(' . PHP_EOL .
' * A, B' . PHP_EOL .
' * ): void $foo' . PHP_EOL .
' */',
new PhpDocNode([
new PhpDocTagNode(
'@param',
new ParamTagValueNode(
new CallableTypeNode(
new IdentifierTypeNode('callable'),
[
new CallableTypeParameterNode(new IdentifierTypeNode('A'), false, false, '', false),
new CallableTypeParameterNode(new IdentifierTypeNode('B'), false, false, '', false),
],
new IdentifierTypeNode('void')
),
false,
'$foo',
''
)
),
]),
];
yield [
'multiline callable types - leading comma',
'/**' . PHP_EOL .
' * @param callable(' . PHP_EOL .
' * A' . PHP_EOL .
' * , B' . PHP_EOL .
' * ): void $foo' . PHP_EOL .
' */',
new PhpDocNode([
new PhpDocTagNode(
'@param',
new ParamTagValueNode(
new CallableTypeNode(
new IdentifierTypeNode('callable'),
[
new CallableTypeParameterNode(new IdentifierTypeNode('A'), false, false, '', false),
new CallableTypeParameterNode(new IdentifierTypeNode('B'), false, false, '', false),
],
new IdentifierTypeNode('void')
),
false,
'$foo',
''
)
),
]),
];
yield [
'multiline callable types - traling comma',
'/**' . PHP_EOL .
' * @param callable(' . PHP_EOL .
' * A,' . PHP_EOL .
' * B,' . PHP_EOL .
' * ): void $foo' . PHP_EOL .
' */',
new PhpDocNode([
new PhpDocTagNode(
'@param',
new ParamTagValueNode(
new CallableTypeNode(
new IdentifierTypeNode('callable'),
[
new CallableTypeParameterNode(new IdentifierTypeNode('A'), false, false, '', false),
new CallableTypeParameterNode(new IdentifierTypeNode('B'), false, false, '', false),
],
new IdentifierTypeNode('void')
),
false,
'$foo',
''
)
),
]),
];
}
public function provideDescriptionWithOrWithoutHtml(): Iterator

View File

@ -1004,6 +1004,101 @@ class TypeParserTest extends TestCase
'int|array{}',
new UnionTypeNode([new IdentifierTypeNode('int'), new ArrayShapeNode([])]),
],
[
'callable(' . PHP_EOL .
' Foo' . PHP_EOL .
'): void',
new CallableTypeNode(
new IdentifierTypeNode('callable'),
[
new CallableTypeParameterNode(new IdentifierTypeNode('Foo'), false, false, '', false),
],
new IdentifierTypeNode('void')
),
],
[
'callable(' . PHP_EOL .
' Foo,' . PHP_EOL .
' Bar' . PHP_EOL .
'): void',
new CallableTypeNode(
new IdentifierTypeNode('callable'),
[
new CallableTypeParameterNode(new IdentifierTypeNode('Foo'), false, false, '', false),
new CallableTypeParameterNode(new IdentifierTypeNode('Bar'), false, false, '', false),
],
new IdentifierTypeNode('void')
),
],
[
'callable(' . PHP_EOL .
' Foo, Bar' . PHP_EOL .
'): void',
new CallableTypeNode(
new IdentifierTypeNode('callable'),
[
new CallableTypeParameterNode(new IdentifierTypeNode('Foo'), false, false, '', false),
new CallableTypeParameterNode(new IdentifierTypeNode('Bar'), false, false, '', false),
],
new IdentifierTypeNode('void')
),
],
[
'callable(' . PHP_EOL .
' Foo,' . PHP_EOL .
' callable(' . PHP_EOL .
' Bar' . PHP_EOL .
' ): void' . PHP_EOL .
'): void',
new CallableTypeNode(
new IdentifierTypeNode('callable'),
[
new CallableTypeParameterNode(new IdentifierTypeNode('Foo'), false, false, '', false),
new CallableTypeParameterNode(
new CallableTypeNode(
new IdentifierTypeNode('callable'),
[
new CallableTypeParameterNode(new IdentifierTypeNode('Bar'), false, false, '', false),
],
new IdentifierTypeNode('void')
),
false,
false,
'',
false
),
],
new IdentifierTypeNode('void')
),
],
[
'callable(' . PHP_EOL .
' Foo,' . PHP_EOL .
' callable(' . PHP_EOL .
' Bar,' . PHP_EOL .
' ): void' . PHP_EOL .
'): void',
new CallableTypeNode(
new IdentifierTypeNode('callable'),
[
new CallableTypeParameterNode(new IdentifierTypeNode('Foo'), false, false, '', false),
new CallableTypeParameterNode(
new CallableTypeNode(
new IdentifierTypeNode('callable'),
[
new CallableTypeParameterNode(new IdentifierTypeNode('Bar'), false, false, '', false),
],
new IdentifierTypeNode('void')
),
false,
false,
'',
false
),
],
new IdentifierTypeNode('void')
),
],
];
}