File tree Expand file tree Collapse file tree 1 file changed +34
-0
lines changed
src/main/php/lang/ast/emit Expand file tree Collapse file tree 1 file changed +34
-0
lines changed Original file line number Diff line number Diff line change
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
+ }
You can’t perform that action at this time.
0 commit comments