feat(php): 添加对box类型的支持

- 在CompilerBase中添加TYPE_BOX常量定义
- 将box类型映射到php::Box类型标识符
- 修改类型解析逻辑以支持box伪类型处理
- 更新gen_stub.php中的类型转换和映射逻辑
- 在StdContainerParser中扩展box类型处理
- 添加box类型到类型搜索顺序数组中
- 实现box类型与其他类型的转换逻辑
pull/1/head
韩天峰 3 months ago
parent 549630e83e
commit 08f90e2df9
  1. 6
      src/Php/CompilerBase.php
  2. 7
      src/Php/Parser/StdContainerParser.php
  3. 3
      src/Php/UniversalMethodCall.php
  4. 14
      src/gen_stub.php
  5. 1
      src/polyfills.php

@ -73,6 +73,7 @@ class CompilerBase extends \PhpAot\Core\Translator
public const string TYPE_BIGINT = 'php::BigInt';
public const string TYPE_DECIMAL = 'php::Decimal';
public const string TYPE_BIGFLOAT = 'php::BigFloat';
public const string TYPE_BOX = 'php::Box';
private const array STREAM_FUNCTIONS = [
'fopen',
@ -173,6 +174,7 @@ class CompilerBase extends \PhpAot\Core\Translator
'bigint' => self::TYPE_BIGINT,
'bigfloat' => self::TYPE_BIGFLOAT,
'decimal' => self::TYPE_DECIMAL,
'box' => self::TYPE_BOX,
];
protected array $globalHeaders = [
'phpx.h',
@ -2699,8 +2701,8 @@ class CompilerBase extends \PhpAot\Core\Translator
}
$class = '';
$type = $this->parseTypeDecl($param->type, self::DECL_TYPE_OF_PARAM, $class);
// stream 是伪类型,实际运行时依然作为 var 处理
if ($type === self::TYPE_STREAM) {
// stream/box 是伪类型,实际运行时依然作为 var 处理
if ($type === self::TYPE_STREAM || $type === self::TYPE_BOX) {
$type = self::TYPE_VAR;
}
if ($class and !$this->hasInterface($class) and !$this->isAbstractClass($class)) {

@ -457,7 +457,7 @@ trait StdContainerParser
protected function getStdContainerElementType(string $type): string
{
return match ($type) {
self::TYPE_BIGINT, self::TYPE_BIGFLOAT, self::TYPE_DECIMAL, self::TYPE_STREAM => self::TYPE_VAR,
self::TYPE_BIGINT, self::TYPE_BIGFLOAT, self::TYPE_DECIMAL, self::TYPE_STREAM, self::TYPE_BOX => self::TYPE_VAR,
default => $type,
};
}
@ -501,6 +501,7 @@ trait StdContainerParser
'type_object' => self::TYPE_OBJECT,
'type_any', 'type_var', 'type_variant' => self::TYPE_VAR,
'type_stream' => self::TYPE_STREAM,
'type_box' => self::TYPE_BOX,
default => $this->fatalError($expr, "An incorrect `{$owner}` definition"),
},
'class' => null,
@ -552,7 +553,7 @@ trait StdContainerParser
$class = $info['class'] ?? null;
if ($class === null) {
$targetType = $info['type'];
if ($targetType === self::TYPE_BIGINT || $targetType === self::TYPE_BIGFLOAT || $targetType === self::TYPE_DECIMAL || $targetType === self::TYPE_STREAM) {
if ($targetType === self::TYPE_BIGINT || $targetType === self::TYPE_BIGFLOAT || $targetType === self::TYPE_DECIMAL || $targetType === self::TYPE_STREAM || $targetType === self::TYPE_BOX) {
return $this->convertStdVarBackedExpr($targetType, $valueExpr, $expr);
}
return $this->convertExprFromType($targetType, $valueExpr);
@ -573,7 +574,7 @@ trait StdContainerParser
if ($sourceType === $targetType) {
return $valueExpr;
}
if ($targetType === self::TYPE_STREAM) {
if ($targetType === self::TYPE_STREAM || $targetType === self::TYPE_BOX) {
return $valueExpr;
}
if ($targetType === self::TYPE_BIGINT) {

@ -347,7 +347,7 @@ trait UniversalMethodCall
private const array MUTATING_HANDLERS = ['direct_method_mutate', 'php_fn_ref'];
private const array TYPE_SEARCH_ORDER = [CompilerBase::TYPE_STR, CompilerBase::TYPE_ARRAY, CompilerBase::TYPE_INT, CompilerBase::TYPE_FLOAT, CompilerBase::TYPE_BOOL, CompilerBase::TYPE_STREAM, CompilerBase::TYPE_BIGINT, CompilerBase::TYPE_DECIMAL, CompilerBase::TYPE_BIGFLOAT];
private const array TYPE_SEARCH_ORDER = [CompilerBase::TYPE_STR, CompilerBase::TYPE_ARRAY, CompilerBase::TYPE_INT, CompilerBase::TYPE_FLOAT, CompilerBase::TYPE_BOOL, CompilerBase::TYPE_STREAM, CompilerBase::TYPE_BIGINT, CompilerBase::TYPE_DECIMAL, CompilerBase::TYPE_BIGFLOAT, CompilerBase::TYPE_BOX];
protected function detectUniversalMethodReturnType(string $type, string $method): ?string
{
@ -382,6 +382,7 @@ trait UniversalMethodCall
CompilerBase::TYPE_BIGINT => 'bigint',
CompilerBase::TYPE_DECIMAL => 'decimal',
CompilerBase::TYPE_BIGFLOAT => 'bigfloat',
CompilerBase::TYPE_BOX => 'box',
];
protected function camelToSnake(string $name): string

@ -269,7 +269,9 @@ class SimpleType {
case "ref":
return new SimpleType(strtolower($typeString), true);
case "any":
return new SimpleType('mixed', true);
return new SimpleType('any', true);
case "box":
return new SimpleType('box', true);
case "array":
return ArrayType::createGenericArray();
case "self":
@ -389,6 +391,8 @@ class SimpleType {
case "callable":
return ["IS_CALLABLE", "MAY_BE_CALLABLE"];
case "mixed":
case "any":
case "box":
return ["IS_MIXED", "MAY_BE_ANY"];
case "void":
return ["IS_VOID", "MAY_BE_VOID"];
@ -449,6 +453,8 @@ class SimpleType {
case "resource":
return "MAY_BE_ARRAY_OF_RESOURCE";
case "mixed":
case "any":
case "box":
return "MAY_BE_ARRAY_OF_ANY";
case "ref":
return "MAY_BE_ARRAY_OF_REF";
@ -470,6 +476,8 @@ class SimpleType {
case "iterable":
return "MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY|MAY_BE_OBJECT";
case "mixed":
case "any":
case "box":
return "MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY";
}
@ -2763,7 +2771,7 @@ class ConstInfo extends VariableLike
{
$type = $this->phpDocType ?? $this->type;
$simpleType = $type ? $type->tryToSimpleType() : null;
if ($simpleType && $simpleType->name === "mixed") {
if ($simpleType && ($simpleType->name === "mixed" || $simpleType->name === "any" || $simpleType->name === "box")) {
$simpleType = null;
}
@ -3037,6 +3045,8 @@ class StringBuilder {
"false" => "ZEND_STR_FALSE",
"null" => "ZEND_STR_NULL_LOWERCASE",
"mixed" => "ZEND_STR_MIXED",
"any" => "ZEND_STR_MIXED",
"box" => "ZEND_STR_MIXED",
];
// NEW in 8.1

@ -25,6 +25,7 @@ class complex_types {
public const type_array = 'array';
public const type_object = 'object';
public const type_stream = 'stream';
public const type_box = 'box';
}
class std

Loading…
Cancel
Save