From 9398f18a02564b442009310ec122c2a2d7b69202 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 26 Feb 2026 17:04:45 +0800 Subject: [PATCH] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=A3=B0=E6=98=8E=E8=A7=A3=E6=9E=90=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E5=8F=98=E9=87=8F=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 parseTypeDecl 方法处理联合类型和可空类型 - 将函数返回类型解析改为使用新的类型声明解析方法 - 优化属性访问和数组访问时的变量存在性检查 - 在方法调用时添加变量存在性验证 - 修改属性定义中的类型解析为统一的方法调用 --- src/Php/CompilerBase.php | 22 ++++++++++++++++++---- src/Php/Translator.php | 2 +- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index d64ac06c..2beea009 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -695,14 +695,25 @@ class CompilerBase extends \PhpAot\Core\Translator return 'php_get_method(' . $funcId . ', ' . $this->getLiteralString($method) . ', ' . $classId . ', ' . $this->getLiteralString($class) . ')'; } + protected function parseTypeDecl(NodeAbstract|null $type): string + { + // 联合类型暂时不支持,使用 var 类型代替 + if ($type instanceof Node\UnionType or $type instanceof NullableType) { + return self::TYPE_VAR; + } else { + return $type ? $this->getTypeFromZendType($this->parseIdentifier($type)) : self::TYPE_VOID; + } + } + protected function parseFunctionDeclaration(Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef { // .stub 存根定义 C++ Native 函数,必须设置返回值类型 if (!$v->returnType && $this->stubFile) { throw new \Exception('No return type for ' . $v->name); } + $fnName = $this->parseIdentifier($v->name); - $returnType = $v->returnType ? $this->getTypeFromZendType($this->parseIdentifier($v->returnType)) : self::TYPE_VOID; + $returnType = $this->parseTypeDecl($v->returnType); $functionDef = new FunctionDef($fnName, $returnType, $this->namespace); $this->functionDef = $functionDef; @@ -2034,7 +2045,7 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$this->hasVar($name)) { $this->fatalError($arg, 'Undefined variable `$' . $name . '`'); } - } elseif ($this->isPropertyFetch($arg->value)) { + } elseif ($this->isPropertyFetch($arg->value) and $this->isVarExpr($arg->value->var)) { $obj = $this->parseIdentifier($arg->value->var); if (!$this->hasVar($obj)) { $this->fatalError($arg, 'Undefined variable `$' . $obj . '`'); @@ -2043,7 +2054,7 @@ class CompilerBase extends \PhpAot\Core\Translator $list_args[] = $obj . '.attrRef(' . $this->identifierToStr($arg->value->name) . ')'; continue; } - } elseif ($this->isArrayDimFetch($arg->value)) { + } elseif ($this->isArrayDimFetch($arg->value) and $this->isVarExpr($arg->value->var)) { $array = $this->parseIdentifier($arg->value->var); if ($this->isVarExpr($arg->value->var) and !$this->hasVar($array)) { $this->fatalError($arg, 'Undefined variable `$' . $array . '`'); @@ -3190,7 +3201,10 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseMethodCall(Node\Expr\MethodCall $expr): string { if ($this->isVarExpr($expr->var)) { - $this->errorUndefinedVariable($expr->var); + $var = $this->parseIdentifier($expr->var); + if (!$this->hasVar($var)) { + $this->errorUndefinedVariable($expr->var); + } } $object = $this->convertToObject($expr->var); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 7fb32ac1..525093ce 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -896,7 +896,7 @@ class Translator extends Preprocessor protected function parsePropertyDef(Node\Stmt\Property $v): void { $flags = $v->flags; - $type = $v->type ? $this->getTypeFromZendType($this->parseIdentifier($v->type)) : self::TYPE_VAR; + $type = $this->parseTypeDecl($v->type); foreach ($v->props as $prop) { $propDef = new PropertyDef($this->parseIdentifier($prop->name), $flags, $type);