Skip to content

Commit 29c2a1c

Browse files
committed
Emit callable expressions as regular function closures for PHP < 7.4
1 parent 1fd3f5b commit 29c2a1c

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php namespace lang\ast\emit;
2+
3+
/**
4+
* Rewrites callable expressions to regular closures
5+
*
6+
* @see https://wiki.php.net/rfc/first_class_callable_syntax
7+
*/
8+
trait CallablesAsClosures {
9+
10+
protected function emitCallable($result, $callable) {
11+
12+
// Use variables in the following cases:
13+
//
14+
// $closure(...); => use ($closure)
15+
// $obj->method(...); => use ($obj)
16+
// $obj->$method(...); => use ($obj, $method)
17+
// ($obj->property)(...); => use ($obj)
18+
// $class::$method(...); => use ($class, $method)
19+
// [$obj, 'method'](...); => use ($obj)
20+
// [Foo::class, $method](...); => use ($method)
21+
$use= [];
22+
foreach ($result->codegen->search($callable, 'variable') as $var) {
23+
'this' === $var->name || $use[$var->name]= true;
24+
}
25+
26+
// Create closure
27+
$t= $result->temp();
28+
$result->out->write('function(...'.$t.')');
29+
$use && $result->out->write('use($'.implode(', $', array_keys($use)).')');
30+
$result->out->write('{ return ');
31+
$this->emitOne($result, $callable->expression);
32+
$result->out->write('(... '.$t.'); }');
33+
}
34+
}

0 commit comments

Comments
 (0)