diff --git a/src/Psalm/Type/ParseTree.php b/src/Psalm/Type/ParseTree.php index 66bd33c78..8e8ba2f42 100644 --- a/src/Psalm/Type/ParseTree.php +++ b/src/Psalm/Type/ParseTree.php @@ -99,11 +99,16 @@ class ParseTree break; case ')': + if ($last_token === '(' && $current_leaf instanceof ParseTree\CallableTree) { + break; + } + do { if ($current_leaf->parent === null || $current_leaf->parent instanceof ParseTree\CallableWithReturnTypeTree ) { if (!$current_leaf instanceof ParseTree\CallableTree) { + var_dump($current_leaf); throw new TypeParseTreeException('Cannot parse generic type'); } diff --git a/tests/AnnotationTest.php b/tests/AnnotationTest.php index 8251dd7d5..0a35e4e97 100644 --- a/tests/AnnotationTest.php +++ b/tests/AnnotationTest.php @@ -752,6 +752,52 @@ class AnnotationTest extends TestCase */ function example(string $x) : void {}', ], + 'megaClosureAnnotationWithoutSpacing' => [ + '|null), b?:Closure():array, c?:Closure():array, d?:Closure():array, e?:Closure():(array{f:null|string, g:null|string, h:null|string, i:string, j:mixed, k:mixed, l:mixed, m:mixed, n:bool, o?:array{0:string}}|null), p?:Closure():(array{f:null|string, g:null|string, h:null|string, q:string, i:string, j:mixed, k:mixed, l:mixed, m:mixed, n:bool, o?:array{0:string}}|null), r?:Closure():(array|null), s:array} */ + $arr = []; + + $arr["a"]()', + ], + 'megaClosureAnnotationWithSpacing' => [ + '|null), + b?: Closure() : array, + c?: Closure() : array, + d?: Closure() : array, + e?: Closure() : (array{ + f: null|string, + g: null|string, + h: null|string, + i: string, + j: mixed, + k: mixed, + l: mixed, + m: mixed, + n: bool, + o?: array{0:string} + }|null), + p?: Closure() : (array{ + f: null|string, + g: null|string, + h: null|string, + q: string, + i: string, + j: mixed, + k: mixed, + l: mixed, + m: mixed, + n: bool, + o?: array{0:string} + }|null), + r?: Closure() : (array|null), + s: array + } */ + $arr = []; + + $arr["a"]()', + ], ]; } diff --git a/tests/TypeParseTest.php b/tests/TypeParseTest.php index 82c67e2fd..844d7e3d3 100644 --- a/tests/TypeParseTest.php +++ b/tests/TypeParseTest.php @@ -10,7 +10,7 @@ class TypeParseTest extends TestCase */ public function setUp() { - //parent::setUp(); + //pae::setUp(); } /** @@ -469,6 +469,19 @@ class TypeParseTest extends TestCase ); } + /** + * @return void + */ + public function testVeryLargeType() + { + $very_large_type = 'array{a:Closure():(array|null), b?:Closure():array, c?:Closure():array, d?:Closure():array, e?:Closure():(array{f:null|string, g:null|string, h:null|string, i:string, j:mixed, k:mixed, l:mixed, m:mixed, n:bool, o?:array{0:string}}|null), p?:Closure():(array{f:null|string, g:null|string, h:null|string, q:string, i:string, j:mixed, k:mixed, l:mixed, m:mixed, n:bool, o?:array{0:string}}|null), r?:Closure():(array|null), s:array}|null'; + + $this->assertSame( + $very_large_type, + (string) Type::parseString($very_large_type) + ); + } + /** * @dataProvider providerTestValidCallMapType *