From ecb7795243e3f76aed461353893a1da35ad1869b Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 2 Apr 2026 11:43:47 +0800 Subject: [PATCH] =?UTF-8?q?fix(aot):=20=E4=BF=AE=E5=A4=8D=E7=A9=BA?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E8=BF=90=E7=AE=97=E7=AC=A6=E7=9A=84=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 parseExpr 中添加对 replace 属性的检查 - 修改 coalesce 运算符的处理逻辑,避免重复函数调用 - 添加临时变量来存储 coalesce 表达式的结果 - 更新测试用例以验证正确的执行顺序和结果 - 添加新的测试用例验证 null 合并运算符行为 - 添加测试用例验证 ??= 运算符的链式赋值功能 --- src/Php/CompilerBase.php | 17 ++++++++++++----- tests/aot/coalesce/002.phpt | 16 +++++++++------- tests/aot/coalesce/003.phpt | 20 ++++++++++++++++++++ tests/aot/coalesce/004.phpt | 28 ++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 tests/aot/coalesce/003.phpt create mode 100644 tests/aot/coalesce/004.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 3e08ec31..5497dfe3 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -310,6 +310,9 @@ class CompilerBase extends \PhpAot\Core\Translator public function parseExpr(NodeAbstract $expr) { + if ($expr->hasAttribute('replace')) { + return $expr->getAttribute('replace'); + } $type = $expr->getType(); $this->writeLog('Line ' . $this->getLine($expr) . ': ' . $type); if ($expr->getLine() === $this->debugLine) { @@ -2924,17 +2927,21 @@ class CompilerBase extends \PhpAot\Core\Translator $this->checkVarMustExist($expr->left, $left); } - $this->mustNoCall($expr->right); - $right = $this->parseIdentifier($expr->right); - $this->checkVarMustExist($expr->right, $right); - $isset = $this->parseChainedExpr($expr->left, self::OP_ISSET, true); $chainOpResult = $expr->left->getAttribute('chainOpResult'); if ($chainOpResult) { $left = $chainOpResult; } - return $isset . ' ? ' . $left . ' : ' . $right; + $right = $this->parseIdentifier($expr->right); + $this->checkVarMustExist($expr->right, $right); + + $tmpVar = $this->addTmpVar(self::TYPE_VAR); + $this->context->beforeStmtLines[] = '// Coalesce: ' . $this->printer->prettyPrintExpr($expr) . PHP_EOL . + $tmpVar . ' = ' . $isset . ' ? ' . $left . ' : ' . $right . ';'; + $expr->setAttribute('replace', $tmpVar); + + return $tmpVar; } protected function parseBinaryOpNotIdentical(Node\Expr\BinaryOp $expr): string diff --git a/tests/aot/coalesce/002.phpt b/tests/aot/coalesce/002.phpt index 28ac8a0e..087067b4 100644 --- a/tests/aot/coalesce/002.phpt +++ b/tests/aot/coalesce/002.phpt @@ -10,14 +10,16 @@ function f($x) } function main() { - $r1 = f(1); - $r2 = f(2); - $a = f(null) ?? $r1 ?? $r2; + $a = f(null) ?? f(2); + var_dump($a); + + $a = f(1) ?? f(2); var_dump($a); } ?> ---EXPECTF-- -f(1) -f(2) +--EXPECT-- f(0) -int(1) +f(2) +int(2) +f(1) +int(1) \ No newline at end of file diff --git a/tests/aot/coalesce/003.phpt b/tests/aot/coalesce/003.phpt new file mode 100644 index 00000000..97c4ece2 --- /dev/null +++ b/tests/aot/coalesce/003.phpt @@ -0,0 +1,20 @@ +--TEST-- +Test ?? operator +--FILE-- + +--EXPECT-- +f(0) +f(1) +int(1) diff --git a/tests/aot/coalesce/004.phpt b/tests/aot/coalesce/004.phpt new file mode 100644 index 00000000..2cbe1b1c --- /dev/null +++ b/tests/aot/coalesce/004.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test ?? operator +--FILE-- + +--EXPECT-- +int(100) +int(100) +int(33) +int(33) \ No newline at end of file