From 029343ebb47d5f5a32c6945c92cb03485f2bde32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Fri, 10 Apr 2026 23:07:14 +0200 Subject: [PATCH] gen_stub: support use statements in stub files Stmt\Use_ and Stmt\GroupUse nodes were not handled in handleStatements(), causing an "Unexpected node" exception when use statements appeared in stub files. Since NameResolver resolves all names to their fully qualified form before handleStatements() runs, these nodes can simply be skipped. --- build/gen_stub.php | 5 +++++ ext/zend_test/test.stub.php | 7 +++++++ ext/zend_test/test_arginfo.h | 23 ++++++++++++++++++++++- ext/zend_test/test_decl.h | 8 ++++---- ext/zend_test/test_legacy_arginfo.h | 20 +++++++++++++++++++- ext/zend_test/tests/gen_stub_test_01.phpt | 12 ++++++++++++ 6 files changed, 69 insertions(+), 6 deletions(-) diff --git a/build/gen_stub.php b/build/gen_stub.php index c189abd03471..eca1ab3e8c13 100755 --- a/build/gen_stub.php +++ b/build/gen_stub.php @@ -4261,6 +4261,11 @@ private function handleStatements(array $stmts, PrettyPrinterAbstract $prettyPri continue; } + if ($stmt instanceof Stmt\Use_ || $stmt instanceof Stmt\GroupUse) { + // use statements are resolved by NameResolver before this point + continue; + } + if ($stmt instanceof Stmt\Const_) { foreach ($stmt->consts as $const) { $this->constInfos[] = parseConstLike( diff --git a/ext/zend_test/test.stub.php b/ext/zend_test/test.stub.php index f4844eb0681f..c9d367d5553f 100644 --- a/ext/zend_test/test.stub.php +++ b/ext/zend_test/test.stub.php @@ -380,6 +380,10 @@ public function method(): ?NotUnlikelyCompileError {} namespace ZendTestNS2 { + use ZendTestNS\Foo as FooAlias; + use ZendTestNS\UnlikelyCompileError; + use ZendTestNS\{NotUnlikelyCompileError}; + /** @var string */ const ZEND_CONSTANT_A = "namespaced"; @@ -387,6 +391,9 @@ class Foo { public ZendSubNS\Foo $foo; public ZendSubNS\Foo&\ZendTestNS\Bar $intersectionProp; public ZendSubNS\Foo|\ZendTestNS\Bar $unionProp; + public FooAlias $fooAlias; + public UnlikelyCompileError $unlProp; + public NotUnlikelyCompileError $notUnlProp; public function method(): void {} } diff --git a/ext/zend_test/test_arginfo.h b/ext/zend_test/test_arginfo.h index d2bdbd72db47..a4da05df2ffb 100644 --- a/ext/zend_test/test_arginfo.h +++ b/ext/zend_test/test_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit test.stub.php instead. - * Stub hash: 9a23b7d5305982930579428a345ded725ff5145f + * Stub hash: dcb089a336c6c3e6c685762057dcedcb393508a7 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_trigger_bailout, 0, 0, IS_NEVER, 0) @@ -1376,6 +1376,27 @@ static zend_class_entry *register_class_ZendTestNS2_Foo(void) zend_declare_typed_property(class_entry, property_unionProp_name, &property_unionProp_default_value, ZEND_ACC_PUBLIC, NULL, property_unionProp_type); zend_string_release_ex(property_unionProp_name, true); + zval property_fooAlias_default_value; + ZVAL_UNDEF(&property_fooAlias_default_value); + zend_string *property_fooAlias_name = zend_string_init("fooAlias", sizeof("fooAlias") - 1, true); + zend_string *property_fooAlias_class_ZendTestNS_Foo = zend_string_init("ZendTestNS\\Foo", sizeof("ZendTestNS\\Foo")-1, 1); + zend_declare_typed_property(class_entry, property_fooAlias_name, &property_fooAlias_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_fooAlias_class_ZendTestNS_Foo, 0, 0)); + zend_string_release_ex(property_fooAlias_name, true); + + zval property_unlProp_default_value; + ZVAL_UNDEF(&property_unlProp_default_value); + zend_string *property_unlProp_name = zend_string_init("unlProp", sizeof("unlProp") - 1, true); + zend_string *property_unlProp_class_ZendTestNS_UnlikelyCompileError = zend_string_init("ZendTestNS\\\125nlikelyCompileError", sizeof("ZendTestNS\\\125nlikelyCompileError")-1, 1); + zend_declare_typed_property(class_entry, property_unlProp_name, &property_unlProp_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_unlProp_class_ZendTestNS_UnlikelyCompileError, 0, 0)); + zend_string_release_ex(property_unlProp_name, true); + + zval property_notUnlProp_default_value; + ZVAL_UNDEF(&property_notUnlProp_default_value); + zend_string *property_notUnlProp_name = zend_string_init("notUnlProp", sizeof("notUnlProp") - 1, true); + zend_string *property_notUnlProp_class_ZendTestNS_NotUnlikelyCompileError = zend_string_init("ZendTestNS\\\116otUnlikelyCompileError", sizeof("ZendTestNS\\\116otUnlikelyCompileError")-1, 1); + zend_declare_typed_property(class_entry, property_notUnlProp_name, &property_notUnlProp_default_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_CLASS(property_notUnlProp_class_ZendTestNS_NotUnlikelyCompileError, 0, 0)); + zend_string_release_ex(property_notUnlProp_name, true); + return class_entry; } diff --git a/ext/zend_test/test_decl.h b/ext/zend_test/test_decl.h index 816e03919a13..bc2ebaa93c3b 100644 --- a/ext/zend_test/test_decl.h +++ b/ext/zend_test/test_decl.h @@ -1,8 +1,8 @@ /* This is a generated file, edit test.stub.php instead. - * Stub hash: 9a23b7d5305982930579428a345ded725ff5145f */ + * Stub hash: dcb089a336c6c3e6c685762057dcedcb393508a7 */ -#ifndef ZEND_TEST_DECL_9a23b7d5305982930579428a345ded725ff5145f_H -#define ZEND_TEST_DECL_9a23b7d5305982930579428a345ded725ff5145f_H +#ifndef ZEND_TEST_DECL_dcb089a336c6c3e6c685762057dcedcb393508a7_H +#define ZEND_TEST_DECL_dcb089a336c6c3e6c685762057dcedcb393508a7_H typedef enum zend_enum_ZendTestUnitEnum { ZEND_ENUM_ZendTestUnitEnum_Foo = 1, @@ -27,4 +27,4 @@ typedef enum zend_enum_ZendTestEnumWithInterface { ZEND_ENUM_ZendTestEnumWithInterface_Bar = 2, } zend_enum_ZendTestEnumWithInterface; -#endif /* ZEND_TEST_DECL_9a23b7d5305982930579428a345ded725ff5145f_H */ +#endif /* ZEND_TEST_DECL_dcb089a336c6c3e6c685762057dcedcb393508a7_H */ diff --git a/ext/zend_test/test_legacy_arginfo.h b/ext/zend_test/test_legacy_arginfo.h index b4a07503ad0f..b446a0f9a293 100644 --- a/ext/zend_test/test_legacy_arginfo.h +++ b/ext/zend_test/test_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit test.stub.php instead. - * Stub hash: 9a23b7d5305982930579428a345ded725ff5145f + * Stub hash: dcb089a336c6c3e6c685762057dcedcb393508a7 * Has decl header: yes */ ZEND_BEGIN_ARG_INFO_EX(arginfo_zend_trigger_bailout, 0, 0, 0) @@ -1096,6 +1096,24 @@ static zend_class_entry *register_class_ZendTestNS2_Foo(void) zend_declare_property_ex(class_entry, property_unionProp_name, &property_unionProp_default_value, ZEND_ACC_PUBLIC, NULL); zend_string_release_ex(property_unionProp_name, true); + zval property_fooAlias_default_value; + ZVAL_NULL(&property_fooAlias_default_value); + zend_string *property_fooAlias_name = zend_string_init("fooAlias", sizeof("fooAlias") - 1, true); + zend_declare_property_ex(class_entry, property_fooAlias_name, &property_fooAlias_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_fooAlias_name, true); + + zval property_unlProp_default_value; + ZVAL_NULL(&property_unlProp_default_value); + zend_string *property_unlProp_name = zend_string_init("unlProp", sizeof("unlProp") - 1, true); + zend_declare_property_ex(class_entry, property_unlProp_name, &property_unlProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_unlProp_name, true); + + zval property_notUnlProp_default_value; + ZVAL_NULL(&property_notUnlProp_default_value); + zend_string *property_notUnlProp_name = zend_string_init("notUnlProp", sizeof("notUnlProp") - 1, true); + zend_declare_property_ex(class_entry, property_notUnlProp_name, &property_notUnlProp_default_value, ZEND_ACC_PUBLIC, NULL); + zend_string_release_ex(property_notUnlProp_name, true); + return class_entry; } diff --git a/ext/zend_test/tests/gen_stub_test_01.phpt b/ext/zend_test/tests/gen_stub_test_01.phpt index 3126eb61631f..0cda0651bee3 100644 --- a/ext/zend_test/tests/gen_stub_test_01.phpt +++ b/ext/zend_test/tests/gen_stub_test_01.phpt @@ -22,6 +22,12 @@ object(ZendTestNS2\Foo)#%d (%d) { uninitialized(ZendTestNS2\ZendSubNS\Foo&ZendTestNS\Bar) ["unionProp"]=> uninitialized(ZendTestNS2\ZendSubNS\Foo|ZendTestNS\Bar) + ["fooAlias"]=> + uninitialized(ZendTestNS\Foo) + ["unlProp"]=> + uninitialized(ZendTestNS\UnlikelyCompileError) + ["notUnlProp"]=> + uninitialized(ZendTestNS\NotUnlikelyCompileError) } object(ZendTestNS2\Foo)#%d (%d) { ["foo"]=> @@ -31,6 +37,12 @@ object(ZendTestNS2\Foo)#%d (%d) { uninitialized(ZendTestNS2\ZendSubNS\Foo&ZendTestNS\Bar) ["unionProp"]=> uninitialized(ZendTestNS2\ZendSubNS\Foo|ZendTestNS\Bar) + ["fooAlias"]=> + uninitialized(ZendTestNS\Foo) + ["unlProp"]=> + uninitialized(ZendTestNS\UnlikelyCompileError) + ["notUnlProp"]=> + uninitialized(ZendTestNS\NotUnlikelyCompileError) } object(ZendTestNS\UnlikelyCompileError)#%d (%d) { }