diff --git a/App/lib/core/Phase1.vp b/App/lib/core/Phase1.vp index 8e6f32b..c26291a 100644 --- a/App/lib/core/Phase1.vp +++ b/App/lib/core/Phase1.vp @@ -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 过程文件