fix(gen): REnum 变体构造支持模块限定形式 mod.Class.Variant

CallGenMixin.translate_call 的 REnum 变体检测只认单层 Name(ClassName.Variant),
llvmlite.LLVMType.Struct(...) 这类嵌套属性漏检 → 误走跨模块函数路径 →
_lookup_module_sha1('llvmlite.LLVMType') 查无 → '跨模块调用找不到模块 SHA1'。
根因修复:扩展检测到嵌套 Attribute,取路径末段为 REnum 类名、前缀为模块,
仅要求最左模块已导入(跨模块任意同名可接受,不做类归属校验),命中后走
_translate_renum_construct 构造变体。对应 TPC HandlesExprCall 静态方法路径。
This commit is contained in:
TermiNexus committed 2026-08-19 02:45:10 +08:00
1 parent 941ba2feb0
commit e700de1055
1 file changed
+32
+32
View File
@@ -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 前缀名)。