feat(php): 添加函数调用表达式检测和相关功能支持

- 新增 isCallExpr 方法用于检测函数调用表达式
- 添加 ceWrappers 属性并在闭包生成器中管理其状态
- 添加 lastNativeCall 属性跟踪最后的本地调用
- 实现 resetExpr 方法重置表达式状态
- 更新常量解析中的 get_called_ce 调用
- 在箭头函数解析中添加对 void 返回类型的处理逻辑
- 优化调试信息中 php_file 的设置位置
pull/1/head
韩天峰 6 months ago
parent ed45578ef1
commit f85889fce1
  1. 7
      src/Php/AstNodeType.php
  2. 22
      src/Php/CompilerBase.php
  3. 3
      src/Php/Generator/ClosureGenerator.php

@ -88,4 +88,11 @@ trait AstNodeType
{ {
return $expr instanceof Expr\AssignOp or $expr instanceof Expr\Assign; 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;
}
} }

@ -191,6 +191,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected ?ClassDef $classDef = null; protected ?ClassDef $classDef = null;
protected ?MethodDef $methodDef = null; protected ?MethodDef $methodDef = null;
protected ?InterfaceDef $interfaceDef = null; protected ?InterfaceDef $interfaceDef = null;
protected ?FunctionDef $lastNativeCall = null;
protected array $superGlobalVars = [ protected array $superGlobalVars = [
'_GET' => self::TYPE_ARRAY, '_GET' => self::TYPE_ARRAY,
'_POST' => self::TYPE_ARRAY, '_POST' => self::TYPE_ARRAY,
@ -295,6 +296,7 @@ class CompilerBase extends \PhpAot\Core\Translator
public function parseExpr(mixed $expr) public function parseExpr(mixed $expr)
{ {
$this->resetExpr();
$type = $expr->getType(); $type = $expr->getType();
$this->writeLog('Line ' . $this->getLine($expr) . ': ' . $type); $this->writeLog('Line ' . $this->getLine($expr) . ': ' . $type);
if ($expr->getLine() === $this->debugLine) { if ($expr->getLine() === $this->debugLine) {
@ -563,6 +565,7 @@ class CompilerBase extends \PhpAot\Core\Translator
$this->staticVars = []; $this->staticVars = [];
$this->arguments = []; $this->arguments = [];
$this->objectWrappers = []; $this->objectWrappers = [];
$this->ceWrappers = [];
$this->tmpVarIndex = 0; $this->tmpVarIndex = 0;
$this->inLoop = false; $this->inLoop = false;
$this->function = ''; $this->function = '';
@ -600,6 +603,11 @@ class CompilerBase extends \PhpAot\Core\Translator
$this->namespace = ''; $this->namespace = '';
} }
protected function resetExpr(): void
{
$this->lastNativeCall = null;
}
protected function getFunctionName(FunctionLike $v): string protected function getFunctionName(FunctionLike $v): string
{ {
return $this->getNativeName($this->parseIdentifier($v->name), $this->namespace, $this->class); return $this->getNativeName($this->parseIdentifier($v->name), $this->namespace, $this->class);
@ -2164,6 +2172,7 @@ class CompilerBase extends \PhpAot\Core\Translator
{ {
$argList = []; $argList = [];
$functionDef = $this->nativeFunctions[$nativeFunc]; $functionDef = $this->nativeFunctions[$nativeFunc];
$this->lastNativeCall = $functionDef;
$args = []; $args = [];
$hasNamedArg = false; $hasNamedArg = false;
// 对命名参数进行重排 // 对命名参数进行重排
@ -3617,7 +3626,7 @@ class CompilerBase extends \PhpAot\Core\Translator
if ($const === 'class') { if ($const === 'class') {
return 'php_get_called_class(this_)'; return 'php_get_called_class(this_)';
} else { } 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 protected function parseNativeMethodCall(string $object, string $nativeFunc, array $args): string
{ {
if (count($args) === 0) { if (count($args) === 0) {
$this->lastNativeCall = $this->nativeFunctions[$nativeFunc];
return self::PREFIX . $nativeFunc . '(' . $object . ')'; return self::PREFIX . $nativeFunc . '(' . $object . ')';
} }
return self::PREFIX . $nativeFunc . '(' . $object . ', ' . $this->parseNativeCallArgs($args, $nativeFunc) . ')'; return self::PREFIX . $nativeFunc . '(' . $object . ', ' . $this->parseNativeCallArgs($args, $nativeFunc) . ')';
@ -3957,11 +3967,11 @@ class CompilerBase extends \PhpAot\Core\Translator
$code = ''; $code = '';
if ($this->debugInfo) { if ($this->debugInfo) {
if ($stmt) { 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.php_line = ' . $stmt->getLine() . ';' . PHP_EOL;
$code .= 'php::debug_info.cpp_line = __LINE__;' . PHP_EOL; $code .= 'php::debug_info.cpp_line = __LINE__;' . PHP_EOL;
} else { } else {
$code .= 'php::debug_info.enable = true;' . PHP_EOL; $code .= 'php::debug_info.enable = true;' . PHP_EOL;
$code .= 'php::debug_info.php_file = "' . $this->escapeString($this->file) . '";' . PHP_EOL;
} }
} }
return $code; return $code;
@ -4005,7 +4015,13 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseArrowFunction(Node\Expr\ArrowFunction $expr): string protected function parseArrowFunction(Node\Expr\ArrowFunction $expr): string
{ {
$cb = function () use ($expr) { $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); return $this->genClosure($expr, $expr->params, $cb, [], true);
} }

@ -34,11 +34,13 @@ trait ClosureGenerator
$oriObjects = $this->objects; $oriObjects = $this->objects;
$oriObjectWrappers = $this->objectWrappers; $oriObjectWrappers = $this->objectWrappers;
$oriCeWrappers = $this->ceWrappers;
$oriArgs = $this->arguments; $oriArgs = $this->arguments;
$oriInClosure = $this->inClosure; $oriInClosure = $this->inClosure;
$this->objects = []; $this->objects = [];
$this->objectWrappers = []; $this->objectWrappers = [];
$this->ceWrappers = [];
$this->arguments = []; $this->arguments = [];
$this->inClosure = true; $this->inClosure = true;
@ -90,6 +92,7 @@ trait ClosureGenerator
} }
$this->objects = $oriObjects; $this->objects = $oriObjects;
$this->objectWrappers = $oriObjectWrappers; $this->objectWrappers = $oriObjectWrappers;
$this->ceWrappers = $oriCeWrappers;
$this->arguments = $oriArgs; $this->arguments = $oriArgs;
$this->inClosure = $oriInClosure; $this->inClosure = $oriInClosure;

Loading…
Cancel
Save