fix(php): 修复编译器中未定义变量检查和引用参数处理逻辑

- 重构引用参数处理逻辑,统一处理未定义变量作为引用的情况
- 添加对属性访问和数组索引操作中未定义变量的检查
- 修复临时变量创建和替换逻辑,确保引用类型参数正确传递
- 修改未定义变量错误报告机制,增强编译时错误检测
- 优化变量引用转换流程,提高代码生成的准确性
pull/1/head
韩天峰 7 months ago
parent 7e5b6ef045
commit 60ba3da404
  1. 27
      src/Php/CompilerBase.php

@ -1905,31 +1905,42 @@ class CompilerBase extends \PhpAot\Core\Translator
}
if ($this->isVarExpr($arg->value)) {
$name = $this->parseIdentifier($arg->value);
// 调用了不存在的变量,可能是引用
if ($funcName and Reflection::isReferenceArg($funcName, $i)) {
if (!$this->hasVar($name)) {
// 若参数是引用类型,可以传入未定义变量,将立即创建变量作为引用
$this->addLocalVar($name, self::TYPE_REF);
$this->beforeStmtLines[] = $name . ' = php::newReference();';
} elseif ($funcName and Reflection::isReferenceArg($funcName, $i)) {
} else {
// 需要引用类型的参数,使用临时变量作为引用,并替换掉实际的参数
$tmpVar = $this->genTmpVarName();
$this->addLocalVar($tmpVar, self::TYPE_REF);
$this->beforeStmtLines[] = $tmpVar . ' = ' . $this->parseExpr($arg->value) . '.toReference();';
$list_args[] = '&' . $tmpVar;
$name = $tmpVar;
}
$this->beforeStmtLines[] = $name . ' = ' . $this->parseExpr($arg->value) . '.toReference();';
$list_args[] = '&' . $name;
continue;
}
if (!$this->hasVar($name)) {
$this->fatalError($arg, 'Undefined variable `$' . $name . '`');
}
} elseif ($this->isPropertyFetch($arg->value)) {
if ($funcName and Reflection::isReferenceArg($funcName, $i)) {
$obj = $this->parseIdentifier($arg->value->var);
if (!$this->hasVar($obj)) {
$this->fatalError($arg, 'Undefined variable `$' . $obj . '`');
}
if ($funcName and Reflection::isReferenceArg($funcName, $i)) {
$list_args[] = $obj . '.attrRef(' . $this->identifierToStr($arg->value->name) . ')';
continue;
}
} elseif ($this->isArrayDimFetch($arg->value)) {
$array = $this->parseIdentifier($arg->value->var);
if (!$this->hasVar($array)) {
$this->fatalError($arg, 'Undefined variable `$' . $array . '`');
}
if ($funcName and Reflection::isReferenceArg($funcName, $i)) {
$obj = $this->parseIdentifier($arg->value->var);
if ($arg->value->dim === null) {
$this->fatalError($arg, 'Array dimension must be a constant expression');
}
$list_args[] = $obj . '.itemRef(' . $this->identifierToStr($arg->value->dim) . ')';
$list_args[] = $array . '.itemRef(' . $this->identifierToStr($arg->value->dim) . ')';
continue;
}
}

Loading…
Cancel
Save