From 9beb5cbba2479ecfdcfb001f675839cdaf826be4 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Fri, 5 Jun 2026 14:55:57 +0800 Subject: [PATCH] =?UTF-8?q?fix(parser):=20=E4=BF=AE=E5=A4=8D=E8=B5=8B?= =?UTF-8?q?=E5=80=BC=E6=93=8D=E4=BD=9C=E7=AC=A6=E5=92=8C=E9=80=92=E5=A2=9E?= =?UTF-8?q?=E9=80=92=E5=87=8F=E6=93=8D=E4=BD=9C=E7=AC=A6=E7=9A=84=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E7=8A=B6=E6=80=81=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 parseAssignOp 方法中正确保存和恢复 inAssignExpr 上下文状态 - 在 parsePreInc 方法中正确保存和恢复 inAssignExpr 上下文状态 - 在 parsePostOp 方法中正确保存和恢复 inAssignExpr 上下文状态 - 在 parsePreDec 方法中正确保存和恢复 inAssignExpr 上下文状态 - 修复 FuncCallOptimizer 中对函数参数类型的检查逻辑,排除 VariadicPlaceholder 占位符情况 --- src/Php/CompilerBase.php | 15 +++++++++++++-- src/Php/Optimizer/FuncCallOptimizer.php | 3 ++- src/Php/Parser/AssignOpTrait.php | 3 +++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 253c179a..89872cc1 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -2576,11 +2576,15 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePreInc(Expr\PreInc $expr): string { + $oriInAssignExpr = $this->context->inAssignExpr; + $this->context->inAssignExpr = true; $type = $this->detectVarType($expr->var); if ($type === self::TYPE_BIGINT || $type === self::TYPE_DECIMAL || $type === self::TYPE_BIGFLOAT) { $this->fatalError($expr, 'Cannot use ++ on ' . $type . '. Use += 1 instead (Big* types are immutable).'); } - return '++' . $this->parseIdentifier($expr->var); + $result = '++' . $this->parseIdentifier($expr->var); + $this->context->inAssignExpr = $oriInAssignExpr; + return $result; } /** @@ -3128,7 +3132,10 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePostOp(Expr\PostDec|Expr\PostInc $expr, string $op): string { if ($this->isVarExpr($expr->var) or $this->isPropertyFetch($expr->var) or $this->isArrayDimFetch($expr->var)) { + $oriInAssignExpr = $this->context->inAssignExpr; + $this->context->inAssignExpr = true; $var = $this->parseIdentifier($expr->var); + $this->context->inAssignExpr = $oriInAssignExpr; if ($this->isVarExpr($expr->var) and !$this->hasVar($var)) { $this->errorUndefinedVariable($expr->var); } @@ -3221,11 +3228,15 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePreDec(Expr\PreDec $expr): string { + $oriInAssignExpr = $this->context->inAssignExpr; + $this->context->inAssignExpr = true; $type = $this->detectVarType($expr->var); if ($type === self::TYPE_BIGINT || $type === self::TYPE_DECIMAL || $type === self::TYPE_BIGFLOAT) { $this->fatalError($expr, 'Cannot use -- on ' . $type . '. Use -= 1 instead (Big* types are immutable).'); } - return '--' . $this->parseIdentifier($expr->var); + $result = '--' . $this->parseIdentifier($expr->var); + $this->context->inAssignExpr = $oriInAssignExpr; + return $result; } protected function parseBitwiseNot(Expr\BitwiseNot $expr): string diff --git a/src/Php/Optimizer/FuncCallOptimizer.php b/src/Php/Optimizer/FuncCallOptimizer.php index 70471000..f6c3d27b 100644 --- a/src/Php/Optimizer/FuncCallOptimizer.php +++ b/src/Php/Optimizer/FuncCallOptimizer.php @@ -193,7 +193,8 @@ trait FuncCallOptimizer if ($name === 'get_class') { return $this->genGetClass($expr); } - if (count($expr->args) === 1) { + // 除了 Node\Arg 之外,可能是 VariadicPlaceholder 占位符 (...) + if (count($expr->args) === 1 && $expr->args[0] instanceof Node\Arg) { $arg = $expr->args[0]->value; $type = $this->detectTypeOfExpr($arg); // is_* compile-time elimination when SSA-narrowed diff --git a/src/Php/Parser/AssignOpTrait.php b/src/Php/Parser/AssignOpTrait.php index 8c672d23..428387d5 100644 --- a/src/Php/Parser/AssignOpTrait.php +++ b/src/Php/Parser/AssignOpTrait.php @@ -296,7 +296,10 @@ trait AssignOpTrait protected function parseAssignOp(Expr\AssignOp $node, string $op): string { + $oriInAssignExpr = $this->context->inAssignExpr; + $this->context->inAssignExpr = true; $var = $this->parseIdentifier($node->var); + $this->context->inAssignExpr = $oriInAssignExpr; $expr = $this->parseIdentifier($node->expr); if ($this->isVarExpr($node->var)) {