From e700de10551839c2a6eb37cea62ac82a181b1b9f Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 19 Aug 2026 02:45:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(gen):=20REnum=20=E5=8F=98=E4=BD=93=E6=9E=84?= =?UTF-8?q?=E9=80=A0=E6=94=AF=E6=8C=81=E6=A8=A1=E5=9D=97=E9=99=90=E5=AE=9A?= =?UTF-8?q?=E5=BD=A2=E5=BC=8F=20mod.Class.Variant?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CallGenMixin.translate_call 的 REnum 变体检测只认单层 Name(ClassName.Variant), llvmlite.LLVMType.Struct(...) 这类嵌套属性漏检 → 误走跨模块函数路径 → _lookup_module_sha1('llvmlite.LLVMType') 查无 → '跨模块调用找不到模块 SHA1'。 根因修复:扩展检测到嵌套 Attribute,取路径末段为 REnum 类名、前缀为模块, 仅要求最左模块已导入(跨模块任意同名可接受,不做类归属校验),命中后走 _translate_renum_construct 构造变体。对应 TPC HandlesExprCall 静态方法路径。 --- App/lib/core/Gen/CallGenMixin.vp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/App/lib/core/Gen/CallGenMixin.vp b/App/lib/core/Gen/CallGenMixin.vp index 0f17337..59bbec0 100644 --- a/App/lib/core/Gen/CallGenMixin.vp +++ b/App/lib/core/Gen/CallGenMixin.vp @@ -425,6 +425,38 @@ class CallGenMixin(CallGenBase.CallGenBase): return ExprCallCtor._translate_renum_construct( pool, builder, mod, rc_cls_name, func_name, rc_tag, cargs, can, trans) + elif rc_at.value is not None and rc_at.value.kind() == ast.ASTKind.Attribute: + # 模块限定 REnum 变体构造: mod.Class.Variant(args...) + # 如 llvmlite.LLVMType.Struct(...) → 构造 llvmlite 模块 LLVMType 的 Struct 变体。 + # 根因:此前只支持单层 Name(ClassName.Variant),嵌套属性漏检 → 误走跨模块 + # 函数路径 → _lookup_module_sha1("llvmlite.LLVMType") 查无 → 报"跨模块调用 + # 'llvmlite.LLVMType.Struct' 找不到模块 SHA1"。跨模块任意同名可接受(REnum + # 表按类名全局注册):仅要求最左模块已导入 + 末段类名在全局 REnum 表中命中, + # 不做"类必须属于该模块"校验(未命中则按后续函数路径 fast-fail)。 + rc_mq_path: str = HandlesExpr.attr_module_path_str(pool, rc_at.value) + if rc_mq_path is not None: + rc_mq_dot: str = string.strrchr(rc_mq_path, 46) # 46 = ord('.') + if rc_mq_dot is not None and rc_mq_dot[1] != '\0': + # 模块路径 = 末段之前(支持多级: w32.fileio.Class.Variant) + rc_mq_len: t.CSizeT = rc_mq_dot - rc_mq_path + rc_mq_mod: str = pool.alloc(rc_mq_len + 1) + if rc_mq_mod is not None: + string.memcpy(rc_mq_mod, rc_mq_path, rc_mq_len) + rc_mq_mod[rc_mq_len] = '\0' + rc_mq_imp: int = 1 + if trans is not None and trans._imported_modules is not None: + rc_mq_imp = HandlesImports.is_module_imported( + trans._imported_modules, rc_mq_mod) + if rc_mq_imp != 0: + rc_mq_cls: str = rc_mq_dot + 1 + # 检查类名是否是已注册的 REnum 类 + if HandlesClassDef._is_renum_class_name(rc_mq_cls) != 0: + rc_mq_tag: int = HandlesClassDef._lookup_renum_variant_in_class( + rc_mq_cls, func_name) + if rc_mq_tag >= 0: + return ExprCallCtor._translate_renum_construct( + pool, builder, mod, rc_mq_cls, func_name, + rc_mq_tag, cargs, can, trans) # 查找函数:优先从函数表按裸名精确匹配(同模块函数), # 再从模块函数链表按后缀匹配(SHA1 前缀名)。