From 7dd30e2908ed2a9dbcc2f6be40d6db8171332b36 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 26 Mar 2026 11:35:23 +0800 Subject: [PATCH] =?UTF-8?q?refactor(php):=20=E4=BC=98=E5=8C=96PHP=E7=BC=96?= =?UTF-8?q?=E8=AF=91=E5=99=A8=E4=BB=A3=E7=A0=81=E7=BB=93=E6=9E=84=E5=92=8C?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改clone表达式解析为使用php::clone函数调用 - 更新属性获取表达式的对象转换方式 - 使用checkArgType方法替代直接的类型比较进行魔术方法验证 - 重构预处理器中的方法准备逻辑以跳过抽象方法 - 添加Modifiers导入并改进依赖排序逻辑 - 为genNativeMethod方法参数添加类型声明 --- src/Php/CompilerBase.php | 4 ++-- src/Php/MagicMethodDetector.php | 13 +++++++------ src/Php/Preprocessor.php | 34 ++++++++++++++++++--------------- src/Php/Translator.php | 2 +- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 062b3e24..235e85fd 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -2909,7 +2909,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseClone(Node\Expr\Clone_ $expr): string { - return $this->convertToObject($expr->expr) . '.clone()'; + return 'php::clone('.$this->parseExpr($expr->expr).')'; } protected function parseInstanceof(Node\Expr\Instanceof_ $expr): string @@ -3640,7 +3640,7 @@ class CompilerBase extends \PhpAot\Core\Translator } if ($this->isPropertyFetch($expr->expr)) { $left = $this->parseIdentifier($expr->var); - $object = $this->convertToObject($expr->expr->var); + $object = $this->parseExpr($expr->expr->var); $prop = $this->identifierToStr($expr->expr->name); return $left . ' = ' . $object . '.attrRef(' . $prop . ')'; diff --git a/src/Php/MagicMethodDetector.php b/src/Php/MagicMethodDetector.php index 0078d669..a038a45d 100644 --- a/src/Php/MagicMethodDetector.php +++ b/src/Php/MagicMethodDetector.php @@ -32,33 +32,34 @@ trait MagicMethodDetector $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument"); } } elseif ($nameLower == '__tostring') { - if ($returnType != self::TYPE_VAR and $returnType != self::TYPE_STR) { + if (!$this->checkArgType($returnType, self::TYPE_STR)) { $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return string"); } } elseif ($nameLower == '__serialize') { - if ($returnType != self::TYPE_VAR and $returnType != self::TYPE_ARRAY) { + if (!$this->checkArgType($returnType, self::TYPE_ARRAY)) { $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array"); } } elseif ($nameLower == '__unserialize') { if (count($argInfoList) != 1) { $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument"); - } elseif (!$argInfoList[0]->type or $argInfoList[0]->type != self::TYPE_ARRAY) { + } + if (!$this->checkArgType($argInfoList[0]->type, self::TYPE_ARRAY)) { $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take array as argument"); } } elseif ($nameLower == '__isset' or $nameLower == '__unset' or $nameLower == '__set_state') { if (count($argInfoList) != 1) { $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument"); } - if (!$argInfoList[0]->type or $argInfoList[0]->type != self::TYPE_STR) { + if (!$this->checkArgType($argInfoList[0]->type, self::TYPE_STR)) { $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take string as argument"); } if ($nameLower == '__set_state') { - if (!$returnType or $returnType != self::TYPE_ARRAY) { + if (!$this->checkArgType($returnType, self::TYPE_ARRAY)) { $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array"); } } } elseif ($nameLower == '__debuginfo') { - if (!$returnType or $returnType != self::TYPE_ARRAY) { + if (!$this->checkArgType($returnType, self::TYPE_ARRAY)) { $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array"); } } diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 84e1ea12..0d22c178 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -10,6 +10,7 @@ namespace PhpAot\Php; use MJS\TopSort\Implementations\StringSort; use PhpAot\Php\Exception\SyntaxError; +use PhpParser\Modifiers; use PhpParser\Node; use PhpParser\NodeAbstract; use PhpParser\NodeFinder; @@ -22,6 +23,7 @@ class Preprocessor extends CompilerBase public function sortFiles(array &$list): void { $sorter = new StringSort(); + foreach ($this->symbolCallInFile as $file => $symbols) { $deps = []; foreach ($symbols as $symbol) { @@ -232,22 +234,24 @@ class Preprocessor extends CompilerBase protected function prepareMethod(Node\Stmt\ClassMethod $v): void { - $this->prepareFunction($v) . PHP_EOL; - if ($this->isIdExpr($v->name) or $this->isNameExpr($v->name)) { - $fullClassName = $this->getNamespacedClassName($this->class); - $fullMethodName = $fullClassName . '::' . $v->name; - $this->classMethodOverride[strtolower($fullMethodName)] = false; - // 查找父类是否有同名方法,递归查找 - $fullClassNameLower = strtolower($fullClassName); - while (isset($this->classExtends[$fullClassNameLower])) { - $parentClass = $this->classExtends[$fullClassNameLower]; - $parentMethodLower = strtolower($parentClass . '::' . $v->name); - // 父类有同名方法,子类覆盖了父类方法,这种情况不能直接使用 C++ 函数,而是使用 ZendVM 动态调用 - if (isset($this->classMethodOverride[$parentMethodLower])) { - $this->classMethodOverride[$parentMethodLower] = true; - } - $fullClassNameLower = strtolower($parentClass); + $abstract = $v->flags & Modifiers::ABSTRACT; + if (!$abstract) { + $this->prepareFunction($v) . PHP_EOL; + } + + $fullClassName = $this->getNamespacedClassName($this->class); + $fullMethodName = $fullClassName . '::' . $v->name; + $this->classMethodOverride[strtolower($fullMethodName)] = false; + // 查找父类是否有同名方法,递归查找 + $fullClassNameLower = strtolower($fullClassName); + while (isset($this->classExtends[$fullClassNameLower])) { + $parentClass = $this->classExtends[$fullClassNameLower]; + $parentMethodLower = strtolower($parentClass . '::' . $v->name); + // 父类有同名方法,子类覆盖了父类方法,这种情况不能直接使用 C++ 函数,而是使用 ZendVM 动态调用 + if (isset($this->classMethodOverride[$parentMethodLower])) { + $this->classMethodOverride[$parentMethodLower] = true; } + $fullClassNameLower = strtolower($parentClass); } } } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 632d1232..248df334 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -927,7 +927,7 @@ class Translator extends Preprocessor return $code; } - protected function genNativeMethod($methodCodes): string + protected function genNativeMethod(array $methodCodes): string { $code = ''; $classDef = $this->classDef;