From 215f5cdcacb5c22816e03a797dae1495cd48f47c Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Sat, 20 Jun 2026 20:48:07 +0800 Subject: [PATCH] =?UTF-8?q?feat(stub):=20=E6=B7=BB=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E6=8E=A8=E6=96=ADPHP=E6=96=87=E6=A1=A3=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E7=9A=84=E5=A4=84=E7=90=86=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在ArgInfo构造函数中添加isInferredPhpDocType参数,默认值为false - 修改beginArgInfoCompatible方法中的有效类型判断逻辑 - 移除未使用的可变参数代码逻辑 - 更新默认参数类型和返回类型推断处理 - 添加mixed类型函数示例文件 - 修复预处理器中参数类型检查的空值判断问题 - 添加void返回类型的基本测试用例 --- examples/mixed.php | 9 +++++++ src/Php/Preprocessor.php | 2 +- src/gen_stub.php | 43 +++++++++++++++++++------------- tests/aot/basic/return-void.phpt | 16 ++++++++++++ 4 files changed, 52 insertions(+), 18 deletions(-) create mode 100644 examples/mixed.php create mode 100644 tests/aot/basic/return-void.phpt diff --git a/examples/mixed.php b/examples/mixed.php new file mode 100644 index 00000000..2819f376 --- /dev/null +++ b/examples/mixed.php @@ -0,0 +1,9 @@ +byRef = $param->byRef; $argInfo->variadic = $param->variadic; $argInfo->property = $param->isPromoted(); - if ($param->type and $param->type instanceof NullableType) { + if ($param->type === null || $param->type instanceof NullableType) { $argInfo->nullable = true; } if ($param->type instanceof NullableType or $param->type instanceof UnionType) { diff --git a/src/gen_stub.php b/src/gen_stub.php index b3cbe908..cae09295 100755 --- a/src/gen_stub.php +++ b/src/gen_stub.php @@ -1110,12 +1110,21 @@ class ReturnInfo { public /* readonly */ ?Type $phpDocType; public /* readonly */ bool $tentativeReturnType; public /* readonly */ string $refcount; + private bool $isInferredPhpDocType; - public function __construct(bool $byRef, ?Type $type, ?Type $phpDocType, bool $tentativeReturnType, ?string $refcount) { + public function __construct( + bool $byRef, + ?Type $type, + ?Type $phpDocType, + bool $tentativeReturnType, + ?string $refcount, + bool $isInferredPhpDocType = false + ) { $this->byRef = $byRef; $this->type = $type; $this->phpDocType = $phpDocType; $this->tentativeReturnType = $tentativeReturnType; + $this->isInferredPhpDocType = $isInferredPhpDocType; $this->setRefcount($refcount); } @@ -1172,7 +1181,7 @@ class ReturnInfo { * based on the PHP version. Separate to allow using early returns */ private function beginArgInfoCompatible(string $funcInfoName, int $minArgs): string { - $effectiveType = $this->type ?? $this->phpDocType; + $effectiveType = $this->type ?? ($this->isInferredPhpDocType ? null : $this->phpDocType); if ($effectiveType !== null) { if (null !== $simpleReturnType = $effectiveType->tryToSimpleType()) { if ($simpleReturnType->isBuiltin) { @@ -2252,18 +2261,6 @@ 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"; } @@ -4991,7 +4988,11 @@ function parseFunctionLike( $type = $param->type ? Type::fromNode($param->type) : null; if ($type === null && !isset($docParamTypes[$varName])) { $defaultParamType = getMagicMethodDefaultParamType($name, $i); - $type = Type::fromString($defaultParamType ?? 'mixed'); + if ($defaultParamType !== null) { + $type = Type::fromString($defaultParamType); + } else { + $docParamTypes[$varName] = 'mixed'; + } } if ($param->default instanceof Expr\ConstFetch && @@ -5034,8 +5035,15 @@ function parseFunctionLike( } $returnType = $func->getReturnType(); + $isInferredReturnType = false; if ($returnType === null && $docReturnType === null && !$name->isConstructor() && !$name->isDestructor()) { - $docReturnType = getMagicMethodDefaultReturnType($name) ?? 'mixed'; + $defaultReturnType = getMagicMethodDefaultReturnType($name); + if ($defaultReturnType !== null) { + $docReturnType = $defaultReturnType; + } else { + $docReturnType = 'mixed'; + $isInferredReturnType = true; + } } $return = new ReturnInfo( @@ -5043,7 +5051,8 @@ function parseFunctionLike( $returnType ? Type::fromNode($returnType) : null, $docReturnType ? Type::fromString($docReturnType) : null, $tentativeReturnType, - $refcount + $refcount, + $isInferredReturnType ); return new FuncInfo( diff --git a/tests/aot/basic/return-void.phpt b/tests/aot/basic/return-void.phpt new file mode 100644 index 00000000..3523f235 --- /dev/null +++ b/tests/aot/basic/return-void.phpt @@ -0,0 +1,16 @@ +--TEST-- +main function +--FILE-- + +--EXPECT-- +string(3) "foo" \ No newline at end of file