Files
TransPyV/App/lib/core/SymbolInserter.py

90 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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