From e0f6de84808f22a77a126e540c1319aaad074fe8 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Thu, 18 Jun 2026 16:38:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(aot):=20=E6=B7=BB=E5=8A=A0=E5=AF=B9any?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=A3=B0=E6=98=8E=E7=9A=84=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=B9=B6=E4=BC=98=E5=8C=96=E5=8F=82=E6=95=B0=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了012、013、014测试用例验证类型声明功能 - 将any类型作为内置伪类型处理,映射为mixed类型 - 支持方法签名中的any返回类型注解 - 实现PHPDoc类型与实际类型的合并处理逻辑 - 为非可变参数函数自动添加尾随可变参数支持 - 修复了回调函数传递额外参数时的类型处理问题 --- src/gen_stub.php | 31 ++++++++++++++++++++++--------- tests/aot/type_decl/012.phpt | 23 +++++++++++++++++++++++ tests/aot/type_decl/013.phpt | 17 +++++++++++++++++ tests/aot/type_decl/014.phpt | 18 ++++++++++++++++++ 4 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 tests/aot/type_decl/012.phpt create mode 100644 tests/aot/type_decl/013.phpt create mode 100644 tests/aot/type_decl/014.phpt diff --git a/src/gen_stub.php b/src/gen_stub.php index c4b7a8ac..f7cac0f3 100755 --- a/src/gen_stub.php +++ b/src/gen_stub.php @@ -230,9 +230,9 @@ class SimpleType { $name = $node->toLowerString(); - // stream/box are compiler pseudo-types, treated like resource (mixed in arginfo) - if ($name === 'stream' || $name === 'box') { - return new SimpleType($name, true); + // stream/box/any are compiler pseudo-types, treated like resource (mixed in arginfo) + if ($name === 'stream' || $name === 'box' || $name === 'any') { + return new SimpleType('mixed', true); } $class = $node->isFullyQualified() ? $node->toString() : getTranslator()->getNamespacedClassName($node->toString()); @@ -274,7 +274,7 @@ class SimpleType { case "ref": return new SimpleType(strtolower($typeString), true); case "any": - return new SimpleType('any', true); + return new SimpleType('mixed', true); case "box": case "stream": return new SimpleType($typeString, true); @@ -1172,15 +1172,16 @@ class ReturnInfo { * based on the PHP version. Separate to allow using early returns */ private function beginArgInfoCompatible(string $funcInfoName, int $minArgs): string { - if ($this->type !== null) { - if (null !== $simpleReturnType = $this->type->tryToSimpleType()) { + $effectiveType = $this->type ?? $this->phpDocType; + if ($effectiveType !== null) { + if (null !== $simpleReturnType = $effectiveType->tryToSimpleType()) { if ($simpleReturnType->isBuiltin) { return sprintf( "%s(%s, %d, %d, %s, %d)\n", $this->tentativeReturnType ? "ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX" : "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX", $funcInfoName, $this->byRef, $minArgs, - $simpleReturnType->toTypeCode(), $this->type->isNullable() + $simpleReturnType->toTypeCode(), $effectiveType->isNullable() ); } return sprintf( @@ -1188,10 +1189,10 @@ class ReturnInfo { $this->tentativeReturnType ? "ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX" : "ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX", $funcInfoName, $this->byRef, $minArgs, - $simpleReturnType->toEscapedName(), $this->type->isNullable() + $simpleReturnType->toEscapedName(), $effectiveType->isNullable() ); } - $arginfoType = $this->type->toArginfoType(); + $arginfoType = $effectiveType->toArginfoType(); if ($arginfoType->hasClassType()) { return sprintf( "%s(%s, %d, %d, %s, %s)\n", @@ -2251,6 +2252,18 @@ OUPUT_EXAMPLE $code .= $argInfo->toZendInfo(); } + // Add trailing variadic to accept extra callback arguments (e.g. array_all passes value + key) + $hasVariadic = false; + foreach ($this->args as $argInfo) { + if ($argInfo->isVariadic) { + $hasVariadic = true; + break; + } + } + if (!$hasVariadic) { + $code .= "\tZEND_ARG_VARIADIC_INFO(0, _extra_args)\n"; + } + $code .= "ZEND_END_ARG_INFO()"; return $code . "\n"; } diff --git a/tests/aot/type_decl/012.phpt b/tests/aot/type_decl/012.phpt new file mode 100644 index 00000000..0673e1d8 --- /dev/null +++ b/tests/aot/type_decl/012.phpt @@ -0,0 +1,23 @@ +--TEST-- +Type Declarations +--FILE-- + 1, + "b" => 2, + "c" => 3, + "d" => 4, + "e" => 5, + ]; + var_dump(array_all($array1, "SmallerTenClass::smallerTen")); +} +?> +--EXPECT-- +bool(true) \ No newline at end of file diff --git a/tests/aot/type_decl/013.phpt b/tests/aot/type_decl/013.phpt new file mode 100644 index 00000000..cc715c68 --- /dev/null +++ b/tests/aot/type_decl/013.phpt @@ -0,0 +1,17 @@ +--TEST-- +Type Declarations +--FILE-- + +--EXPECT-- +string(20) "SmallerTenClass::foo" \ No newline at end of file diff --git a/tests/aot/type_decl/014.phpt b/tests/aot/type_decl/014.phpt new file mode 100644 index 00000000..a5105f2a --- /dev/null +++ b/tests/aot/type_decl/014.phpt @@ -0,0 +1,18 @@ +--TEST-- +Type Declarations +--FILE-- + +--EXPECT-- +string(20) "SmallerTenClass::foo" +NULL \ No newline at end of file