|
1 | 1 | <?php namespace lang\ast\emit; |
2 | 2 |
|
3 | | -use lang\ast\nodes\{CallableExpression, CallableNewExpression, Variable}; |
| 3 | +use lang\ast\nodes\{CallableExpression, CallableNewExpression, Variable, Placeholder}; |
4 | 4 |
|
5 | 5 | /** |
6 | 6 | * Emulates pipelines / the pipe operator, including a null-safe version. |
7 | 7 | * |
| 8 | + * ```php |
| 9 | + * // Enclose expressions as follows: |
| 10 | + * $in |> $expr; |
| 11 | + * ($expr)($in); |
| 12 | + * |
| 13 | + * // Optimize for first-class callables with single placeholder argument: |
| 14 | + * $in |> strlen(...); |
| 15 | + * strlen($in); |
| 16 | + * ``` |
| 17 | + * |
8 | 18 | * @see https://wiki.php.net/rfc/pipe-operator-v3 |
9 | 19 | * @see https://externals.io/message/107661#107670 |
10 | 20 | * @test lang.ast.unittest.emit.PipelinesTest |
11 | 21 | */ |
12 | 22 | trait EmulatePipelines { |
13 | 23 |
|
| 24 | + private function singlePlaceholder($arguments) { |
| 25 | + return 1 === sizeof($arguments) && $arguments[0] instanceof Placeholder; |
| 26 | + } |
| 27 | + |
14 | 28 | protected function emitPipeTarget($result, $target, $arg) { |
15 | | - if ($target instanceof CallableNewExpression) { |
| 29 | + if ($target instanceof CallableNewExpression && $this->singlePlaceholder($target->arguments)) { |
16 | 30 | $target->type->arguments= [new Variable(substr($arg, 1))]; |
17 | 31 | $this->emitOne($result, $target->type); |
18 | 32 | $target->type->arguments= null; |
19 | | - } else if ($target instanceof CallableExpression) { |
| 33 | + } else if ($target instanceof CallableExpression && $this->singlePlaceholder($target->arguments)) { |
20 | 34 | $this->emitOne($result, $target->expression); |
21 | 35 | $result->out->write('('.$arg.')'); |
22 | 36 | } else { |
|
0 commit comments