From e5f044dd03fd067074b71fa5694ef43204ab5506 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 30 Sep 2026 14:45:55 +0800 Subject: [PATCH] =?UTF-8?q?chore(=E8=AF=8A=E6=96=AD):=20AnnAssign=20RHS=20?= =?UTF-8?q?=E4=B8=BA=20`=E6=8E=A5=E6=94=B6=E8=80=85=E9=93=BE.=E6=96=B9?= =?UTF-8?q?=E6=B3=95(...)`=20=E6=97=B6=E8=A1=A5=E6=8E=A5=E6=94=B6=E8=80=85?= =?UTF-8?q?=E5=9F=BA=E5=9D=80=E8=AF=8A=E6=96=AD=20+=20=E6=9C=80=E8=BF=91?= =?UTF-8?q?=E4=B8=80=E6=AC=A1=E5=B1=9E=E6=80=A7=E8=AF=BB=E5=8F=96=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E5=8E=9F=E5=9B=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【b 机制漏豁免 —— 只加取证,不改任何判定/IR】现场:翻译 TransPyV/App/lib/core/Gen/Class/ClassGenEnum.vp:59 `ty: llvmlite.LLVMType* = self.Gen.TypeGenResolve.resolve_typedef_or_map(pool, at.attr, imported_modules, from_imports)` 报"(Call 形态)编译期求值为空"。 已按代码**排除**出来的事实(写进注释,供后续不再重复排查): · 方法声明缺失会在 HandlesExprCall._HandleMethodCallLlvm 内 raise "Undefined method …",不会走到该 fail-fast; · 该函数在"方法已找到"之后不会返回 None,唯一的 None 出口是 `ObjVal = HandleExprLlvm(Node.func.value)` 为假(L3335-3337)—— 即**接收者链 `self.Gen.TypeGenResolve` 自身求值为空**才是根因; · 但原报文的"基址诊断"只在 RHS 是 **Attribute** 时才打印(HandlesBase:784), Call 形态下接收者失败原因被丢弃 ⇒ 报错点与真因相隔数层。 修法(纯取证):HandlesBase 的通用 fail-fast 增 `elif Call(func=Attribute)` 分支,补三行: ① `被调者接收者诊断:` —— 复用 `_DescribeAttrBase(Gen, Node.func.value)`:接收者 (如 `self.Gen`)的基座形态 / var_struct_class / alloca 类型 / 是否在 Gen.structs / class_members 项数与字段名单 / struct body 元素数 / 该字段计算偏移; ② `最近一次属性读取失败:` —— 回显 `Gen._LastAttrNone` 的 (类, 字段, 原因):Call 形态下 无法用 (类, 字段) 与被报节点比对,故此处**无条件**回显(Attribute 形态仍保持 "必须与被报节点一致"的原判据,避免旧记录误导); ③ `被调方法=… 已声明同名方法键(示前 4 / 共 N):` —— 区分"方法根本没声明"与 "接收者读不出来"(后者才会命中本 fail-fast,但这一行让两者一眼可分)。 未验证:本提交只改诊断文本,行为不变;需再跑一次构建才能看到新增三行。 --- lib/core/Handles/HandlesBase.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/lib/core/Handles/HandlesBase.py b/lib/core/Handles/HandlesBase.py index a3baa1e..327a4df 100644 --- a/lib/core/Handles/HandlesBase.py +++ b/lib/core/Handles/HandlesBase.py @@ -783,6 +783,34 @@ class BaseHandle: # 见 HandlesExprCall._RequireArgValue)。 if isinstance(Node, ast.Attribute): msg += "\n│ 基址诊断: " + self._DescribeAttrBase(Gen, Node) + elif isinstance(Node, ast.Call) and isinstance(Node.func, ast.Attribute): + # 被调者形如 `接收者链.方法(...)`:整条 Call 求值为空的**唯一来源**是接收者链 + # 先求值为空(HandlesExprCall._HandleMethodCallLlvm 里 + # `ObjVal = HandleExprLlvm(Node.func.value)` 为假即 `return None`; + # 方法声明缺失会在同函数内 raise "Undefined method …",不会走到这里)。 + # 行号只能指到整条调用,故把**接收者**的基址事实与最近一次属性读取失败原因 + # 一并回显;Call 形态下无法用 (类, 字段) 与节点比对,该记录无条件回显。 + try: + msg += "\n│ 被调者接收者诊断: " + self._DescribeAttrBase(Gen, Node.func.value) + except Exception as _e_d: # noqa: BLE001 + msg += f"\n│ 被调者接收者诊断生成失败: {type(_e_d).__name__}: {_e_d}" + try: + _recC: Any = getattr(Gen, '_LastAttrNone', None) + if isinstance(_recC, tuple) and len(_recC) >= 3 and _recC[2]: + msg += (f"\n│ 最近一次属性读取失败: 类={_recC[0]!r} 字段={_recC[1]!r}" + f" 原因={_recC[2]}") + except Exception: # noqa: BLE001 + pass + _mnC: str = getattr(Node.func, 'attr', '') or '' + _declC: list[str] = [] + try: + for _fk in (getattr(Gen, 'functions', {}) or {}): + if _mnC and _fk.endswith(f'.{_mnC}'): + _declC.append(_fk) + except Exception: # noqa: BLE001 + _declC = [] + msg += (f"\n│ 被调方法={_mnC!r};已声明同名方法键(示前 4 / 共 {len(_declC)}): " + f"{_declC[:4]}") _vlog().compile_error(msg, src_file, lineno, code_line) sys.exit(1)