fix(handles): MRO 查找归一化带 sha1 前缀类名,修复继承方法 Undefined method
TPC 编译 TPV 报 "Undefined method 'find_func_in_module' in class 'c9b44d17cd621a75.CallGenLib'":跨模块 ObjVal 类型反查 Gen.structs 得到带 sha1 前缀的类名,而 class_parents / ModuleSha1Map / _struct_sha1_map 键为裸类名 → _get_mro_chain 查不到父类 → MRO 回退失效 → fail-fast。 - BaseGen._get_mro_chain:查 class_parents 前剥离 "16位hex." 前缀(父类名带前缀时同样处理) - HandlesExprCall._EnsureClassParentsLoaded:归一化后再查 class_parents / 按需加载父类信息
This commit is contained in:
1 parent
3aebf402bb
commit
1f3c83cb6d
2 files changed
+22
-4
No files matched your search
@@ -2516,13 +2516,22 @@ class ExprCallHandle(BaseHandle):
|
|||||||
return
|
return
|
||||||
if Gen.class_parents.get(ClassName):
|
if Gen.class_parents.get(ClassName):
|
||||||
return
|
return
|
||||||
sha1_cls = Gen.ModuleSha1Map.get(ClassName)
|
# 归一化:ClassName 可能带 sha1 前缀(如 "c9b44d17cd621a75.CallGenLib",
|
||||||
|
# 跨模块 structs 表键),而 class_parents / ModuleSha1Map / _struct_sha1_map
|
||||||
|
# 的键是裸类名。不剥离则查不到父类 → 继承方法 MRO 回退失效 → fail-fast
|
||||||
|
# "Undefined method 'find_func_in_module' in class '...CallGenLib'"。
|
||||||
|
lookup_cls: str = ClassName
|
||||||
|
if len(ClassName) > 17 and ClassName[16] == '.':
|
||||||
|
lookup_cls = ClassName[17:]
|
||||||
|
if Gen.class_parents.get(lookup_cls):
|
||||||
|
return
|
||||||
|
sha1_cls = Gen.ModuleSha1Map.get(lookup_cls)
|
||||||
if not sha1_cls:
|
if not sha1_cls:
|
||||||
sha1_cls = getattr(Gen, '_struct_sha1_map', {}).get(ClassName)
|
sha1_cls = getattr(Gen, '_struct_sha1_map', {}).get(lookup_cls)
|
||||||
if not sha1_cls:
|
if not sha1_cls:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.Trans.ImportHandler._TryLoadClassMembersFromPyi(ClassName, f"{sha1_cls}.stub.ll", Gen)
|
self.Trans.ImportHandler._TryLoadClassMembersFromPyi(lookup_cls, f"{sha1_cls}.stub.ll", Gen)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -601,6 +601,11 @@ class BaseGenMixin:
|
|||||||
|
|
||||||
顺序: 自身 → 父类1 及祖先 → 父类2 及祖先(先声明父类优先,菱形去重)。
|
顺序: 自身 → 父类1 及祖先 → 父类2 及祖先(先声明父类优先,菱形去重)。
|
||||||
与 TPV HandlesStruct.get_mro_chain 的语义一致。
|
与 TPV HandlesStruct.get_mro_chain 的语义一致。
|
||||||
|
|
||||||
|
支持带 sha1 前缀的类名(如 "c9b44d17cd621a75.CallGenLib",跨模块
|
||||||
|
structs 表键):查 class_parents 前剥离前缀,否则表键(裸类名)不匹配
|
||||||
|
→ MRO 链只剩自身 → 继承方法调用 fail-fast "Undefined method
|
||||||
|
'find_func_in_module' in class '...CallGenLib'"(CallGenLib 根因)。
|
||||||
"""
|
"""
|
||||||
chain: list[str] = []
|
chain: list[str] = []
|
||||||
visited: set[str] = set()
|
visited: set[str] = set()
|
||||||
@@ -612,7 +617,11 @@ class BaseGenMixin:
|
|||||||
continue
|
continue
|
||||||
visited.add(cur)
|
visited.add(cur)
|
||||||
chain.append(cur)
|
chain.append(cur)
|
||||||
parents: list[str] = parents_map.get(cur, [])
|
# 归一化:剥离 "16位hex." 前缀后用裸类名查父类表
|
||||||
|
lookup: str = cur
|
||||||
|
if len(cur) > 17 and cur[16] == '.':
|
||||||
|
lookup = cur[17:]
|
||||||
|
parents: list[str] = parents_map.get(lookup, parents_map.get(cur, []))
|
||||||
# 父类逆序压栈,保证声明顺序弹出(先访问父类1 的整条链)
|
# 父类逆序压栈,保证声明顺序弹出(先访问父类1 的整条链)
|
||||||
for p in reversed(parents):
|
for p in reversed(parents):
|
||||||
if p and p not in visited:
|
if p and p not in visited:
|
||||||
|
|||||||
Reference in new issue
Block a user