refactor(compiler): 重构标准库函数调用解析逻辑

- 提取 std 函数调用解析为独立方法 parseStdCall
- 简化 CompilerBase 中的类型转换处理逻辑
- 优化 gen_stub 中版本特性合并的实现方式
- 修改 getAllFuncInfos 方法返回值类型为数组合并
- 为 std::int 类型声明测试用例添加新断言
pull/1/head
韩天峰 5 months ago
parent 17f4d14940
commit ee8c40698b
  1. 38
      src/Php/CompilerBase.php
  2. 37
      src/gen_stub.php
  3. 5
      tests/aot/operator/assignop_bitwiseor.phpt

@ -1320,21 +1320,11 @@ class CompilerBase extends \PhpAot\Core\Translator
} elseif ($this->isStaticCall($right) and $this->isIdExpr($right->name)) { } elseif ($this->isStaticCall($right) and $this->isIdExpr($right->name)) {
$class = $this->parseIdentifier($right->class); $class = $this->parseIdentifier($right->class);
if ($class === 'std') { if ($class === 'std') {
$func = $this->parseIdentifier($right->name); $valueExpr = $this->parseStdCall($right);
$type = match ($func) { if (!$this->hasVar($var)) {
'int' => self::TYPE_INT, $this->addLocalVar($var, $right->getAttribute('nativeType'));
'float' => self::TYPE_FLOAT,
'bool' => self::TYPE_BOOL,
default => '',
};
// Native 类型
if ($type) {
if (!$this->hasVar($var)) {
$this->addLocalVar($var, $type);
}
$expr = $this->parseExpr($right->args[0]->value);
return $var . ' = ' . $this->convertExprFromType($type, $expr);
} }
return $var . ' = ' . $valueExpr;
} }
} elseif ($this->isVarExpr($right)) { } elseif ($this->isVarExpr($right)) {
$rightVar = $this->parseIdentifier($right); $rightVar = $this->parseIdentifier($right);
@ -4095,6 +4085,8 @@ class CompilerBase extends \PhpAot\Core\Translator
$self = true; $self = true;
} elseif ($class === 'parent') { } elseif ($class === 'parent') {
return $this->parseParentMethodCall($expr); return $this->parseParentMethodCall($expr);
} elseif ($class === 'std') {
return $this->parseStdCall($expr);
} }
$class = $this->getNamespacedClassName($class); $class = $this->getNamespacedClassName($class);
@ -4658,6 +4650,24 @@ class CompilerBase extends \PhpAot\Core\Translator
return $code . "{$obj}.updateArrayProperty({$propName}, {$dim}, {$value})"; return $code . "{$obj}.updateArrayProperty({$propName}, {$dim}, {$value})";
} }
protected function parseStdCall(Expr\StaticCall $expr): string
{
$func = $this->parseIdentifier($expr->name);
$type = match ($func) {
'int' => self::TYPE_INT,
'float' => self::TYPE_FLOAT,
'bool' => self::TYPE_BOOL,
default => '',
};
if ($type) {
$expr->setAttribute('nativeType', $type);
$valueExpr = $this->parseExpr($expr->args[0]->value);
return $this->convertExprFromType($type, $valueExpr);
} else {
$this->fatalError($expr, 'Unknown std method: ' . $func);
}
}
protected function parseParentMethodCall(Expr\StaticCall $expr): string protected function parseParentMethodCall(Expr\StaticCall $expr): string
{ {
$methodStr = $this->classDef->name . '::' . $this->parseIdentifier($expr->name); $methodStr = $this->classDef->name . '::' . $this->parseIdentifier($expr->name);

@ -3119,24 +3119,22 @@ class StringBuilder {
return $result; return $result;
} }
$include = self::PHP_80_KNOWN; $include = self::PHP_80_KNOWN;
switch ($minPhp) {
case PHP_85_VERSION_ID: $versions = [
$include = array_merge($include, self::PHP_85_KNOWN); PHP_85_VERSION_ID => self::PHP_85_KNOWN,
// Intentional fall through PHP_84_VERSION_ID => self::PHP_84_KNOWN,
PHP_82_VERSION_ID => self::PHP_82_KNOWN, // 8.3 合并到 8.2
case PHP_84_VERSION_ID: PHP_81_VERSION_ID => self::PHP_81_KNOWN,
$include = array_merge($include, self::PHP_84_KNOWN); ];
// Intentional fall through
krsort($versions);
case PHP_83_VERSION_ID:
case PHP_82_VERSION_ID: foreach ($versions as $versionId => $knownItems) {
$include = array_merge($include, self::PHP_82_KNOWN); if ($minPhp >= $versionId) {
// Intentional fall through $include = array_merge($include, $knownItems);
}
case PHP_81_VERSION_ID:
$include = array_merge($include, self::PHP_81_KNOWN);
break;
} }
if (array_key_exists($content, $include)) { if (array_key_exists($content, $include)) {
$knownStr = $include[$content]; $knownStr = $include[$content];
return [ return [
@ -4279,10 +4277,11 @@ class FileInfo {
*/ */
public function getAllFuncInfos(): iterable public function getAllFuncInfos(): iterable
{ {
$allFuncInfos = [];
foreach ($this->classInfos as $classInfo) { foreach ($this->classInfos as $classInfo) {
yield from $classInfo->funcInfos; $allFuncInfos = array_merge($allFuncInfos, $classInfo->funcInfos);
} }
yield from $this->funcInfos; return array_merge($allFuncInfos, $this->funcInfos);
} }
/** @return array<string, ConstInfo> */ /** @return array<string, ConstInfo> */

@ -7,7 +7,12 @@ function main()
$a = 100; $a = 100;
$a |= 16; $a |= 16;
var_dump($a); var_dump($a);
$b = std::int(200);
$b |= std::int(32);
var_dump($b);
} }
?> ?>
--EXPECT-- --EXPECT--
int(116) int(116)
int(232)

Loading…
Cancel
Save