From 9b86ce36762cc20c2fdfb11eb69400ae7b5e247a Mon Sep 17 00:00:00 2001 From: Timm Friebe Date: Sat, 6 Jan 2024 14:44:51 +0100 Subject: [PATCH] Fix parsing captures and return types for closures --- ChangeLog.md | 2 ++ src/main/php/lang/ast/syntax/PHP.class.php | 14 ++++++++++++-- .../lang/ast/unittest/parse/ClosuresTest.class.php | 8 ++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 62a617a..e58bdd9 100755 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -3,6 +3,8 @@ XP AST ChangeLog ## ?.?.? / ????-??-?? +* Fixed parsing captures and return types for closures - @thekid + ## 10.3.0 / 2023-10-06 * Merged PR #49: Record starting line numbers for multi-line nodes diff --git a/src/main/php/lang/ast/syntax/PHP.class.php b/src/main/php/lang/ast/syntax/PHP.class.php index 430fe4a..f226378 100755 --- a/src/main/php/lang/ast/syntax/PHP.class.php +++ b/src/main/php/lang/ast/syntax/PHP.class.php @@ -1484,7 +1484,10 @@ public function signature($parse, $byref= false) { public function closure($parse, $static) { $line= $parse->token->line; - $signature= $this->signature($parse); + + $parse->expecting('(', 'signature'); + $parameters= $this->parameters($parse); + $parse->expecting(')', 'signature'); if ('use' === $parse->token->value) { $parse->forward(); @@ -1508,11 +1511,18 @@ public function closure($parse, $static) { $use= null; } + if (':' === $parse->token->value) { + $parse->forward(); + $return= $this->type($parse); + } else { + $return= null; + } + $parse->expecting('{', 'function'); $statements= $this->statements($parse); $parse->expecting('}', 'function'); - return new ClosureExpression($signature, $use, $statements, $static, $line); + return new ClosureExpression(new Signature($parameters, $return, false, $line), $use, $statements, $static, $line); } public function block($parse) { diff --git a/src/test/php/lang/ast/unittest/parse/ClosuresTest.class.php b/src/test/php/lang/ast/unittest/parse/ClosuresTest.class.php index 4ff6804..4ea8114 100755 --- a/src/test/php/lang/ast/unittest/parse/ClosuresTest.class.php +++ b/src/test/php/lang/ast/unittest/parse/ClosuresTest.class.php @@ -45,6 +45,14 @@ public function with_use_by_value() { ); } + #[Test] + public function with_use_and_return() { + $this->assertParsed( + [new ClosureExpression(new Signature([], new Type('int'), false, self::LINE), ['$a'], [$this->returns], false, self::LINE)], + 'function() use($a): int { return $a + 1; };' + ); + } + #[Test] public function with_use_by_reference() { $this->assertParsed(