Skip to content

Commit

Permalink
Fix enclosing scopes when using references
Browse files Browse the repository at this point in the history
  • Loading branch information
thekid committed Oct 4, 2024
1 parent f37388f commit 07dd3b4
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 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 Compiler ChangeLog

## ?.?.? / ????-??-??

* Fixed enclosing scopes when using references - @thekid

## 9.3.0 / 2024-08-31

* Fixed checks for property hooks emulation with asymmetric visibility
Expand Down
16 changes: 8 additions & 8 deletions src/main/php/lang/ast/emit/PHP.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ protected function enclose($result, $node, $signature, $static, $emit) {
$capture= [];
foreach ($result->codegen->search($node, 'variable') as $var) {
if (isset($result->locals[$var->pointer])) {
$capture[$var->pointer]= true;
$capture[$var->pointer]??= ($result->locals[$var->pointer] ? '&$' : '$').$var->pointer;
}
}
unset($capture['this']);
Expand All @@ -143,9 +143,9 @@ protected function enclose($result, $node, $signature, $static, $emit) {
}

if ($capture) {
$result->out->write('use($'.implode(', $', array_keys($capture)).')');
foreach ($capture as $name => $_) {
$result->locals[$name]= true;
$result->out->write('use('.implode(', ', $capture).')');
foreach ($capture as $name => $variable) {
$result->locals[$name]= '&' === $variable[0];
}
}

Expand Down Expand Up @@ -298,7 +298,7 @@ protected function emitArray($result, $array) {
}

protected function emitParameter($result, $parameter) {
$result->locals[$parameter->name]= true;
$result->locals[$parameter->name]= $parameter->reference;
$parameter->annotations && $this->emitOne($result, $parameter->annotations);

// If we have a non-constant default and a type, emit a nullable type hint
Expand Down Expand Up @@ -340,7 +340,7 @@ protected function emitSignature($result, $signature, $use= null) {
if ($use) {
$result->out->write(' use('.implode(',', $use).') ');
foreach ($use as $variable) {
$result->locals[substr($variable, 1)]= true;
$result->locals[ltrim($variable, '&$')]= '&' === $variable[0];
}
}

Expand Down Expand Up @@ -675,7 +675,7 @@ protected function emitProperty($result, $property) {

protected function emitMethod($result, $method) {
$locals= $result->locals;
$result->locals= ['this' => true];
$result->locals= ['this' => false];
$meta= [
DETAIL_RETURNS => $method->signature->returns ? $method->signature->returns->name() : 'var',
DETAIL_ANNOTATIONS => $method->annotations,
Expand Down Expand Up @@ -798,7 +798,7 @@ protected function emitOffset($result, $offset) {
protected function emitAssign($result, $target) {
if ($target instanceof Variable && $target->const) {
$result->out->write('$'.$target->pointer);
$result->locals[$target->pointer]= true;
$result->locals[$target->pointer]= false;
} else if ($target instanceof ArrayLiteral) {
$result->out->write('[');
foreach ($target->values as $pair) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,4 +211,24 @@ public function run() {

Assert::equals('one item', $r(1));
}

#[Test]
public function match_block_inside_function_using_ref() {
$r= $this->run('class %T {
public function run() {
$test= "Original";
(function() use(&$test) {
match (true) {
true => {
$test= "Changed";
return true;
}
};
})();
return $test;
}
}');

Assert::equals('Changed', $r);
}
}

0 comments on commit 07dd3b4

Please sign in to comment.