fix(parser): 修复赋值操作符和递增递减操作符的上下文状态管理

- 在 parseAssignOp 方法中正确保存和恢复 inAssignExpr 上下文状态
- 在 parsePreInc 方法中正确保存和恢复 inAssignExpr 上下文状态
- 在 parsePostOp 方法中正确保存和恢复 inAssignExpr 上下文状态
- 在 parsePreDec 方法中正确保存和恢复 inAssignExpr 上下文状态
- 修复 FuncCallOptimizer 中对函数参数类型的检查逻辑,排除 VariadicPlaceholder 占位符情况
pull/1/head
韩天峰 3 months ago
parent c8e6f2ecc4
commit 9beb5cbba2
  1. 15
      src/Php/CompilerBase.php
  2. 3
      src/Php/Optimizer/FuncCallOptimizer.php
  3. 3
      src/Php/Parser/AssignOpTrait.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

@ -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

@ -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)) {

Loading…
Cancel
Save