diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 2c803036..2614913b 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.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)) { diff --git a/src/Php/Parser/StdContainerParser.php b/src/Php/Parser/StdContainerParser.php index 2f793e98..47cb92d6 100644 --- a/src/Php/Parser/StdContainerParser.php +++ b/src/Php/Parser/StdContainerParser.php @@ -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) { diff --git a/src/Php/UniversalMethodCall.php b/src/Php/UniversalMethodCall.php index 99107f80..1938eb42 100644 --- a/src/Php/UniversalMethodCall.php +++ b/src/Php/UniversalMethodCall.php @@ -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 diff --git a/src/gen_stub.php b/src/gen_stub.php index bcf8cd16..9e8928d1 100755 --- a/src/gen_stub.php +++ b/src/gen_stub.php @@ -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 diff --git a/src/polyfills.php b/src/polyfills.php index d5f6332d..a7dac262 100644 --- a/src/polyfills.php +++ b/src/polyfills.php @@ -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