diff --git a/lib/core/Handles/HandlesBase.py b/lib/core/Handles/HandlesBase.py index f43c814..32a12b8 100644 --- a/lib/core/Handles/HandlesBase.py +++ b/lib/core/Handles/HandlesBase.py @@ -658,6 +658,34 @@ class BaseHandle: f"{(',目标变量 ' + repr(VarName)) if VarName else ''}" f"{(',注解 ' + ann_text) if ann_text else ''}。位置 {loc}" f"{(',源码: ' + code_line) if code_line else ''}") + # 【基址诊断】属性读返回 None 的根因只有两类(先说事实,不再从"求值为空"反推): + # ① 类名登记退化 —— var_struct_class 存的是占位/折叠态('rawptr'、'rawptr[X]'、 + # 'CVoid'…)或压根没登记; + # ② 登记名与 Gen.structs / class_members 的键不同源(短名 vs sha1 全名)。 + # 故把"基址变量登记成什么 + alloca 实际 LLVM 类型 + 该登记名在两表的命中情况" + # 一并打进报文(与 _DescribeMemberSlot 同口径:列数据而非猜)。仅 Attribute + Name + # 基址时追加,其余形态报文逐字不变。 + if isinstance(Node, ast.Attribute) and isinstance(Node.value, ast.Name): + _bn: str = Node.value.id + _vc: str | None = None + _alloc: Any = None + try: + _vc = (getattr(Gen, 'var_struct_class', None) or {}).get(_bn) + if not _vc: + _vc = (getattr(Gen, 'global_struct_class', None) or {}).get(_bn) + _alloc = (getattr(Gen, 'variables', None) or {}).get(_bn) + except Exception: # noqa: BLE001 + pass + _slot_ty: object = getattr(_alloc, 'type', None) + if _vc: + _hit_st: str = '是' if _vc in Gen.structs else '否' + _hit_cm: str = ('%d 个字段' % len(Gen.class_members.get(_vc) or [])) \ + if _vc in Gen.class_members else '无该键' + else: + _hit_st, _hit_cm = '—', '—' + msg += (f"\n│ 基址诊断: '{_bn}' 的 var_struct_class={_vc!r};" + f"alloca 类型={_slot_ty};该名在 Gen.structs={_hit_st};" + f"class_members={_hit_cm}") _vlog().compile_error(msg, src_file, lineno, code_line) sys.exit(1) diff --git a/lib/core/Handles/HandlesImports.py b/lib/core/Handles/HandlesImports.py index 33fe841..601143f 100644 --- a/lib/core/Handles/HandlesImports.py +++ b/lib/core/Handles/HandlesImports.py @@ -3206,7 +3206,10 @@ class ImportHandle(BaseHandle): """`_TryLoadClassMembersFromPyi` 重跑的依赖签名(纯读,不产生副作用)。 收录"重跑能否产生新结果"的全部输入: - - 全局进度:`len(class_members)` / `len(_members_flattened)` + - 全局进度:**逐类**(`class_members` 键, 该表长度) 的完整元组(不是"类数"—— + 只看键数会在"某已有类的成员表继续增长"(父类成员后到)时看不出变化, + 而父类成员正是继承前缀的来源);`_members_flattened` 长度; + `class_parents` / `class_parent` 的条目数(父链登记本身也是输入) - 本类自身:成员表长度、是否已登记已展平、struct body 元素数(None ⇒ -1) - 各父类:成员表长度 + 是否已展平(父类从 `class_parents` / `class_parent` 取; 两者都缺时用空元组 —— 此时本类依赖尚未建立,签名仍稳定,不影响收敛) @@ -3225,9 +3228,12 @@ class ImportHandle(BaseHandle): (_p, len(Gen.class_members.get(_p, []) or []), _p in _flat) for _p in _parents ) + _cm_sig: tuple = tuple((_k, len(_v)) for _k, _v in Gen.class_members.items()) return ( - len(Gen.class_members), + _cm_sig, len(_flat), + len(getattr(Gen, 'class_parents', {}) or {}), + len(getattr(Gen, 'class_parent', {}) or {}), len(Gen.class_members.get(class_name, []) or []), class_name in _flat, _st_len,