feat(php): 添加类型声明解析功能并优化变量检查逻辑

- 新增 parseTypeDecl 方法处理联合类型和可空类型
- 将函数返回类型解析改为使用新的类型声明解析方法
- 优化属性访问和数组访问时的变量存在性检查
- 在方法调用时添加变量存在性验证
- 修改属性定义中的类型解析为统一的方法调用
pull/1/head
韩天峰 6 months ago
parent b6e2741c31
commit 9398f18a02
  1. 22
      src/Php/CompilerBase.php
  2. 2
      src/Php/Translator.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);

@ -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);

Loading…
Cancel
Save