feat(php): 支持引用参数的默认值为数组

- 添加 isEmptyArray 方法检查空数组
- 修改编译器对引用参数默认值的处理逻辑
- 实现引用参数默认值为空数组的支持
- 更新参数解析逻辑以正确处理引用参数
- 添加测试用例验证引用参数数组默认值功能
- 修复命名参数缺失默认值时的错误处理
pull/1/head
韩天峰 5 months ago
parent 7681f6dc26
commit e230e66164
  1. 5
      src/Php/AstNodeType.php
  2. 15
      src/Php/CompilerBase.php
  3. 6
      src/Php/Translator.php
  4. 29
      tests/aot/ref/default-array.phpt

@ -129,4 +129,9 @@ trait AstNodeType
}
return $expr instanceof Expr\Exit_;
}
protected function isEmptyArray(NodeAbstract $expr): bool
{
return $expr instanceof Node\Expr\Array_ && count($expr->items) === 0;
}
}

@ -1031,11 +1031,17 @@ class CompilerBase extends \PhpAot\Core\Translator
}
if ($param->default) {
if ($param->byRef) {
$this->fatalError($param, 'Default value for parameters passed by reference is not supported');
if (!$this->isEmptyArray($param->default)) {
$this->fatalError($param, 'Default value for parameters passed by reference must be an empty array');
} else {
$argInfo->default = 'php::getEmptyArrayRef()';
$argInfo->defaultValue = null;
}
} else {
$argInfo->default = $this->parseParamDefaultValue($param->default);
$argInfo->defaultValue = $param->default;
}
$defaultValueCount++;
$argInfo->default = $this->parseParamDefaultValue($param->default);
$argInfo->defaultValue = $param->default;
} elseif ($param->variadic) {
// 变长参数可以视为空数组默认值
$defaultValueCount++;
@ -2339,6 +2345,9 @@ class CompilerBase extends \PhpAot\Core\Translator
// 命名参数中间存在空洞,需要使用默认参数填充
foreach ($functionDef->argInfoList as $k => $argInfo) {
if (!isset($args[$k])) {
if ($argInfo->defaultValue === null) {
$this->fatalError($callArgs[$i], 'Named argument `' . $argInfo->name . '` is missing default value');
}
$args[$k] = new Node\Arg($argInfo->defaultValue);
}
}

@ -954,7 +954,11 @@ class Translator extends Preprocessor
$cppCode .= '}' . PHP_EOL;
} else {
if ($argInfo->default) {
$argExpr = 'php::getCallArg(' . $k . ', ' . $argInfo->default . ')';
if ($argInfo->byRef) {
$argExpr = 'php::getCallArgByRef(' . $k . ', ' . $argInfo->default . ')';
} else {
$argExpr = 'php::getCallArg(' . $k . ', ' . $argInfo->default . ')';
}
} else {
if ($argInfo->byRef) {
$argExpr = 'php::getCallArgByRef(' . $k . ')';

@ -0,0 +1,29 @@
--TEST--
ref call arg
--FILE--
<?php
function foo(array &$ref = []) {
$ref[] = uniqid();
return $ref;
}
function main()
{
$rs = foo();
var_dump($rs);
foo($rs);
var_dump($rs);
}
?>
--EXPECTF--
array(1) {
[0]=>
string(13) "%s"
}
array(2) {
[0]=>
string(13) "%s"
[1]=>
string(13) "%s"
}
Loading…
Cancel
Save