fix(Handles/PythonParser/DeclarationGenerator): 补齐 3 处"调用了不存在成员"的死路径 + 1 处被 hasattr 掩盖的静默降级
类别:a(编译器缺陷)
现场:翻译 TransPyV/App/lib/core/Gen/Call/CallGenLeafKit.vp 时终止编译
RuntimeError: 翻译 ... 失败: 'ClassHandle' object has no attribute '_PreRegisterClassMembers'
(FuncGen.py:965 有调用,方法全仓无定义)
按要求做了全仓静态扫描(ast:属性访问 vs 全仓属性定义;symtable:未定义全局名),共修 4 处:
1) HandlesClassDef.ClassHandle._PreRegisterClassMembers(缺失 → 实现)
调用点:FuncGen._get_member_offset 的"struct body 已存在、class_members[类名] 为空"分支
—— 该类的成员表在本次翻译里从未被收集,而按名定位字段槽位必须有表。
实现与既有两处成员收集段同源(CollectAnnAssignMember → 追加 (名, 类型)),但**只做收集**:
· 不展平继承前缀(调用方随后经 _member_base → EnsureClassMembersFlattened 补齐);
· 不调用 _generate_structs(body 已存在,重入 set_body 会把残缺布局永久固化);
· 只追加尚无同名的条目(幂等,重复命中不会把表撑长)。
跳过 __provides__/__requires__/__require_must__(非布局槽位),并登记字段限定符。
2) HandlesExprAttr.ExprAttrHandle._load_bitfield_member(缺失 → 实现)
读路径 7 处调用(位域分支)全部指向不存在的方法 ⇒ 任何位域字段读取都会 AttributeError。
实现与 HandlesAssign._store_bitfield_member 严格对称:位域类 body 只有一个 storage 槽
(elements[0]),字段位置由 class_member_bitoffsets/bitfields/signeds 表达,
读取 = `(storage >> 位偏移) & ((1<<位宽)-1)`,有符号字段再做符号扩展;
缺位偏移 / 位宽 ≤ 0 / struct 未具化 / storage 非整数一律 fail-fast(不返回 i32 兜底)。
3) PythonParserMixin 的 __set_default__ 分支(幽灵调用 → 明确报未支持)
原调用 self._handle_set_default_in_parse(...) 全仓无定义。核实:该注解在 TransPyC/lib 内
无任何消费端(只有 t.py 的定义与 StubGen/Converter 的"剥离该调用保留类型"),
includes 全仓亦无源使用 ⇒ 不静默丢弃源码语义,改为 NotImplementedError 明确报"未支持"。
4) DeclarationGenerator._llvm_type_size_str 的数组分支(静默降级 → 修好)
原写作 `self._ARR_TYPE_RE`(少一个 A)并以 hasattr 守卫 —— 该属性全仓从未定义 ⇒ 守卫恒假
⇒ 数组字段一律落到"未知类型 → 8",与 docstring 声明的"_EmitREnumLlvm 尺寸口径对齐"不符。
改用本类已定义的 _ARRAY_TYPE_RE,并去掉守卫(属性再丢失应当响亮失败)。
核验:compileall 全 lib 通过;属性扫描剩余 26 条全为仓外对象(logging / vast AST /
llvmlite Value·Instruction·IRBuilder / 内置 Exception.args / __class__ / __dict__);
symtable 未定义全局名仅 __file__(运行时内置)。未新增/放宽任何 fail-fast。
This commit is contained in:
1 parent
52ea21f082
commit
c2f53852ee
4 files changed
+134
-2
No files matched your search
@@ -225,7 +225,19 @@ class PythonParserMixin:
|
||||
|
||||
# 检查是否有 __set_default__ 初始化
|
||||
if AnnotationContainsName(NextNode.annotation, '__set_default__'):
|
||||
self._handle_set_default_in_parse(ClassKey, TargetName, ClassName, NextNode)
|
||||
# 【fail-fast,替代**不存在的** _handle_set_default_in_parse
|
||||
# (2026-09-30)】原调用指向的方法全仓无定义 ⇒ 一旦命中即
|
||||
# `AttributeError`(与 ClassHandle._PreRegisterClassMembers
|
||||
# 同族:死调用,非"未走到")。
|
||||
# 现状核实:`__set_default__` 在 TransPyC/lib 内只有
|
||||
# t.py 的定义与 StubGen/Converter 的"剥离该调用、保留类型",
|
||||
# **没有任何消费端**读取它的 kwargs;includes 全仓亦无源使用。
|
||||
# 因此这里既不调用幽灵方法,也不静默丢弃源码语义:明确报未支持,
|
||||
# 语义(字段默认值如何落到 class_member_defaults)确定后再实现。
|
||||
raise NotImplementedError(
|
||||
f"[未支持] 注解里的 __set_default__(...):类 '{ClassKey}' "
|
||||
f"字段 '{TargetName}'(TPC 翻译路径无消费端;"
|
||||
f"拒绝静默丢弃该默认值语义)")
|
||||
j += 1
|
||||
continue
|
||||
# 再处理旧格式:xxx: t.CTypedef = xxx 或 xxx: t.CPtr = xxx
|
||||
|
||||
Reference in new issue
Block a user