diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 09c5bab1..7450781c 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -2543,6 +2543,33 @@ class CompilerBase extends \PhpAot\Core\Translator return implode(', ', $argList); } + protected function parseNamedCallArgs(array $args, int $firstIndex, array $listArgs): string + { + $namedArgs = []; + foreach ($args as $i => $arg) { + if ($i < $firstIndex) { + continue; + } + if ($arg->name === null) { + $this->fatalError($arg, 'Named argument must follow positional argument'); + } + if (!$this->isIdExpr($arg->name)) { + $this->fatalError($arg, 'Named argument must be a string'); + } + $namedArgs[$arg->name->name] = $this->parseArg($arg); + } + + $tmpVar = $this->genTmpVarName(); + + $array = self::TYPE_ARRAY . ' ' . $tmpVar . ';'; + foreach ($namedArgs as $k => $v) { + $array .= $tmpVar . '.set(' . $this->getLiteralString($k) . ', ' . $v . ');' . PHP_EOL; + } + $this->context->beforeStmtLines[] = $array; + + return '{' . implode(', ', $listArgs) . '}, ' . $tmpVar . '.array()'; + } + protected function parseCallArgs(array $args, string $funcName = '', string $className = ''): string { $list_args = []; @@ -2552,7 +2579,7 @@ class CompilerBase extends \PhpAot\Core\Translator throw new PlaceHolder(); } if ($arg->name !== null) { - $this->fatalError($arg, 'Named arguments are not supported'); + return $this->parseNamedCallArgs($args, $i, $list_args); } $byRef = $funcName && Reflection::isReferenceArg($funcName, $className, $i); if ($this->isVarExpr($arg->value)) { diff --git a/tests/aot/dynamic_call/functions.inc b/tests/aot/dynamic_call/functions.inc new file mode 100644 index 00000000..485cfab1 --- /dev/null +++ b/tests/aot/dynamic_call/functions.inc @@ -0,0 +1,10 @@ + $name, 'age' => $age, 'city' => $city, 'vip' => $vip]; +} diff --git a/tests/aot/dynamic_call/named-args.phpt b/tests/aot/dynamic_call/named-args.phpt new file mode 100644 index 00000000..0b4e3413 --- /dev/null +++ b/tests/aot/dynamic_call/named-args.phpt @@ -0,0 +1,36 @@ +--TEST-- +named args +--FILE-- + +--EXPECT-- +array(4) { + ["name"]=> + string(4) "John" + ["age"]=> + int(20) + ["city"]=> + string(7) "Beijing" + ["vip"]=> + bool(false) +} +array(4) { + ["name"]=> + string(3) "Tom" + ["age"]=> + int(20) + ["city"]=> + string(7) "Beijing" + ["vip"]=> + bool(true) +}