"""Pass 3: SymbolInserter — 将解析后的符号插入 SymbolTable(主命名空间)""" 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 SymbolInserter: """将解析后的符号插入 SymbolTable 的主命名空间(无前缀)""" 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 self._symtab.register_namespace(namespace) def insert(self, module_symbols: ModuleSymbols) -> 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 cls in module_symbols.classes: self._symtab._InsertClassSymbol( cls.name, cls.type_kind, cls.lineno, file_path, cls.members, cls.is_cpython_object, cls.is_packed ) loaded.append(cls.name) if self._namespace: ns[cls.name] = self._symtab._symbols[cls.name] # 插入枚举成员(短名 + 类名.成员名)—— CEnum 和 REnum 共用 if cls.type_kind in ('enum', 'renum'): for member_name, member_value, member_lineno in cls.enum_members: self._symtab._InsertEnumMemberSymbol(member_name, cls.name, member_lineno, file_path, value=member_value) loaded.append(member_name) class_member_name: str = f"{cls.name}.{member_name}" self._symtab._InsertEnumMemberSymbol(class_member_name, cls.name, member_lineno, file_path, value=member_value) loaded.append(class_member_name) # REnum: 记录变体名列表到类符号(供 HandlesExprCall 跨模块变体构造识别) if cls.type_kind == 'renum': renum_info = self._symtab._symbols[cls.name] renum_info.RenumVariants = [m[0] for m in cls.enum_members] # 插入 typedef 符号 for td in module_symbols.typedefs: self._symtab._InsertTypedefSymbol( td.name, td.original_type_kind, td.original_class, td.lineno, file_path, td.members ) loaded.append(td.name) if self._namespace: ns[td.name] = self._symtab._symbols[td.name] # 插入函数符号 for func in module_symbols.functions: # 优先使用 CTypeInfo(保留符号性),回退到 LLVM 类型字符串 ret_type = func.ret_ctype if func.ret_ctype else func.ret_type self._symtab._InsertFuncSymbol( func.name, ret_type, func.param_types, func.lineno, file_path, func.is_variadic, func.is_inline ) loaded.append(func.name) if self._namespace: ns[func.name] = self._symtab._symbols[func.name] # 插入 define 符号 for define in module_symbols.defines: self._symtab._InsertDefineSymbol( define.name, define.value, define.lineno, file_path ) loaded.append(define.name) if self._namespace: ns[define.name] = self._symtab._symbols[define.name] # 插入匿名类型符号(短名) for anon_name, anon_data in module_symbols.anonymous_types.items(): self._symtab._InsertAnonymousSymbol( anon_name, anon_data.is_union, anon_data.members, anon_data.lineno, file_path ) return loaded