feat(aot): 添加对any类型声明的支持并优化参数信息生成

- 添加了012、013、014测试用例验证类型声明功能
- 将any类型作为内置伪类型处理,映射为mixed类型
- 支持方法签名中的any返回类型注解
- 实现PHPDoc类型与实际类型的合并处理逻辑
- 为非可变参数函数自动添加尾随可变参数支持
- 修复了回调函数传递额外参数时的类型处理问题
pull/3/head
韩天峰 2 months ago
parent cba9990e80
commit e0f6de8480
  1. 31
      src/gen_stub.php
  2. 23
      tests/aot/type_decl/012.phpt
  3. 17
      tests/aot/type_decl/013.phpt
  4. 18
      tests/aot/type_decl/014.phpt

@ -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";
}

@ -0,0 +1,23 @@
--TEST--
Type Declarations
--FILE--
<?php
class SmallerTenClass {
public static function smallerTen($input) {
return $input < 10;
}
}
function main() {
$array1 = [
"a" => 1,
"b" => 2,
"c" => 3,
"d" => 4,
"e" => 5,
];
var_dump(array_all($array1, "SmallerTenClass::smallerTen"));
}
?>
--EXPECT--
bool(true)

@ -0,0 +1,17 @@
--TEST--
Type Declarations
--FILE--
<?php
class SmallerTenClass {
public static function foo($input): any {
return __METHOD__;
}
}
function main() {
$fn = "SmallerTenClass::foo";
var_dump($fn(10));
}
?>
--EXPECT--
string(20) "SmallerTenClass::foo"

@ -0,0 +1,18 @@
--TEST--
Type Declarations
--FILE--
<?php
class SmallerTenClass {
public static function foo($input) {
var_dump(__METHOD__);
}
}
function main() {
$fn = "SmallerTenClass::foo";
var_dump($fn(10));
}
?>
--EXPECT--
string(20) "SmallerTenClass::foo"
NULL
Loading…
Cancel
Save