refactor(php): 重构PHP编译器中的变量表达式判断逻辑

- 引入AstNodeType trait来统一处理变量表达式判断
- 将原来基于getType()方法的判断改为使用isVarExpr()方法
- 在CompilerBase类中使用新的trait来检测变量表达式
- 更新类型映射表以支持更多PHP类型转换
- 优化变量赋值、函数调用、静态调用等场景下的变量检测逻辑
- 统一代码中多处重复的变量表达式判断逻辑为单一实现
pull/1/head
韩天峰 7 months ago
parent 8e7d39d7fe
commit 9ca07388bc
  1. 13
      src/Php/AstNodeType.php
  2. 27
      src/Php/CompilerBase.php

@ -0,0 +1,13 @@
<?php
namespace PhpAot\Php;
use PhpParser\Node\Expr;
trait AstNodeType
{
protected function isVarExpr(Expr $expr): bool
{
return $expr instanceof Expr\Variable;
}
}

@ -23,6 +23,7 @@ use stdClass;
class CompilerBase extends \PhpAot\Core\Translator
{
use AstNodeType;
public const string TYPE_VAR = 'php::Var';
public const string TYPE_BOOL = 'php::Bool';
public const string TYPE_INT = 'php::Int';
@ -52,8 +53,12 @@ class CompilerBase extends \PhpAot\Core\Translator
'int' => self::TYPE_INT,
'float' => self::TYPE_FLOAT,
'bool' => self::TYPE_BOOL,
'void' => self::TYPE_VOID,
'string' => self::TYPE_STR,
'array' => self::TYPE_ARRAY,
'object' => self::TYPE_OBJECT,
'mixed' => self::TYPE_VAR,
];
protected array $reservedNames;
protected array $globalHeaders = [
'phpx.h',
'phpx_helper.h',
@ -676,7 +681,7 @@ class CompilerBase extends \PhpAot\Core\Translator
$array = $this->parseIdentifier($left->var);
$code = '';
// 这是 PHP 的初始化+赋值写法,需要先创建数组
if (!$this->hasVar($array) and $left->var->getType() === self::EXPR_VARIABLE) {
if (!$this->hasVar($array) and $this->isVarExpr($left->var)) {
$this->addLocalVar($array, self::TYPE_ARRAY);
}
@ -1158,7 +1163,7 @@ class CompilerBase extends \PhpAot\Core\Translator
$var = $this->parseIdentifier($node->var);
$expr = $this->parseIdentifier($node->expr);
$leftExprType = $node->var->getType();
if ($leftExprType === self::EXPR_VARIABLE) {
if ($this->isVarExpr($node->var)) {
if (!$this->hasVar($var)) {
$this->fatalError($node->var, 'Cannot assign to undefined variable');
}
@ -1316,7 +1321,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseFuncCall(Node\Expr\FuncCall $expr, bool $silent = false): string
{
if ($expr->name->getType() === self::EXPR_VARIABLE) {
if ($this->isVarExpr($expr->name)) {
$fn = $this->parseIdentifier($expr->name);
$name = '';
} elseif ($expr->name->getType() === 'Name') {
@ -1373,7 +1378,7 @@ class CompilerBase extends \PhpAot\Core\Translator
$list_args = [];
foreach ($args as $i => $arg) {
if ($arg->value->getType() === self::EXPR_VARIABLE) {
if ($this->isVarExpr($arg->value)) {
$name = $this->parseIdentifier($arg->value);
// 调用了不存在的变量,可能是引用
if (!$this->hasVar($name)) {
@ -2226,12 +2231,12 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseAssignRef(Node\Expr\AssignRef $expr): string
{
if ($expr->var->getType() === self::EXPR_VARIABLE) {
if ($this->isVarExpr($expr->var)) {
$var = $this->parseIdentifier($expr->var);
if (!$this->hasVar($var)) {
$this->addLocalVar($var, self::TYPE_VAR);
}
if ($expr->expr->getType() === self::EXPR_VARIABLE) {
if ($this->isVarExpr($expr->expr)) {
return $var . ' = &' . $this->parseIdentifier($expr->expr);
} elseif ($expr->expr->getType() === self::EXPR_ARRAY_DIM_FETCH) {
return $var . ' = ' . $this->parseIdentifier($expr->expr);
@ -2254,7 +2259,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function identifierToStr(Node $node, bool $require = true): string
{
$id = $this->parseIdentifier($node);
if ($node->getType() === self::EXPR_VARIABLE) {
if ($this->isVarExpr($node)) {
if ($require) {
$this->requireVar($node, $id);
}
@ -2286,7 +2291,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseStaticCall(Node\Expr\StaticCall $expr): string
{
if ($expr->class->getType() === self::EXPR_VARIABLE or $expr->name->getType() === self::EXPR_VARIABLE) {
if ($this->isVarExpr($expr->class) or $this->isVarExpr($expr->name)) {
$fn = 'php::concat({' . $this->identifierToStr($expr->class). ', "::", ' . $this->identifierToStr($expr->name) . '})';
} else {
$class = $this->parseIdentifier($expr->class);
@ -2320,7 +2325,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function parseThrow(mixed $expr): string
{
if ($expr->expr->getType() != self::EXPR_VARIABLE and $expr->expr->getType() != self::EXPR_NEW) {
if (!$this->isVarExpr($expr->expr) and $expr->expr->getType() != self::EXPR_NEW) {
$this->fatalError($expr, 'The throw statement only accepts a object variable');
}
return 'php::throwException(' . $this->parseIdentifier($expr->expr). ')';
@ -2451,7 +2456,7 @@ class CompilerBase extends \PhpAot\Core\Translator
protected function isArrayVar($var): bool
{
return $var->getType() == self::EXPR_VARIABLE and $this->hasVar($var->name) and $this->getVarType($var->name) == self::TYPE_ARRAY;
return $this->isVarExpr($var) and $this->hasVar($var->name) and $this->getVarType($var->name) == self::TYPE_ARRAY;
}
protected function setBuildDir(string $string): void

Loading…
Cancel
Save