From 8865796b431437d032da5a9722100561637e7745 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 16 Apr 2026 16:27:47 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E5=AE=9E=E7=8E=B0=20compact=20?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E6=94=AF=E6=8C=81=E5=B9=B6=E5=A2=9E=E5=BC=BA?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E9=87=8D=E5=AE=9A=E4=B9=89=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 compact 函数的功能实现和语法优化 - 移除 UNSUPPORTED_FUNCTIONS 列表中的 compact 条目 - 在 Preprocessor 中添加防止重定义内置函数的检查 - 实现 genCompact 方法来处理 compact 函数调用 - 添加测试用例验证 compact 函数功能正确性 - 增强错误处理机制以捕获非法变量使用情况 --- src/Php/Constants.php | 1 - src/Php/FuncCallOptimizer.php | 28 ++++++++++++++++++++++++++++ src/Php/Preprocessor.php | 4 ++++ tests/aot/functions/compact.phpt | 22 ++++++++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 tests/aot/functions/compact.phpt diff --git a/src/Php/Constants.php b/src/Php/Constants.php index 5e7fd3ca..b028dcb5 100644 --- a/src/Php/Constants.php +++ b/src/Php/Constants.php @@ -58,7 +58,6 @@ class Constants ]; public const UNSUPPORTED_FUNCTIONS = [ - 'compact', 'extract', ]; } diff --git a/src/Php/FuncCallOptimizer.php b/src/Php/FuncCallOptimizer.php index cf66b2a8..edc124c6 100644 --- a/src/Php/FuncCallOptimizer.php +++ b/src/Php/FuncCallOptimizer.php @@ -126,6 +126,9 @@ trait FuncCallOptimizer return 'true'; } } + if ($name === 'compact') { + return $this->genCompact($expr); + } if ($name === 'get_class') { return $this->genGetClass($expr); } @@ -166,4 +169,29 @@ trait FuncCallOptimizer } return 'php::fn::get_class(' . $this->parseIdentifier($object) . ')'; } + + protected function genCompact(Node\Expr\FuncCall $expr): string + { + $list = []; + + $this->indentLevel++; + foreach ($expr->args as $arg) { + if (!$this->isScalarString($arg->value)) { + $this->fatalError($expr, 'The argument of compact function can only be literal string'); + } + $var = $arg->value->value; + if (!$this->hasVar($var)) { + $this->errorUndefinedVariable($var); + } + if ($this->isSuperGlobal($var)) { + $this->fatalError($expr, 'Cannot use super global variable `' . $var . '` in compact function'); + } + + $key = $this->getLiteralString($var); + $list[] = $this->getIndent() . '{ ' . $key . '.str(), ' . $var . ' }'; + } + $this->indentLevel--; + + return $this->genArray($list); + } } diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index a5901523..2f189b03 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -369,6 +369,10 @@ class Preprocessor extends CompilerBase if ($this->hasFunction($name)) { $this->fatalError($v, "Duplicate function `{$name}`"); } + // 禁止重定义内置函数 + if (!$this->methodDef and $this->isInternalFunction($name)) { + $this->fatalError($v, "The function `{$name}` is a built-in function and cannot be redefined"); + } $functionDef = $this->parseFunctionDecl($v); $this->addFunction($name, $functionDef); if ($this->methodDef) { diff --git a/tests/aot/functions/compact.phpt b/tests/aot/functions/compact.phpt new file mode 100644 index 00000000..1715d11d --- /dev/null +++ b/tests/aot/functions/compact.phpt @@ -0,0 +1,22 @@ +--TEST-- +compact +--FILE-- + +--EXPECT-- +array(3) { + ["event"]=> + string(8) "SIGGRAPH" + ["city"]=> + string(13) "San Francisco" + ["state"]=> + string(2) "CA" +} \ No newline at end of file