fix(phase): App 预注册期注入依赖 vpi,修 list[ast.ClassDef*] 票名前缀分裂

Phase A-pre(App 预注册)此前不做导入处理、不注入依赖 .vpi,导致包重导出
类的字段注解在预注册期只能保留「包前缀」(1abcd…),并被冻结进结构体布局;
阶段 A 构造函数侧却能借包别名 entry 校正为真定义前缀(e70bd…),两处票名
分裂 ⇒「非基本类型指针不可隐式转换」(现场 ClassGenGeneric.vp:92)。

改动(只放开 App 预注册,不动 includes 预注册那条防依赖环自锁的约束):
- Translator 新增 _pre_allow_dep_inject 开关,并在导入处理门拆成两道:
  ①导入处理 + 自动容器可见性 + LoadDepVpiIntoModule —— 全量翻译与 App 预注册共用;
  ②模块级变量预注册 + 函数前向声明 —— 仍只在全量翻译做。
- BuildPipeline.TranslateFileGetTrans 新增 pre_allow_dep_inject 参数并写入 Translator。
- Phase2 App 预注册调用点传 1;includes 预注册保持默认 0。
This commit is contained in:
TermiNexus committed 2026-10-02 01:03:31 +08:00
1 parent 57f8c655c8
commit 981af07d5c
3 files changed
+69 -28

No files matched your search

+9 -1
View File
@@ -119,12 +119,16 @@ def TranslateFileGetTrans(mb: memhub.MemBuddy*, file_path: str,
sha1_val: str,
current_package: str = None,
declare_only: int = 0,
temp_dir: str = None) -> rawptr[HandlesTranslator.Translator]:
temp_dir: str = None,
pre_allow_dep_inject: int = 0) -> rawptr[HandlesTranslator.Translator]:
"""翻译文件,返回 Translator 对象(调用者负责 dump_ir),None 失败
current_package: 当前文件所属包名(用于解析相对导入),None 表示顶级模块
declare_only: 0=全量翻译(默认),1=仅注册 struct/enum/union(不翻译方法体)
temp_dir: temp 目录路径(非 None 时在翻译前生成 .vpi 存根文件)
pre_allow_dep_inject: 仅 **App 预注册**(Phase A-pre)传 1:声明期也处理导入语句并
注入依赖 .vpi,使类字段注解与阶段 A 同上下文(详见 Translator._pre_allow_dep_inject)。
includes 预注册(Phase A-pre-inc)必须保持 0。
"""
if file_path is None: return None
f: rawptr[fileio.File] = fileio.File(file_path, fileio.MODE.R)
@@ -190,6 +194,10 @@ def TranslateFileGetTrans(mb: memhub.MemBuddy*, file_path: str,
tr.ModuleSha1 = sha1_val
tr.CurrentPackage = current_package
tr._declare_only = declare_only
# App 预注册(Phase A-pre)专用开关:置 1 时声明期也做导入处理 + 依赖 vpi 注入
# (详见 Translator._pre_allow_dep_inject)。includes 预注册(Phase A-pre-inc)
# 必须传 0,否则依赖环自锁(见 Translator 内 _declare_only==0 门处注释)。
tr._pre_allow_dep_inject = pre_allow_dep_inject
# P2: 复用全局 gen 单例(App/main.vp 创建;HandlesType 等旧模块函数经
# 延迟 import 委托到 gen 方法)。单例未注册时兜底创建(防御直接调用路径)。
gen: rawptr[GenGenerator.Generator] = GenGenerator._g_gen
+6 -1
View File
@@ -946,7 +946,12 @@ def RunMultiFileProject(mb: memhub.MemBuddy*,
if string.strlen(ent_pre.Path) > src_dir_len_pre + 1:
rel_path_pre: str = ent_pre.Path + src_dir_len_pre + 1
pkg_pre = GenApi.compute_package_from_relpath(mb, rel_path_pre)
tr_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(mb, ent_pre.Path, ent_pre.Sha1, pkg_pre, 1)
# App 预注册传 pre_allow_dep_inject=1:声明期也做导入处理 + 依赖 vpi 注入,
# 使类字段注解在预注册期即与阶段 A 同上下文(否则包重导出类
# list[ast.ClassDef*] 的票名前缀会在预注册期被冻结成包前缀,与阶段 A
# 解析出的真定义前缀分裂 → 结构体布局不兼容,见 Translator 字段说明)。
tr_pre: rawptr[HandlesTranslator.Translator] = BuildPipeline.TranslateFileGetTrans(
mb, ent_pre.Path, ent_pre.Sha1, pkg_pre, 1, None, 1)
if tr_pre is None:
VLogger.error(f"预注册失败: {ent_pre.Path}", "PhaseA")
# OOM 清理:回收本 App 文件预注册翻译的瞬时数据