fix(phase1): 容器模板按需纳入可达集合(includes 层)

ad2b97a 移除 _list/_dict 无条件预加入后,includes 文件使用
list[...]/dict[...] 泛型(如 base.vp 的 list[AST | CPtr])但不显式
import _list/_dict 时,_list.vp 不进入可达集合 → 泛型模板未注册 →
"泛型类 list 未找到模板"。
Phase 1a-pre 翻译每个 includes 后新增 _ScanTreeForContainers 扫描
(裸名/泛型下标/字面量),命中则追加 _list/_dict 到 _imported_modules
→ 进 deps → _BuildReachableSha1Set 的可达集合自动包含(Phase1/Phase2
都受益),对齐 App 层 _inject_auto_container_visibility。
This commit is contained in:
TermiNexus committed 2026-08-13 04:16:26 +08:00
1 parent 5efca5b8e4
commit dfb86380a6
1 file changed
+66
+66
View File
@@ -226,6 +226,46 @@ def _FindClassDefSha1(class_names_buf: bytes, def_sha1s_buf: bytes,
return None
# ============================================================
# _ScanTreeForContainers - 递归扫描 AST 检测 list/dict 容器使用
#
# 覆盖:裸名(list/dict)、泛型下标(list[T] 的 Subscript.value)、
# 字面量([]/{})。命中即置 need_list/need_dict 标志。
# 误报无害(最多多编译 _list/_dict 两个空壳模块)。
# ============================================================
def _ScanTreeForContainers(node: ast.AST | t.CPtr,
need_list_box: t.CPtr,
need_dict_box: t.CPtr):
"""递归扫描 AST,检测 list/dict 容器使用"""
if node is None:
return
k_s: int = node.kind()
if k_s == ast.ASTKind.Name:
nm_s: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
if nm_s.id is not None:
if string.strcmp(nm_s.id, "list") == 0:
need_list_box[0] = 1
elif string.strcmp(nm_s.id, "dict") == 0:
need_dict_box[0] = 1
elif k_s == ast.ASTKind.Subscript:
sub_s: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(node)
if sub_s.value is not None:
_ScanTreeForContainers(sub_s.value, need_list_box, need_dict_box)
elif k_s == ast.ASTKind.List:
# [] 字面量
need_list_box[0] = 1
elif k_s == ast.ASTKind.Dict:
# {} 字面量
need_dict_box[0] = 1
# 递归子节点
if node.children is not None:
ch_s: list[ast.AST | t.CPtr] | t.CPtr = node.children
n_s: t.CSizeT = len(ch_s)
ci_s: t.CSizeT
for ci_s in range(n_s):
_ScanTreeForContainers(ch_s.get(ci_s), need_list_box, need_dict_box)
# ============================================================
# _TopoSortFiles - 根据类继承关系对文件进行拓扑排序
#
@@ -641,6 +681,32 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
else:
p1a_registered += 1
# 容器模板按需纳入依赖:includes 使用 list/dict 泛型/构造/字面量
# (如 base.vp 的 list[AST | CPtr])时追加 _list/_dict 到
# _imported_modules → 进 deps → _BuildReachableSha1Set 的可达集合
# 自动包含(Phase1 与 Phase2 都受益),否则泛型模板未注册 →
# "泛型类 'list' 未找到模板"。对齐 App 层 _inject_auto_container_visibility。
cl_box: t.CPtr = stdlib.malloc(4)
cd_box: t.CPtr = stdlib.malloc(4)
if cl_box is not None and cd_box is not None:
cl_box[0] = 0
cd_box[0] = 0
_ScanTreeForContainers(tree_a, cl_box, cd_box)
if cl_box[0] != 0:
if tr_a._imported_modules is None or \
HandlesImports.is_module_imported(tr_a._imported_modules, "_list") == 0:
tr_a._imported_modules = HandlesImports.add_imported_module(
mb, tr_a._imported_modules, "_list")
if cd_box[0] != 0:
if tr_a._imported_modules is None or \
HandlesImports.is_module_imported(tr_a._imported_modules, "_dict") == 0:
tr_a._imported_modules = HandlesImports.add_imported_module(
mb, tr_a._imported_modules, "_dict")
if cl_box is not None:
stdlib.free(cl_box)
if cd_box is not None:
stdlib.free(cd_box)
# 生成 .deps.txt(记录依赖模块名,供依赖图按需翻译使用)
# 同时填充内存依赖存储器(PopulateIncludesDeps),供 _BuildReachableSha1Set
# 直接从内存读取,不依赖 .deps.txt 过程文件