Files
TransPyC/lib/core/SymbolReexporter.py
2026-07-18 19:25:40 +08:00

100 lines
4.8 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 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