From f85889fce19a6c8c19dcc3b153269b884065e027 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 5 Mar 2026 13:24:57 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E8=B0=83=E7=94=A8=E8=A1=A8=E8=BE=BE=E5=BC=8F=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=E5=92=8C=E7=9B=B8=E5=85=B3=E5=8A=9F=E8=83=BD=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 isCallExpr 方法用于检测函数调用表达式 - 添加 ceWrappers 属性并在闭包生成器中管理其状态 - 添加 lastNativeCall 属性跟踪最后的本地调用 - 实现 resetExpr 方法重置表达式状态 - 更新常量解析中的 get_called_ce 调用 - 在箭头函数解析中添加对 void 返回类型的处理逻辑 - 优化调试信息中 php_file 的设置位置 --- src/Php/AstNodeType.php | 7 +++++++ src/Php/CompilerBase.php | 22 +++++++++++++++++++--- src/Php/Generator/ClosureGenerator.php | 3 +++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/Php/AstNodeType.php b/src/Php/AstNodeType.php index 7c87a1d9..1157f976 100644 --- a/src/Php/AstNodeType.php +++ b/src/Php/AstNodeType.php @@ -88,4 +88,11 @@ trait AstNodeType { return $expr instanceof Expr\AssignOp or $expr instanceof Expr\Assign; } + + protected function isCallExpr(NodeAbstract $expr): bool + { + return $expr instanceof Node\Expr\FuncCall + or $expr instanceof Node\Expr\MethodCall + or $expr instanceof Node\Expr\StaticCall; + } } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 0ae0d98d..8477d176 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -191,6 +191,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected ?ClassDef $classDef = null; protected ?MethodDef $methodDef = null; protected ?InterfaceDef $interfaceDef = null; + protected ?FunctionDef $lastNativeCall = null; protected array $superGlobalVars = [ '_GET' => self::TYPE_ARRAY, '_POST' => self::TYPE_ARRAY, @@ -295,6 +296,7 @@ class CompilerBase extends \PhpAot\Core\Translator public function parseExpr(mixed $expr) { + $this->resetExpr(); $type = $expr->getType(); $this->writeLog('Line ' . $this->getLine($expr) . ': ' . $type); if ($expr->getLine() === $this->debugLine) { @@ -563,6 +565,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->staticVars = []; $this->arguments = []; $this->objectWrappers = []; + $this->ceWrappers = []; $this->tmpVarIndex = 0; $this->inLoop = false; $this->function = ''; @@ -600,6 +603,11 @@ class CompilerBase extends \PhpAot\Core\Translator $this->namespace = ''; } + protected function resetExpr(): void + { + $this->lastNativeCall = null; + } + protected function getFunctionName(FunctionLike $v): string { return $this->getNativeName($this->parseIdentifier($v->name), $this->namespace, $this->class); @@ -2164,6 +2172,7 @@ class CompilerBase extends \PhpAot\Core\Translator { $argList = []; $functionDef = $this->nativeFunctions[$nativeFunc]; + $this->lastNativeCall = $functionDef; $args = []; $hasNamedArg = false; // 对命名参数进行重排 @@ -3617,7 +3626,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($const === 'class') { return 'php_get_called_class(this_)'; } else { - return 'php::constant(php_get_called_ce(), ' . $this->getLiteralString($const) . ')'; + return 'php::constant(php_get_called_ce(this_), ' . $this->getLiteralString($const) . ')'; } } @@ -3921,6 +3930,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseNativeMethodCall(string $object, string $nativeFunc, array $args): string { if (count($args) === 0) { + $this->lastNativeCall = $this->nativeFunctions[$nativeFunc]; return self::PREFIX . $nativeFunc . '(' . $object . ')'; } return self::PREFIX . $nativeFunc . '(' . $object . ', ' . $this->parseNativeCallArgs($args, $nativeFunc) . ')'; @@ -3957,11 +3967,11 @@ class CompilerBase extends \PhpAot\Core\Translator $code = ''; if ($this->debugInfo) { if ($stmt) { + $code .= 'php::debug_info.php_file = "' . $this->escapeString($this->file) . '";' . PHP_EOL; $code .= 'php::debug_info.php_line = ' . $stmt->getLine() . ';' . PHP_EOL; $code .= 'php::debug_info.cpp_line = __LINE__;' . PHP_EOL; } else { $code .= 'php::debug_info.enable = true;' . PHP_EOL; - $code .= 'php::debug_info.php_file = "' . $this->escapeString($this->file) . '";' . PHP_EOL; } } return $code; @@ -4005,7 +4015,13 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseArrowFunction(Node\Expr\ArrowFunction $expr): string { $cb = function () use ($expr) { - return 'return ' . $this->parseExpr($expr->expr) . ';'; + $code = $this->parseExpr($expr->expr); + if ($this->isCallExpr($expr->expr)) { + if ($this->lastNativeCall and $this->lastNativeCall->returnType === self::TYPE_VOID) { + return $code . ";\nreturn " . self::VALUE_NULL . ';'; + } + } + return 'return ' . $code . ';'; }; return $this->genClosure($expr, $expr->params, $cb, [], true); } diff --git a/src/Php/Generator/ClosureGenerator.php b/src/Php/Generator/ClosureGenerator.php index 85e11829..a7dde09c 100644 --- a/src/Php/Generator/ClosureGenerator.php +++ b/src/Php/Generator/ClosureGenerator.php @@ -34,11 +34,13 @@ trait ClosureGenerator $oriObjects = $this->objects; $oriObjectWrappers = $this->objectWrappers; + $oriCeWrappers = $this->ceWrappers; $oriArgs = $this->arguments; $oriInClosure = $this->inClosure; $this->objects = []; $this->objectWrappers = []; + $this->ceWrappers = []; $this->arguments = []; $this->inClosure = true; @@ -90,6 +92,7 @@ trait ClosureGenerator } $this->objects = $oriObjects; $this->objectWrappers = $oriObjectWrappers; + $this->ceWrappers = $oriCeWrappers; $this->arguments = $oriArgs; $this->inClosure = $oriInClosure;