From 50a4772a7d8614a55d5ae0ac163a3a4da5bda20a Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 26 Aug 2026 17:39:25 +0800 Subject: [PATCH] =?UTF-8?q?fix(gen):=20=E6=A8=A1=E5=9D=97=E9=99=90?= =?UTF-8?q?=E5=AE=9A=E6=9E=84=E9=80=A0=E4=BC=98=E5=85=88=E4=BA=8E=E8=A3=B8?= =?UTF-8?q?=E5=90=8D=E5=8F=AF=E8=A7=81=E6=80=A7=E5=88=86=E6=94=AF=EF=BC=8C?= =?UTF-8?q?=E6=A0=B9=E6=B2=BB=20ctor=20=E5=BD=92=E5=B1=9E=E5=86=85?= =?UTF-8?q?=E6=A0=B8=E5=90=8C=E5=90=8D=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gfx.Scene3D(...) 的 ctor 检测:Scene3D 因 includes 预注册(VKernel gfx 0ae)可见 → is_struct_visible 为真 → 走裸名分支 find_struct_by_module( func_name, trans.ModuleSha1) 落空 → 裸名回退 find_struct("Scene3D") 命中 先注册的内核版 0ae → ctor 生成 @0ae.Scene3D.__before_init__。上一版只改 了 elif 分支(vis!=0 时是死代码),未生效。 改为模块限定构造优先:在裸名可见性检查之前,识别 Module.Class(...) 且 模块已导入 → _lookup_module_sha1(模块名) 精确解析 SHA1 → find_struct_by_module 命中 App 版(9aab),锁定后跳过裸名回退。 --- App/lib/core/Gen/CallGenMixin.vp | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/App/lib/core/Gen/CallGenMixin.vp b/App/lib/core/Gen/CallGenMixin.vp index 76f8172..956211c 100644 --- a/App/lib/core/Gen/CallGenMixin.vp +++ b/App/lib/core/Gen/CallGenMixin.vp @@ -226,8 +226,30 @@ class CallGenMixin(CallGenBase.CallGenBase): # 用 find_struct_by_module 规避跨模块同名 find_struct 找错 struct_ty: llvmlite.LLVMType | t.CPtr = None gen_ctor_entry: GenTypes.StructEntry | t.CPtr = None + # 模块限定构造 Module.Class(...) 优先:按模块名解析 SHA1 精确命中类。 + # 必须在裸名可见性分支之前——跨模块同名类(VKernel gfx 与 App gfx 都 + # 定义 Scene3D)存在时,裸名 find_struct 返回先注册的错误 entry + # (0ae → ctor 生成 @0ae.Scene3D.__before_init__ → 链接 undefined + # symbol,Scene3D 根因)。模块解析成功即锁定,跳过下方裸名回退。 + mod_qual_done: int = 0 + if trans is not None and cl.func is not None and cl.func.kind() == ast.ASTKind.Attribute: + at_qc0: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(cl.func) + mod_path0: str = None + if at_qc0.value is not None and at_qc0.value.kind() == ast.ASTKind.Name: + mod_nm0: ast.Name | t.CPtr = (ast.Name | t.CPtr)(at_qc0.value) + if mod_nm0.id is not None: + mod_path0 = mod_nm0.id + elif at_qc0.value is not None and at_qc0.value.kind() == ast.ASTKind.Attribute: + mod_path0 = self.Gen.ExprGenAttr._attr_module_path_str(pool, at_qc0.value) + if mod_path0 is not None: + if self.Gen.ImportsGen.is_module_imported(trans._imported_modules, mod_path0) != 0: + mod_sha1_0: str = self._lookup_module_sha1(mod_path0) + if mod_sha1_0 is not None: + gen_ctor_entry = self.Gen.StructGen.find_struct_by_module( + func_name, mod_sha1_0) + mod_qual_done = 1 vis: int = self.Gen.StructGen.is_struct_visible(func_name) - if vis != 0: + if mod_qual_done == 0 and vis != 0: if trans is not None: gen_ctor_entry = self.Gen.StructGen.find_struct_by_module(func_name, trans.ModuleSha1) if gen_ctor_entry is None: