Skip to content

Commit

Permalink
bug: Fix non-parenthesized callable return type parse (#6961)
Browse files Browse the repository at this point in the history
Co-authored-by: Greg Korba <greg@codito.dev>
  • Loading branch information
mvorisek and Wirone committed May 18, 2023
1 parent 234e98f commit 733dd38
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/DocBlock/TypeExpression.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ final class TypeExpression
\h*\)
(?:
\h*\:\h*
(?<callable_return>(?&types))
(?<callable_return>(?&type))
)?
)
|
Expand Down Expand Up @@ -89,7 +89,7 @@ final class TypeExpression
(?i)
null | true | false
| -?(?:\d+(?:\.\d*)?|\.\d+) # all sorts of numbers with or without minus, e.g.: 1, 1.1, 1., .1, -1
| \'(?:[^\'\\\\]|\\\\.)+?\' | "(?:[^"\\\\]|\\\\.)+?"
| \'(?:[^\'\\\\]|\\\\.)*?\' | "(?:[^"\\\\]|\\\\.)*?"
| [@$]?(?:this | self | static)
(?-i)
)
Expand Down
51 changes: 43 additions & 8 deletions tests/DocBlock/TypeExpressionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ public function testGetTypes(string $typesExpression, array $expectedTypes): voi
{
$expression = new TypeExpression($typesExpression, null, []);
self::assertSame($expectedTypes, $expression->getTypes());

$unionTestNs = '__UnionTest__';
$unionExpression = new TypeExpression(
$unionTestNs.'\\A|'.$typesExpression.'|'.$unionTestNs.'\\Z',
null,
[]
);
self::assertSame(
[$unionTestNs.'\\A', ...$expectedTypes, $unionTestNs.'\\Z'],
[...$unionExpression->getTypes()]
);
}

public static function provideGetTypesCases(): iterable
Expand Down Expand Up @@ -153,6 +164,8 @@ public static function provideGetTypesCases(): iterable

yield ['\\Closure(string|int, bool): bool', ['\\Closure(string|int, bool): bool']];

yield ['\\Closure(float|int): (bool|int)', ['\\Closure(float|int): (bool|int)']];

yield ['array < int , callable ( string ) : bool >', ['array < int , callable ( string ) : bool >']];

yield ['(int)', ['(int)']];
Expand Down Expand Up @@ -415,8 +428,13 @@ public static function provideSortTypesCases(): iterable
];

yield 'simple in callable return type' => [
'callable(): string|float',
'callable(): float|string',
'callable(): (string|float)',
'callable(): (float|string)',
];

yield 'callable with union return type and within union itself' => [
'callable(): (string|float)|bool',
'bool|callable(): (float|string)',
];

yield 'simple in closure argument' => [
Expand All @@ -430,13 +448,23 @@ public static function provideSortTypesCases(): iterable
];

yield 'simple in closure return type' => [
'Closure(): string|float',
'Closure(): float|string',
'Closure(): (string|float)',
'Closure(): (float|string)',
];

yield 'closure with union return type and within union itself' => [
'Closure(): (string|float)|bool',
'bool|Closure(): (float|string)',
];

yield 'with multiple nesting levels' => [
'array{0: Foo<int|bool>|Bar<callable(string|float|array<int|bool>): Foo|Bar>}',
'array{0: Bar<callable(array<bool|int>|float|string): Bar|Foo>|Foo<bool|int>}',
'array{0: Foo<int|bool>|Bar<callable(string|float|array<int|bool>): (Foo|Bar)>}',
'array{0: Bar<callable(array<bool|int>|float|string): (Bar|Foo)>|Foo<bool|int>}',
];

yield 'with multiple nesting levels and callable within union' => [
'array{0: Foo<int|bool>|Bar<callable(string|float|array<int|bool>): (Foo|Bar)|Baz>}',
'array{0: Bar<Baz|callable(array<bool|int>|float|string): (Bar|Foo)>|Foo<bool|int>}',
];

yield 'complex type with Closure with $this' => [
Expand All @@ -450,8 +478,15 @@ public static function provideSortTypesCases(): iterable
];

yield 'nullable callable' => [
'?callable(Foo|Bar): Foo|Bar',
'?callable(Bar|Foo): Bar|Foo',
'?callable(Foo|Bar): (Foo|Bar)',
'?callable(Bar|Foo): (Bar|Foo)',
];

// This union type makes no sense in general (it should be `Bar|callable|null`)
// but let's ensure nullable types are also sorted.
yield 'nullable callable with union return type and within union itself' => [
'?callable(Foo|Bar): (Foo|Bar)|?Bar',
'?Bar|?callable(Bar|Foo): (Bar|Foo)',
];

yield 'nullable array shape' => [
Expand Down

0 comments on commit 733dd38

Please sign in to comment.