Skip to content

Commit

Permalink
Fix parsing captures and return types for closures
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed Jan 6, 2024
1 parent 08c725e commit 9b86ce3
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
2 changes: 2 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 12 additions & 2 deletions src/main/php/lang/ast/syntax/PHP.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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) {
Expand Down
8 changes: 8 additions & 0 deletions src/test/php/lang/ast/unittest/parse/ClosuresTest.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down

0 comments on commit 9b86ce3

Please sign in to comment.