"""Pass 4: PackageReexporter — 将符号重新导出到命名空间前缀下""" from __future__ import annotations from typing import TYPE_CHECKING if TYPE_CHECKING: from lib.core.SymbolTable import SymbolTable from lib.core.SymbolData import ModuleSymbols class PackageReexporter: """将已解析的符号重新导出到命名空间前缀下(如 memhub.MemPool)""" def __init__(self, symbol_table: SymbolTable) -> None: self._symtab: SymbolTable = symbol_table self._namespace: str | None = None def set_namespace(self, namespace: str) -> None: """设置当前模块的命名空间""" self._namespace = namespace def reexport(self, module_symbols: ModuleSymbols, prefixes: list[str], lineno: int = 0) -> list[str]: """将符号重新导出到所有命名空间前缀下,返回新增的符号名列表""" loaded: list[str] = [] file_path: str = module_symbols.file_path ns: dict[str, object] = self._symtab._namespaces.get(self._namespace, {}) if self._namespace else {} for prefix in prefixes: # 插入类符号(前缀.类名) for cls in module_symbols.classes: full_name: str = f"{prefix}.{cls.name}" self._symtab._InsertClassSymbol( full_name, cls.type_kind, cls.lineno, file_path, cls.members, cls.is_cpython_object, cls.is_packed ) loaded.append(full_name) if self._namespace: ns[full_name] = self._symtab._symbols[full_name] # 插入枚举成员(前缀.成员名 + 前缀.类名.成员名)—— CEnum 和 REnum 共用 if cls.type_kind in ('enum', 'renum'): for member_name, member_value, member_lineno in cls.enum_members: full_member_name: str = f"{prefix}.{member_name}" self._symtab._InsertEnumMemberSymbol(full_member_name, cls.name, member_lineno, file_path, value=member_value) loaded.append(full_member_name) # 同时注册 prefix.ClassName.member_name,以支持 module.Class.MEMBER 三层访问 qualified_member_name: str = f"{prefix}.{cls.name}.{member_name}" self._symtab._InsertEnumMemberSymbol(qualified_member_name, cls.name, member_lineno, file_path, value=member_value) loaded.append(qualified_member_name) # REnum: 记录变体名列表到前缀类符号 if cls.type_kind == 'renum': renum_info = self._symtab._symbols[full_name] renum_info.RenumVariants = [m[0] for m in cls.enum_members] # 插入 typedef 符号(前缀.名称) for td in module_symbols.typedefs: full_name: str = f"{prefix}.{td.name}" self._symtab._InsertTypedefSymbol( full_name, td.original_type_kind, td.original_class, td.lineno, file_path, td.members ) loaded.append(full_name) if self._namespace: ns[full_name] = self._symtab._symbols[full_name] # 插入函数符号(前缀.名称) for func in module_symbols.functions: full_name: str = f"{prefix}.{func.name}" # 优先使用 CTypeInfo(保留符号性),回退到 LLVM 类型字符串 ret_type = func.ret_ctype if func.ret_ctype else func.ret_type self._symtab._InsertFuncSymbol( full_name, ret_type, func.param_types, func.lineno, file_path, func.is_variadic, func.is_inline ) loaded.append(full_name) if self._namespace: ns[full_name] = self._symtab._symbols[full_name] # 插入 define 符号(前缀.名称) for define in module_symbols.defines: full_name: str = f"{prefix}.{define.name}" self._symtab._InsertDefineSymbol( full_name, define.value, define.lineno, file_path ) loaded.append(full_name) if self._namespace: ns[full_name] = self._symtab._symbols[full_name] # 插入模块别名 self._symtab._InsertModuleSymbol(prefix, lineno, file_path) # 插入匿名类型符号(前缀.名称) for anon_name, anon_data in module_symbols.anonymous_types.items(): full_type_name: str = f"{prefix}.{anon_name}" self._symtab._InsertAnonymousSymbol( full_type_name, anon_data.is_union, anon_data.members, anon_data.lineno, file_path ) return loaded