From 805f2a62ee9f82bda2010cfeeeb1e4805a336766 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 7 May 2026 13:34:47 +0800 Subject: [PATCH] =?UTF-8?q?refactor(compiler):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=A0=87=E5=87=86=E6=95=B0=E7=BB=84=E8=AE=BF=E9=97=AE=E7=9A=84?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=B5=8B=E5=92=8C=E8=A1=A8=E8=BE=BE?= =?UTF-8?q?=E5=BC=8F=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除 phpx_std_array.h 头文件引用 - 将表达式解析提取为独立变量以提高可读性 - 添加标准数组维度获取的属性缓存机制 - 实现完整的数组维度访问层级检测 - 修复参数传递中的数组转换逻辑 - 优化嵌套数组访问的解析流程 --- src/Php/CompilerBase.php | 22 ++++++++++++++++++---- src/Php/Parser/StdArrayParser.php | 9 ++++----- tests/aot/std-array/002.phpt | 25 +++++++++++++++++++++++++ tests/aot/std-array/003.phpt | 19 +++++++++++++++++++ 4 files changed, 66 insertions(+), 9 deletions(-) create mode 100644 tests/aot/std-array/002.phpt create mode 100644 tests/aot/std-array/003.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 2b6798ce..dd2b6a67 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -134,7 +134,6 @@ class CompilerBase extends \PhpAot\Core\Translator protected array $globalHeaders = [ 'phpx.h', 'phpx_helper.h', - 'phpx_std_array.h', 'phpx_func.h', 'php_func_decl.h', 'php_global_var_decl.h', @@ -1595,7 +1594,8 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->parseAssignArrayDim($left, $right); } - return $var . ' = ' . $this->convertExprType($this->parseExpr($right), $this->detectTypeOfExpr($left), $this->detectTypeOfExpr($right)); + $rightExpr = $this->parseExpr($right); + return $var . ' = ' . $this->convertExprType($rightExpr, $this->detectTypeOfExpr($left), $this->detectTypeOfExpr($right)); } protected function parseEcho(mixed $v): string @@ -2156,7 +2156,15 @@ class CompilerBase extends \PhpAot\Core\Translator break; case 'Expr_ArrayDimFetch': if ($this->isStdArrayExpr($expr)) { - return $this->getStdArrayInfo($expr)['type']; + if (!$expr->hasAttribute('stdArrayDimFetch')) { + $this->parseStdArrayDimFetch($expr); + } + $attr = $expr->getAttribute('stdArrayDimFetch'); + if ($attr['accessLevel'] === $attr['totalLevel']) { + return $this->context->stdArrays[$attr['var']]['type']; + } else { + return self::TYPE_ARRAY; + } } break; case 'Expr_New': @@ -3459,7 +3467,13 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseArg(Node\Arg $arg): string { if ($this->isArrayDimFetch($arg->value) and $this->isStdArrayExpr($arg->value)) { - return $this->convertArrayExpr($this->parseStdArrayDimFetch($arg->value, true)); + $valueExpr = $this->parseStdArrayDimFetch($arg->value); + $attr = $arg->value->getAttribute('stdArrayDimFetch'); + if ($attr['accessLevel'] === $attr['totalLevel']) { + return $this->convertExprFromType($this->context->stdArrays[$attr['var']]['type'], $valueExpr); + } else { + return $this->convertArrayExpr($valueExpr); + } } $expr = $this->parseIdentifier($arg->value); if ($this->isVarExpr($arg->value) and $this->isStdArray($arg->value->name)) { diff --git a/src/Php/Parser/StdArrayParser.php b/src/Php/Parser/StdArrayParser.php index 20de1282..8379570f 100644 --- a/src/Php/Parser/StdArrayParser.php +++ b/src/Php/Parser/StdArrayParser.php @@ -64,7 +64,7 @@ trait StdArrayParser return $arrayDimFetch . ' ' . $binaryOp . '= ' . $this->convertExprFromType($info['type'], $this->parseExpr($expr->expr)); } - protected function parseStdArrayDimFetch(Expr\ArrayDimFetch $expr, bool $toArray = false): string + protected function parseStdArrayDimFetch(Expr\ArrayDimFetch $expr): string { $tmp = $expr; $nesting = []; @@ -92,11 +92,10 @@ trait StdArrayParser } } - if (!$toArray and count($nesting) !== count($info['sizes']) + 1) { - $this->fatalError($expr, 'Wrong dimension access std::array used'); - } + $nesting = array_reverse($nesting); + $expr->setAttribute('stdArrayDimFetch', ['var' => $nesting[0], 'accessLevel' => $level, 'totalLevel' => count($info['sizes'])]); - return implode('', array_reverse($nesting)); + return implode('', $nesting); } protected function parseStdArray(string $var, Expr\StaticCall $expr): string diff --git a/tests/aot/std-array/002.phpt b/tests/aot/std-array/002.phpt new file mode 100644 index 00000000..adb87507 --- /dev/null +++ b/tests/aot/std-array/002.phpt @@ -0,0 +1,25 @@ +--TEST-- +std array: 002 +--FILE-- + +--EXPECT-- +int(2026) +int(13) +int(2019) +int(13) + diff --git a/tests/aot/std-array/003.phpt b/tests/aot/std-array/003.phpt new file mode 100644 index 00000000..a60101ed --- /dev/null +++ b/tests/aot/std-array/003.phpt @@ -0,0 +1,19 @@ +--TEST-- +std array: 003 +--FILE-- + +--EXPECT-- +int(2026) +int(2019)