From af9ecf336f39d6f641209dc4b2d0acc796162987 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 13 Jan 2026 19:43:21 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E5=92=8C=E5=87=BD=E6=95=B0=E4=B8=8A=E4=B8=8B=E6=96=87?= =?UTF-8?q?=E8=B7=9F=E8=B8=AA=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 method 和 function 属性用于跟踪当前解析的方法和函数名 - 在解析函数时设置函数名并清空函数上下文 - 实现类中 this_ 参数的自动注入 - 添加魔术常量 Method 和 Function 的支持 - 实现父类方法调用的特殊处理逻辑 - 添加静态变量赋值引用的变量声明 - 实现 __call 魔术方法参数验证 - 重构注释生成逻辑到独立方法 - 启用 noLiteralStrings 优化选项 --- src/Php/CompilerBase.php | 60 ++++++++++++++++++++++++++++++++-------- src/Php/Translator.php | 9 ++++++ 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 577e640a..7b7a87a1 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -77,6 +77,8 @@ class CompilerBase extends \PhpAot\Core\Translator protected string $file; protected string $dir; protected string $namespace = ''; + protected string $method = ''; + protected string $function = ''; protected array $useNamespaces = []; protected array $useFunctions = []; protected string $class = ''; @@ -242,6 +244,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseFunction(Node\FunctionLike $v): string { $this->resetScope(); + $this->function = $this->parseIdentifier($v->name); $name = $this->getFunctionName($v); if (isset($this->nativeFunctions[$name])) { $this->functionDef = $this->nativeFunctions[$name]; @@ -254,6 +257,11 @@ class CompilerBase extends \PhpAot\Core\Translator } } + if ($this->class) { + $this->arguments['this_'] = self::TYPE_OBJECT; + $this->addLocalVar('this_', self::TYPE_OBJECT); + } + foreach ($this->functionDef->argInfoList as $argInfo) { $this->arguments[$argInfo->name] = $argInfo->type; if (!$this->hasLocalVar($argInfo->name)) { @@ -261,10 +269,6 @@ class CompilerBase extends \PhpAot\Core\Translator } } - if ($this->class) { - $this->arguments['this_'] = self::TYPE_OBJECT; - } - if ($v->stmts) { $this->indentLevel++; $stmts = $this->parseStmts($v->stmts); @@ -295,6 +299,8 @@ class CompilerBase extends \PhpAot\Core\Translator $code .= $stmts; $code .= "}\n"; + $this->function = ''; + return $code; } @@ -371,6 +377,14 @@ class CompilerBase extends \PhpAot\Core\Translator $functionDef->params = implode(', ', $list); } + protected function getComment(Node\Stmt $v, string $class): string + { + if ($class == 'Stmt_Expression') { + $class = 'Stmt_Expression(' . $v->expr->getType() . ')'; + } + return $this->getIndent() . '// ' . $class . ' [' . $v->getStartLine() . ':' . $v->getEndLine() . ']'; + } + protected function parseStmts(array $stmts): string { $lines = []; @@ -379,7 +393,8 @@ class CompilerBase extends \PhpAot\Core\Translator $this->beforeStmtLines = []; $this->afterStmtLines = []; $this->writeLog('Line ' . $this->getLine($v) . ': ' . $class); - $lines[] = $this->getIndent() . '// ' . $class . ' [' . $v->getStartLine() . ':' . $v->getEndLine() . ']'; + + $lines[] = $this->getComment($v, $class); switch ($class) { case 'Stmt_Expression': $result = $this->parseExpr($v->expr) . ';'; @@ -605,6 +620,7 @@ class CompilerBase extends \PhpAot\Core\Translator case 'Scalar_MagicConst_Dir': case 'Scalar_MagicConst_Line': case 'Scalar_MagicConst_Function': + case 'Scalar_MagicConst_Method': case 'Scalar_MagicConst_Class': return $this->parseMagicConst($expr); case 'Scalar_InterpolatedString': @@ -1905,9 +1921,11 @@ class CompilerBase extends \PhpAot\Core\Translator case 'Scalar_MagicConst_Line': return (string)$expr->getStartLine(); case 'Scalar_MagicConst_Function': - return '"' . $this->escapeString($this->functionDef->name) . '"'; + return '"' . $this->escapeString($this->function) . '"'; case 'Scalar_MagicConst_Class': - return '"' . $this->escapeString($this->classDef->name) . '"'; + return '"' . $this->escapeString($this->class) . '"'; + case 'Scalar_MagicConst_Method': + return '"' . $this->escapeString($this->class) . '::' . $this->escapeString($this->method) . '"'; default: abort($expr); } @@ -2192,10 +2210,14 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseAssignRef(Node\Expr\AssignRef $expr): string { if ($expr->var->getType() === self::EXPR_VARIABLE) { + $var = $this->parseIdentifier($expr->var); + if (!$this->hasVar($var)) { + $this->addLocalVar($var, self::TYPE_VAR); + } if ($expr->expr->getType() === self::EXPR_VARIABLE) { - return $this->parseIdentifier($expr->var) . ' = &' . $this->parseIdentifier($expr->expr); + return $var . ' = &' . $this->parseIdentifier($expr->expr); } elseif ($expr->expr->getType() === self::EXPR_ARRAY_DIM_FETCH) { - return $this->parseIdentifier($expr->var) . ' = ' . $this->parseIdentifier($expr->expr); + return $var . ' = ' . $this->parseIdentifier($expr->expr); } } abort($expr); @@ -2235,13 +2257,27 @@ class CompilerBase extends \PhpAot\Core\Translator } } - protected function parseStaticCall(mixed $expr): string + private function parseParentMethodCall(Node\Expr\StaticCall $expr): string + { + $method = $this->identifierToStr($expr->name); + if (empty($expr->args)) { + return 'this_.callParentMethod(' . $method . ')'; + } else { + return 'this_.callParentMethod(' . $method . ', {' . $this->parseCallArgs($expr->args) . '})'; + } + } + + protected function parseStaticCall(Node\Expr\StaticCall $expr): string { if ($expr->class->getType() === self::EXPR_VARIABLE or $expr->name->getType() === self::EXPR_VARIABLE) { $fn = 'php::concat({' . $this->identifierToStr($expr->class). ', "::", ' . $this->identifierToStr($expr->name) . '})'; } else { $class = $this->parseIdentifier($expr->class); - $class = $class === 'self' ? $this->class : $class; + if ($class === 'self') { + $class = $this->class; + } elseif ($class === 'parent') { + return $this->parseParentMethodCall($expr); + } $method = $this->parseIdentifier($expr->name); $fn = '"' . $class . '::' . $method . '"'; } @@ -2508,4 +2544,6 @@ class CompilerBase extends \PhpAot\Core\Translator } abort($expr); } + + } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 3de04a79..f5c2a795 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -64,6 +64,8 @@ class Translator extends Preprocessor $this->preprocessArgvAdvanced(); $this->climate->arguments->parse(); $this->optimizeLevel = $this->climate->arguments->get('optimize'); +// $this->noLiteralStrings = $this->climate->arguments->get('noLiteralStrings'); + $this->noLiteralStrings = true; $this->internalFunctions = array_flip(get_defined_functions()['internal']); if ($this->climate->arguments->defined('help')) { $this->showUsage(); @@ -661,9 +663,16 @@ class Translator extends Preprocessor private function parseClassMethod(Node\Stmt\ClassMethod $v, array &$methodCodes): void { $name = $this->getMethodName($v); + $this->method = $name; $methodCodes[$name] = $this->parseFunction($v); $methodDef = new MethodDef($v->flags, $name, $this->functionDef); + if ($name == '__call') { + if (count($methodDef->functionDef->argInfoList) != 2) { + $this->fatalError($v, 'Method ' . $this->class . '::__call() must take exactly 2 arguments'); + } + } $this->classDef->methods[$name] = $methodDef; + $this->method = ''; } private function parseIdentifierList(array $implements): array