修正了一些错误
This commit is contained in:
@@ -14,8 +14,38 @@ from lib.Projectrans.Phase1Generator import Phase1Generator
|
||||
from lib.Projectrans.Phase2Translator import Phase2Translator
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 全局 SHA1 映射内存存储器
|
||||
#
|
||||
# Phase1 生成 sha1_map 后写入此处(save_sha1_map),
|
||||
# Phase2 从此处读取(Load_sha1_map / Phase2Translator._LoadSha1Map)。
|
||||
# _sha1_map.txt 文件仅作为人类可读输出,不再作为机器分析数据源。
|
||||
# ============================================================
|
||||
_g_sha1_map_store: dict[str, str] = {}
|
||||
|
||||
|
||||
def get_sha1_map_store() -> dict[str, str]:
|
||||
"""返回全局 SHA1 映射内存存储器(供 Phase2Translator 直接访问)"""
|
||||
return _g_sha1_map_store
|
||||
|
||||
|
||||
def clear_sha1_map_store() -> None:
|
||||
"""清空全局 SHA1 映射内存存储器"""
|
||||
_g_sha1_map_store.clear()
|
||||
|
||||
|
||||
def save_sha1_map(temp_dir: str, sha1_map: dict[str, str]) -> None:
|
||||
"""将 SHA1 映射表保存到文件"""
|
||||
"""将 SHA1 映射表保存到内存存储器,并输出人类可读的 _sha1_map.txt
|
||||
|
||||
机器分析使用内存存储器(_g_sha1_map_store),
|
||||
_sha1_map.txt 仅作为人类可读输出,不再被机器读取。
|
||||
"""
|
||||
# 写入内存存储器(机器分析数据源)
|
||||
_g_sha1_map_store.clear()
|
||||
for sha1, rel in sha1_map.items():
|
||||
_g_sha1_map_store[sha1] = rel
|
||||
|
||||
# 写入文件(仅人类可读输出)
|
||||
map_path: str = os.path.join(temp_dir, '_sha1_map.txt')
|
||||
with open(map_path, 'w', encoding='utf-8') as f:
|
||||
for sha1, rel in sorted(sha1_map.items()):
|
||||
@@ -23,18 +53,14 @@ def save_sha1_map(temp_dir: str, sha1_map: dict[str, str]) -> None:
|
||||
|
||||
|
||||
def Load_sha1_map(temp_dir: str) -> dict[str, str]:
|
||||
"""从文件加载 SHA1 映射表"""
|
||||
map_path: str = os.path.join(temp_dir, '_sha1_map.txt')
|
||||
"""从内存存储器加载 SHA1 映射表
|
||||
|
||||
temp_dir 参数保留用于签名兼容性,但不再读取文件。
|
||||
机器分析使用内存存储器(_g_sha1_map_store)。
|
||||
"""
|
||||
result: dict[str, str] = {}
|
||||
if os.path.exists(map_path):
|
||||
with open(map_path, 'r', encoding='utf-8') as f:
|
||||
for line in f:
|
||||
line: str = line.strip()
|
||||
if ':' in line:
|
||||
sha1: str
|
||||
rel: str
|
||||
sha1, rel = line.split(':', 1)
|
||||
result[sha1] = rel
|
||||
for sha1, rel in _g_sha1_map_store.items():
|
||||
result[sha1] = rel
|
||||
return result
|
||||
|
||||
|
||||
@@ -69,17 +95,9 @@ def resolve_paths(config: dict[str, Any], project_file: str) -> dict[str, Any]:
|
||||
resolved_sources.append(resolve(src))
|
||||
result['sources'] = [s for s in resolved_sources if os.path.isfile(s)]
|
||||
|
||||
# build_dir: 统一构建目录(默认 ./.tpv_build),temp 和 output 作为其子目录
|
||||
# 不再单独读取 temp_dir/output_dir,由 build_dir 自动计算
|
||||
build_dir: str = config.get('build_dir', './.tpv_build')
|
||||
build_dir = resolve(build_dir)
|
||||
result['build_dir'] = build_dir
|
||||
if build_dir is not None:
|
||||
result['temp_dir'] = os.path.join(build_dir, 'temp')
|
||||
result['output_dir'] = os.path.join(build_dir, 'output')
|
||||
else:
|
||||
result['temp_dir'] = None
|
||||
result['output_dir'] = None
|
||||
# 直接使用 output_dir / temp_dir(与新版本 TPV 一致,不再支持 build_dir)
|
||||
result['temp_dir'] = resolve(config.get('temp_dir', './temp'))
|
||||
result['output_dir'] = resolve(config.get('output_dir', './output'))
|
||||
|
||||
if 'includes' in result:
|
||||
result['includes'] = [resolve(inc) for inc in result['includes']]
|
||||
|
||||
@@ -528,7 +528,7 @@ class Phase1Generator:
|
||||
sha1: str = self._get_sha1(src_path)
|
||||
if not sha1:
|
||||
return
|
||||
self.sha1_map[sha1] = rel_path
|
||||
self.sha1_map[sha1] = rel_path.replace(os.sep, '/').replace(chr(92), '/')
|
||||
|
||||
sig_path: str = os.path.join(self.temp_dir, f"{sha1}.pyi")
|
||||
if os.path.isfile(sig_path):
|
||||
|
||||
@@ -218,18 +218,18 @@ class Phase2Translator:
|
||||
if sha1 not in self.stub_files:
|
||||
self.stub_files[sha1] = os.path.join(_GLOBAL_CACHE_DIR, fname)
|
||||
|
||||
sha1_file_path = os.path.join(self.temp_dir, '_sha1_map.txt')
|
||||
if os.path.exists(sha1_file_path):
|
||||
with open(sha1_file_path, 'r', encoding='utf-8') as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if ':' in line:
|
||||
sha1, rel = line.split(':', 1)
|
||||
self.sha1_map[sha1] = rel
|
||||
if rel.startswith('includes/'):
|
||||
module_name = os.path.splitext(os.path.basename(rel))[0]
|
||||
self.include_py_map[module_name] = sha1
|
||||
# 从内存存储器读取 SHA1 映射(_sha1_map.txt 仅人类可读,不再作为机器数据源)
|
||||
# 延迟导入避免循环依赖(Config 导入 Phase2Translator)
|
||||
from lib.Projectrans.Config import get_sha1_map_store
|
||||
mem_store: dict[str, str] = get_sha1_map_store()
|
||||
if mem_store:
|
||||
for sha1, rel in mem_store.items():
|
||||
self.sha1_map[sha1] = rel
|
||||
if rel.startswith('includes/'):
|
||||
module_name = os.path.splitext(os.path.basename(rel))[0]
|
||||
self.include_py_map[module_name] = sha1
|
||||
else:
|
||||
# 内存存储器为空(独立运行 Phase2 的回退):从 stub 文件名推断
|
||||
for sha1, stub_path in self.stub_files.items():
|
||||
self.sha1_map[sha1] = sha1
|
||||
|
||||
@@ -2534,7 +2534,7 @@ class Phase2Translator:
|
||||
# 注册到 sig_files 和 _source_module_sig_files
|
||||
if os.path.isfile(sig_path):
|
||||
self.sig_files[sha1] = sig_path
|
||||
self.sha1_map[sha1] = f"includes/{mod_full.replace('.', os.sep)}.py"
|
||||
self.sha1_map[sha1] = f"includes/{mod_full.replace('.', '/')}.py"
|
||||
if self._shared_source_module_sig_files is not None:
|
||||
self._shared_source_module_sig_files[mod_full] = sig_path
|
||||
self._shared_source_module_sig_files[module_name] = sig_path
|
||||
@@ -2759,15 +2759,18 @@ class Phase2Translator:
|
||||
py_path = os.path.join(abs_includes, py_file)
|
||||
try:
|
||||
# 复用 parse_python_file 的 AST 缓存
|
||||
_, py_tree = parse_python_file(py_path)
|
||||
py_content, py_tree = parse_python_file(py_path)
|
||||
if py_tree is None:
|
||||
continue
|
||||
# 计算 include 文件的 SHA1,供特化时统一命名空间
|
||||
py_sha1: str = compute_sha1(py_content)
|
||||
for node in py_tree.body:
|
||||
if isinstance(node, ast.ClassDef) and hasattr(node, 'type_params') and node.type_params:
|
||||
type_params = [tp.name for tp in node.type_params]
|
||||
generic_class_templates[node.name] = {
|
||||
'node': node,
|
||||
'type_params': type_params,
|
||||
'sha1': py_sha1,
|
||||
}
|
||||
except Exception as _e:
|
||||
if _config_mode == "strict":
|
||||
@@ -2817,9 +2820,9 @@ class Phase2Translator:
|
||||
scan_dirs = []
|
||||
if self.src_root and os.path.isdir(self.src_root):
|
||||
scan_dirs.append(self.src_root)
|
||||
project_dir = os.path.dirname(self.output_dir)
|
||||
if project_dir and os.path.isdir(project_dir) and project_dir not in scan_dirs:
|
||||
scan_dirs.append(project_dir)
|
||||
# 不再扫描 output_dir 的父目录:当 output_dir 位于顶层时,
|
||||
# 父目录是整个仓库根,会误扫到 ViperOS/includes/vqt6 等无关 C/C++ 源文件。
|
||||
# 项目特定的 C/汇编文件应放在 src_root 下,或通过 extra_compile_files 指定。
|
||||
for scan_dir in scan_dirs:
|
||||
for root, dirs, files in os.walk(scan_dir):
|
||||
dirs[:] = [d for d in dirs if not d.startswith('.') and d != '__pycache__']
|
||||
|
||||
@@ -20,12 +20,13 @@ from lib.Projectrans.Utils import (
|
||||
from lib.Projectrans.Phase1Generator import Phase1Generator
|
||||
from lib.Projectrans.DeclarationGenerator import DeclarationGenerator
|
||||
from lib.Projectrans.Phase2Translator import Phase2Translator, _parallel_translate_worker
|
||||
from lib.Projectrans.Config import save_sha1_map, Load_sha1_map, Load_project_config, resolve_paths, main
|
||||
from lib.Projectrans.Config import save_sha1_map, Load_sha1_map, get_sha1_map_store, clear_sha1_map_store, Load_project_config, resolve_paths, main
|
||||
|
||||
__all__ = [
|
||||
'compute_sha1', '_check_annotation_for_export', 'sha1_file',
|
||||
'get_file_dependencies', 'find_reachable_files_from_entries',
|
||||
'topological_sort_files', 'Phase1Generator', 'DeclarationGenerator',
|
||||
'Phase2Translator', '_parallel_translate_worker',
|
||||
'save_sha1_map', 'Load_sha1_map', 'Load_project_config', 'resolve_paths', 'main'
|
||||
'save_sha1_map', 'Load_sha1_map', 'get_sha1_map_store', 'clear_sha1_map_store',
|
||||
'Load_project_config', 'resolve_paths', 'main'
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user