修复了大量存在的问题,增加了假鸭子类型等等机制
This commit is contained in:
@@ -1,11 +1,22 @@
|
||||
from __future__ import annotations
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import TYPE_CHECKING, Any, Dict, Iterator
|
||||
if TYPE_CHECKING:
|
||||
from lib.core.translator import Translator
|
||||
|
||||
import ast
|
||||
import traceback
|
||||
|
||||
from lib.core.Handles.HandlesBase import CTypeInfo, CTypeHelper
|
||||
from lib.includes import t
|
||||
from typing import Any, Dict, Iterator
|
||||
import ast
|
||||
from lib.core.VLogger import get_logger as _vlog
|
||||
from lib.core.DiagnosticCollector import DiagnosticCollector
|
||||
from lib.core.LLVMTypeMapper import LLVMTypeMapper
|
||||
from lib.core.SymbolExtractor import ASTSymbolExtractor
|
||||
from lib.core.SymbolTypeResolver import TypeResolver
|
||||
from lib.core.SymbolInserter import SymbolInserter
|
||||
from lib.core.SymbolReexporter import PackageReexporter
|
||||
from lib.core.ConstEvaluator import ConstEvaluator
|
||||
from lib.core.SymbolData import ModuleSymbols
|
||||
|
||||
# 从 SymbolUtils 重导出,保持向后兼容
|
||||
from lib.core.SymbolUtils import IsTModuleType as _IsTModuleType
|
||||
@@ -14,30 +25,35 @@ from lib.core.SymbolUtils import CheckAnnotationHasCInline as _CheckAnnotationHa
|
||||
|
||||
|
||||
class SymbolTable:
|
||||
def __init__(self, translator: "Translator"):
|
||||
self.translator = translator
|
||||
self._symbols: Dict[str, CTypeInfo] = {}
|
||||
from lib.core.DiagnosticCollector import DiagnosticCollector
|
||||
self.diagnostics = DiagnosticCollector()
|
||||
from lib.core.LLVMTypeMapper import LLVMTypeMapper
|
||||
self._type_mapper = LLVMTypeMapper(self)
|
||||
self.import_aliases: Dict[str, str] = {}
|
||||
def __init__(self, translator: Translator) -> None:
|
||||
self.translator: Translator = translator
|
||||
self._symbols: dict[str, CTypeInfo] = {}
|
||||
self._namespaces: dict[str, dict[str, CTypeInfo]] = {} # 模块名 -> 符号字典
|
||||
self._namespace_imports: dict[str, set[str]] = {} # 模块名 -> 已导入的模块名集合
|
||||
self._t_type_symbols: dict[str, type] = {} # 别名 -> t.CType 子类 (from t import CEnum as en)
|
||||
self.diagnostics: DiagnosticCollector = DiagnosticCollector()
|
||||
self._type_mapper: LLVMTypeMapper = LLVMTypeMapper(self)
|
||||
self.import_aliases: dict[str, str] = {} # 别名 -> 模块路径
|
||||
|
||||
def clear(self):
|
||||
def clear(self) -> None:
|
||||
self._symbols.clear()
|
||||
self._namespaces.clear()
|
||||
self._namespace_imports.clear()
|
||||
self._t_type_symbols.clear()
|
||||
self.import_aliases.clear()
|
||||
|
||||
def get(self, name: str, default=None) -> CTypeInfo:
|
||||
def get(self, name: str, default: CTypeInfo | None = None) -> CTypeInfo | None:
|
||||
return self._symbols.get(name, default)
|
||||
|
||||
def set(self, name: str, value: Any):
|
||||
def set(self, name: str, value: CTypeInfo | dict[str, Any]) -> None:
|
||||
if isinstance(value, CTypeInfo):
|
||||
self._symbols[name] = value
|
||||
else:
|
||||
# 兼容旧代码传入 dict 的情况
|
||||
info = self._CTypeInfoFromDict(name, value)
|
||||
info: CTypeInfo = self._CTypeInfoFromDict(name, value)
|
||||
self._symbols[name] = info
|
||||
|
||||
def update(self, symbols: Dict[str, Any]):
|
||||
def update(self, symbols: dict[str, CTypeInfo | dict[str, Any]]) -> None:
|
||||
for name, value in symbols.items():
|
||||
self.set(name, value)
|
||||
|
||||
@@ -50,7 +66,7 @@ class SymbolTable:
|
||||
def items(self) -> Iterator[tuple[str, CTypeInfo]]:
|
||||
return iter(self._symbols.items())
|
||||
|
||||
def pop(self, name: str, *args) -> CTypeInfo:
|
||||
def pop(self, name: str, *args: Any) -> CTypeInfo:
|
||||
return self._symbols.pop(name, *args)
|
||||
|
||||
def __getitem__(self, name: str) -> CTypeInfo:
|
||||
@@ -58,10 +74,10 @@ class SymbolTable:
|
||||
return self._symbols[name]
|
||||
raise KeyError(name)
|
||||
|
||||
def __setitem__(self, name: str, value: Any):
|
||||
def __setitem__(self, name: str, value: CTypeInfo | dict[str, Any]) -> None:
|
||||
self.set(name, value)
|
||||
|
||||
def __delitem__(self, name: str):
|
||||
def __delitem__(self, name: str) -> None:
|
||||
del self._symbols[name]
|
||||
|
||||
def __contains__(self, name: str) -> bool:
|
||||
@@ -78,8 +94,73 @@ class SymbolTable:
|
||||
# ==================================================================
|
||||
|
||||
def lookup(self, name: str) -> CTypeInfo | None:
|
||||
"""查找符号,不存在返回 None(替代 `SymbolTable.get(name)`)"""
|
||||
return self._symbols.get(name)
|
||||
"""查找符号,支持别名解析和 dotted name
|
||||
|
||||
解析顺序:
|
||||
1. 直接匹配 _symbols
|
||||
2. 如果包含 '.',解析第一个段为别名后查找剩余路径
|
||||
3. 查 _t_type_symbols(t/c 类型别名,返回模拟 CTypeInfo)
|
||||
"""
|
||||
if name in self._symbols:
|
||||
return self._symbols[name]
|
||||
|
||||
if '.' not in name:
|
||||
return self._lookup_t_type(name)
|
||||
|
||||
# dotted name: 尝试解析第一个段为别名
|
||||
parts: list[str] = name.split('.', 1)
|
||||
first: str = parts[0]
|
||||
rest: str = parts[1]
|
||||
|
||||
# 1) 别名解析:import X as Y → Y.Symbol → X.Symbol
|
||||
resolved: str | None = self.import_aliases.get(first)
|
||||
if resolved:
|
||||
alias_name: str = f"{resolved}.{rest}"
|
||||
if alias_name in self._symbols:
|
||||
return self._symbols[alias_name]
|
||||
|
||||
# 2) 纯路径查找:module.ClassName
|
||||
# (已在 line 100 检查过,此处为兜底,保留注释说明路径查找语义)
|
||||
|
||||
return None
|
||||
|
||||
def _lookup_t_type(self, name: str) -> CTypeInfo | None:
|
||||
"""在 _t_type_symbols 中查找 t/c 类型别名,返回模拟 CTypeInfo"""
|
||||
cls: type | None = self._t_type_symbols.get(name)
|
||||
if cls is None:
|
||||
return None
|
||||
info: CTypeInfo = CTypeInfo()
|
||||
info.Name = name
|
||||
info.BaseType = cls()
|
||||
if issubclass(cls, (t.CEnum, t.REnum)):
|
||||
info.IsEnum = True
|
||||
elif issubclass(cls, t.CUnion):
|
||||
info.IsUnion = True
|
||||
elif issubclass(cls, t.CStruct):
|
||||
info.IsStruct = True
|
||||
return info
|
||||
|
||||
def lookup_in_namespace(self, name: str, namespace: str) -> CTypeInfo | None:
|
||||
"""在指定模块命名空间中查找符号"""
|
||||
ns: dict[str, CTypeInfo] | None = self._namespaces.get(namespace)
|
||||
if ns:
|
||||
return ns.get(name)
|
||||
return None
|
||||
|
||||
def register_namespace(self, module_name: str) -> None:
|
||||
"""注册一个模块命名空间"""
|
||||
if module_name not in self._namespaces:
|
||||
self._namespaces[module_name] = {}
|
||||
|
||||
def register_namespace_import(self, importer: str, imported: str) -> None:
|
||||
"""记录模块导入关系"""
|
||||
if importer not in self._namespace_imports:
|
||||
self._namespace_imports[importer] = set()
|
||||
self._namespace_imports[importer].add(imported)
|
||||
|
||||
def get_namespace_symbols(self, module_name: str) -> dict[str, CTypeInfo]:
|
||||
"""获取模块的命名空间符号表"""
|
||||
return self._namespaces.get(module_name, {})
|
||||
|
||||
def has(self, name: str) -> bool:
|
||||
"""检查符号是否存在(替代 `name in SymbolTable`)"""
|
||||
@@ -87,70 +168,70 @@ class SymbolTable:
|
||||
|
||||
def lookup_struct(self, name: str) -> CTypeInfo | None:
|
||||
"""查找结构体符号,非结构体返回 None"""
|
||||
entry = self._symbols.get(name)
|
||||
entry: CTypeInfo | None = self._symbols.get(name)
|
||||
if entry and (entry.IsStruct or entry.IsCpythonObject):
|
||||
return entry
|
||||
return None
|
||||
|
||||
def lookup_enum(self, name: str) -> CTypeInfo | None:
|
||||
"""查找枚举符号,非枚举返回 None"""
|
||||
entry = self._symbols.get(name)
|
||||
entry: CTypeInfo | None = self._symbols.get(name)
|
||||
if entry and entry.IsEnum:
|
||||
return entry
|
||||
return None
|
||||
|
||||
def lookup_typedef(self, name: str) -> CTypeInfo | None:
|
||||
"""查找 typedef 符号,非 typedef 返回 None"""
|
||||
entry = self._symbols.get(name)
|
||||
entry: CTypeInfo | None = self._symbols.get(name)
|
||||
if entry and entry.IsTypedef:
|
||||
return entry
|
||||
return None
|
||||
|
||||
def lookup_function(self, name: str) -> CTypeInfo | None:
|
||||
"""查找函数符号,非函数返回 None"""
|
||||
entry = self._symbols.get(name)
|
||||
entry: CTypeInfo | None = self._symbols.get(name)
|
||||
if entry and (entry.IsFunction or entry.IsFuncPtr):
|
||||
return entry
|
||||
return None
|
||||
|
||||
def lookup_define(self, name: str) -> CTypeInfo | None:
|
||||
"""查找常量定义符号,非 define 返回 None"""
|
||||
entry = self._symbols.get(name)
|
||||
entry: CTypeInfo | None = self._symbols.get(name)
|
||||
if entry and entry.IsDefine:
|
||||
return entry
|
||||
return None
|
||||
|
||||
def is_struct(self, name: str) -> bool:
|
||||
"""检查名称是否为结构体"""
|
||||
entry = self._symbols.get(name)
|
||||
entry: CTypeInfo | None = self._symbols.get(name)
|
||||
return entry is not None and (entry.IsStruct or entry.IsCpythonObject)
|
||||
|
||||
def is_enum(self, name: str) -> bool:
|
||||
"""检查名称是否为枚举"""
|
||||
entry = self._symbols.get(name)
|
||||
entry: CTypeInfo | None = self._symbols.get(name)
|
||||
return entry is not None and entry.IsEnum
|
||||
|
||||
def is_typedef(self, name: str) -> bool:
|
||||
"""检查名称是否为 typedef"""
|
||||
entry = self._symbols.get(name)
|
||||
entry: CTypeInfo | None = self._symbols.get(name)
|
||||
return entry is not None and entry.IsTypedef
|
||||
|
||||
def is_function(self, name: str) -> bool:
|
||||
"""检查名称是否为函数"""
|
||||
entry = self._symbols.get(name)
|
||||
entry: CTypeInfo | None = self._symbols.get(name)
|
||||
return entry is not None and (entry.IsFunction or entry.IsFuncPtr)
|
||||
|
||||
def is_variable(self, name: str) -> bool:
|
||||
"""检查名称是否为变量"""
|
||||
entry = self._symbols.get(name)
|
||||
entry: CTypeInfo | None = self._symbols.get(name)
|
||||
return entry is not None and entry.IsVariable
|
||||
|
||||
def is_define(self, name: str) -> bool:
|
||||
"""检查名称是否为常量定义"""
|
||||
entry = self._symbols.get(name)
|
||||
entry: CTypeInfo | None = self._symbols.get(name)
|
||||
return entry is not None and entry.IsDefine
|
||||
|
||||
def insert(self, name: str, info: CTypeInfo):
|
||||
def insert(self, name: str, info: CTypeInfo) -> None:
|
||||
"""插入符号(替代 `SymbolTable[name] = info`)"""
|
||||
self._symbols[name] = info
|
||||
|
||||
@@ -160,19 +241,25 @@ class SymbolTable:
|
||||
|
||||
def find_by_suffix(self, suffix: str) -> list[tuple[str, CTypeInfo]]:
|
||||
"""按名称后缀模糊查找符号(替代遍历 + endswith 匹配)"""
|
||||
results = []
|
||||
results: list[tuple[str, CTypeInfo]] = []
|
||||
for name, info in self._symbols.items():
|
||||
if name.endswith(suffix):
|
||||
results.append((name, info))
|
||||
return results
|
||||
|
||||
def ToDict(self) -> Dict[str, Any]:
|
||||
"""序列化为字典格式"""
|
||||
result = {}
|
||||
def ToDict(self) -> dict[str, Any]:
|
||||
"""序列化为字典格式,BaseType 使用可重建的 dict 格式
|
||||
|
||||
返回的 dict 包含:
|
||||
- 符号条目:{name: {attrs}}(与旧格式兼容)
|
||||
- '__namespaces__': {namespace: [symbol_names]} 命名空间索引
|
||||
- '__import_aliases__': {alias: module_path} 导入别名
|
||||
"""
|
||||
result: dict[str, Any] = {}
|
||||
for name, info in self._symbols.items():
|
||||
entry = {'name': name}
|
||||
entry: dict[str, Any] = {'name': name}
|
||||
if info.BaseType:
|
||||
entry['BaseType'] = str(info.BaseType)
|
||||
entry['BaseType'] = self._SerializeBaseType(info.BaseType)
|
||||
if info.PtrCount:
|
||||
entry['PtrCount'] = info.PtrCount
|
||||
if info.IsTypedef:
|
||||
@@ -197,27 +284,99 @@ class SymbolTable:
|
||||
entry['file'] = info.file
|
||||
if info.Members:
|
||||
entry['members'] = info.Members
|
||||
extra = info._sm._extra
|
||||
extra: dict[str, Any] = info._sm._extra
|
||||
if extra:
|
||||
entry.update(extra)
|
||||
result[name] = entry
|
||||
|
||||
# 序列化命名空间信息
|
||||
if self._namespaces:
|
||||
result['__namespaces__'] = {
|
||||
ns: list(symbols.keys()) for ns, symbols in self._namespaces.items()
|
||||
}
|
||||
if self.import_aliases:
|
||||
result['__import_aliases__'] = dict(self.import_aliases)
|
||||
if self._t_type_symbols:
|
||||
result['__t_type_symbols__'] = {
|
||||
name: cls.__name__ for name, cls in self._t_type_symbols.items()
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def _SerializeBaseType(base_type: t.CType | tuple | list | str | None) -> dict | str:
|
||||
"""将 BaseType 序列化为可重建的格式"""
|
||||
if isinstance(base_type, t.CType):
|
||||
return {'class': type(base_type).__name__}
|
||||
if isinstance(base_type, (tuple, list)):
|
||||
return {'classes': [type(b).__name__ for b in base_type if isinstance(b, t.CType)]}
|
||||
return str(base_type)
|
||||
|
||||
@staticmethod
|
||||
def _DeserializeBaseType(data: Any) -> Any:
|
||||
"""从序列化格式恢复 BaseType"""
|
||||
if isinstance(data, dict):
|
||||
if 'class' in data:
|
||||
cls: type | None = getattr(t, data['class'], None)
|
||||
if cls and isinstance(cls, type) and issubclass(cls, t.CType):
|
||||
return cls()
|
||||
elif 'classes' in data:
|
||||
types: list[t.CType] = []
|
||||
for cname in data['classes']:
|
||||
cls: type | None = getattr(t, cname, None)
|
||||
if cls and isinstance(cls, type) and issubclass(cls, t.CType):
|
||||
types.append(cls())
|
||||
if types:
|
||||
return tuple(types)
|
||||
elif isinstance(data, str):
|
||||
cls: type | None = getattr(t, data, None)
|
||||
if cls and isinstance(cls, type) and issubclass(cls, t.CType):
|
||||
return cls()
|
||||
return None
|
||||
|
||||
def FromDict(self, symbols: Dict[str, Any]):
|
||||
"""从字典格式反序列化"""
|
||||
def FromDict(self, symbols: dict[str, Any]) -> None:
|
||||
"""从字典格式反序列化(兼容带/不带命名空间信息的两种格式)"""
|
||||
self._symbols.clear()
|
||||
self._namespaces.clear()
|
||||
self.import_aliases.clear()
|
||||
self._t_type_symbols.clear()
|
||||
|
||||
_SPECIAL_KEYS: frozenset[str] = frozenset({'__namespaces__', '__import_aliases__', '__t_type_symbols__'})
|
||||
|
||||
for name, attrs in symbols.items():
|
||||
if name in _SPECIAL_KEYS:
|
||||
continue
|
||||
if isinstance(attrs, dict):
|
||||
info = self._CTypeInfoFromDict(name, attrs)
|
||||
info: CTypeInfo = self._CTypeInfoFromDict(name, attrs)
|
||||
self._symbols[name] = info
|
||||
elif isinstance(attrs, CTypeInfo):
|
||||
self._symbols[name] = attrs
|
||||
|
||||
# 恢复命名空间信息
|
||||
ns_data: dict[str, list[str]] | None = symbols.get('__namespaces__')
|
||||
if ns_data:
|
||||
for ns, sym_names in ns_data.items():
|
||||
self._namespaces[ns] = {}
|
||||
for sym_name in sym_names:
|
||||
if sym_name in self._symbols:
|
||||
self._namespaces[ns][sym_name] = self._symbols[sym_name]
|
||||
aliases_data: dict[str, str] | None = symbols.get('__import_aliases__')
|
||||
if aliases_data:
|
||||
self.import_aliases.update(aliases_data)
|
||||
|
||||
# 恢复 t 类型别名
|
||||
t_type_data: dict[str, str] | None = symbols.get('__t_type_symbols__')
|
||||
if t_type_data:
|
||||
for name, cls_name in t_type_data.items():
|
||||
cls: type | None = getattr(t, cls_name, None)
|
||||
if cls and isinstance(cls, type) and issubclass(cls, t.CType):
|
||||
self._t_type_symbols[name] = cls
|
||||
|
||||
def _CTypeInfoFromDict(self, name: str, attrs: dict) -> CTypeInfo:
|
||||
def _CTypeInfoFromDict(self, name: str, attrs: dict[str, Any]) -> CTypeInfo:
|
||||
"""从旧 dict 格式创建 CTypeInfo(兼容旧代码)"""
|
||||
info = CTypeInfo()
|
||||
info: CTypeInfo = CTypeInfo()
|
||||
info.Name = name
|
||||
node_type = attrs.get('type', '')
|
||||
node_type: str = attrs.get('type', '')
|
||||
|
||||
if node_type == 'struct' or attrs.get('IsStruct'):
|
||||
info.IsStruct = True
|
||||
@@ -260,13 +419,17 @@ class SymbolTable:
|
||||
info.EnumName = attrs['EnumName']
|
||||
if 'DefineValue' in attrs:
|
||||
info.DefineValue = attrs['DefineValue']
|
||||
if 'BaseType' in attrs:
|
||||
info.BaseType = self._DeserializeBaseType(attrs['BaseType'])
|
||||
if 'name' in attrs and attrs['name'] != name:
|
||||
info.Name = attrs['name']
|
||||
|
||||
# 其他属性存入 _extra
|
||||
skip_keys = {'type', 'PtrCount', 'OriginalType', 'lineno', 'file',
|
||||
skip_keys: frozenset[str] = frozenset({'type', 'name', 'PtrCount', 'OriginalType', 'lineno', 'file',
|
||||
'members', 'IsPtr', 'dims', 'IsCpythonObject', 'IsAnonymous',
|
||||
'IsPacked', 'EnumName', 'DefineValue',
|
||||
'IsPacked', 'EnumName', 'DefineValue', 'BaseType',
|
||||
'IsStruct', 'IsEnum', 'IsUnion', 'IsTypedef',
|
||||
'IsFunction', 'IsVariable', 'IsDefine', 'IsEnumMember'}
|
||||
'IsFunction', 'IsVariable', 'IsDefine', 'IsEnumMember'})
|
||||
for key, value in attrs.items():
|
||||
if key not in skip_keys:
|
||||
info.set(key, value)
|
||||
@@ -281,34 +444,33 @@ class SymbolTable:
|
||||
return self._LoadSymbolsFromFile(FullModulePath, asname, lineno)
|
||||
|
||||
def _LoadSymbolsFromFile(self, FilePath: str, namespace_prefix: str | list[str], lineno: int = 0) -> list[str]:
|
||||
from lib.core.SymbolExtractor import ASTSymbolExtractor
|
||||
from lib.core.SymbolTypeResolver import TypeResolver
|
||||
from lib.core.SymbolInserter import SymbolInserter
|
||||
from lib.core.SymbolReexporter import PackageReexporter
|
||||
|
||||
try:
|
||||
# 提取模块名作为命名空间
|
||||
module_name: str = namespace_prefix[0] if isinstance(namespace_prefix, list) else namespace_prefix
|
||||
|
||||
# Pass 1: 从 AST 提取原始符号信息
|
||||
extractor = ASTSymbolExtractor(self)
|
||||
module_symbols = extractor.extract(FilePath)
|
||||
extractor: ASTSymbolExtractor = ASTSymbolExtractor(self)
|
||||
module_symbols: ModuleSymbols = extractor.extract(FilePath)
|
||||
|
||||
# Pass 2: 解析类型信息(typedef、函数签名、define 值)
|
||||
resolver = TypeResolver(self)
|
||||
resolver: TypeResolver = TypeResolver(self)
|
||||
resolver.resolve(module_symbols)
|
||||
|
||||
# Pass 3: 插入符号到主命名空间(无前缀)
|
||||
inserter = SymbolInserter(self)
|
||||
loaded = inserter.insert(module_symbols)
|
||||
inserter: SymbolInserter = SymbolInserter(self)
|
||||
inserter.set_namespace(module_name)
|
||||
loaded: list[str] = inserter.insert(module_symbols)
|
||||
|
||||
# Pass 4: 重新导出到命名空间前缀下
|
||||
prefixes = [namespace_prefix] if isinstance(namespace_prefix, str) else namespace_prefix
|
||||
reexporter = PackageReexporter(self)
|
||||
prefixes: list[str] = [namespace_prefix] if isinstance(namespace_prefix, str) else namespace_prefix
|
||||
reexporter: PackageReexporter = PackageReexporter(self)
|
||||
reexporter.set_namespace(module_name)
|
||||
loaded.extend(reexporter.reexport(module_symbols, prefixes, lineno))
|
||||
|
||||
return loaded
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
print(traceback.format_exc())
|
||||
_vlog().error(traceback.format_exc())
|
||||
self.diagnostics.error(FilePath, lineno, f"加载模块失败: {e}")
|
||||
return []
|
||||
|
||||
@@ -316,28 +478,28 @@ class SymbolTable:
|
||||
# 类型解析辅助方法(委托到 LLVMTypeMapper)
|
||||
# ==================================================================
|
||||
|
||||
def _GetLLVMTypeStr(self, node):
|
||||
def _GetLLVMTypeStr(self, node: ast.AST) -> str:
|
||||
return self._type_mapper.get_llvm_type_str(node)
|
||||
|
||||
def _GetFuncRetTypeStr(self, returns_node):
|
||||
def _GetFuncRetTypeStr(self, returns_node: ast.AST | None) -> str:
|
||||
return self._type_mapper.get_func_ret_type_str(returns_node)
|
||||
|
||||
@staticmethod
|
||||
def _CheckAnnotationHasCInline(annotation_node) -> bool:
|
||||
def _CheckAnnotationHasCInline(annotation_node: ast.AST | None) -> bool:
|
||||
return _CheckAnnotationHasCInline(annotation_node)
|
||||
|
||||
def _GetFuncParamTypeStr(self, annotation_node):
|
||||
def _GetFuncParamTypeStr(self, annotation_node: ast.AST) -> str:
|
||||
return self._type_mapper.get_func_param_type_str(annotation_node)
|
||||
|
||||
def _ResolveTypedefValueType(self, node):
|
||||
def _ResolveTypedefValueType(self, node: ast.AST) -> str:
|
||||
return self._type_mapper.resolve_typedef_value_type(node)
|
||||
|
||||
# ==================================================================
|
||||
# 符号插入方法(供 SymbolInserter / PackageReexporter 调用)
|
||||
# ==================================================================
|
||||
|
||||
def _InsertClassSymbol(self, FullName: str, TypeKind: str, lineno: int, FilePath: str, members: dict, IsCpythonObject: bool, IsPacked: bool = False):
|
||||
info = CTypeInfo()
|
||||
def _InsertClassSymbol(self, FullName: str, TypeKind: str, lineno: int, FilePath: str, members: dict[str, CTypeInfo], IsCpythonObject: bool, IsPacked: bool = False) -> None:
|
||||
info: CTypeInfo = CTypeInfo()
|
||||
info.Lineno = lineno
|
||||
info.file = FilePath
|
||||
info.Members = members if members else {}
|
||||
@@ -359,17 +521,18 @@ class SymbolTable:
|
||||
|
||||
self._symbols[FullName] = info
|
||||
|
||||
def _InsertEnumMemberSymbol(self, FullName: str, EnumName: str, lineno: int, FilePath: str):
|
||||
info = CTypeInfo()
|
||||
def _InsertEnumMemberSymbol(self, FullName: str, EnumName: str, lineno: int, FilePath: str) -> None:
|
||||
info: CTypeInfo = CTypeInfo()
|
||||
info.IsEnumMember = True
|
||||
info.EnumName = EnumName
|
||||
info.Lineno = lineno
|
||||
info.file = FilePath
|
||||
self._symbols[FullName] = info
|
||||
|
||||
def _InsertTypedefSymbol(self, FullName: str, OriginalType_kind: str | None, OriginalClass, lineno: int, FilePath: str, members: dict | None = None):
|
||||
info = CTypeInfo()
|
||||
def _InsertTypedefSymbol(self, FullName: str, OriginalType_kind: str | None, OriginalClass: CTypeInfo | str | None, lineno: int, FilePath: str, members: dict[str, CTypeInfo] | None = None) -> None:
|
||||
info: CTypeInfo = CTypeInfo()
|
||||
info.IsTypedef = True
|
||||
info.Name = FullName
|
||||
info.Lineno = lineno
|
||||
info.file = FilePath
|
||||
if members:
|
||||
@@ -378,7 +541,7 @@ class SymbolTable:
|
||||
if isinstance(OriginalClass, CTypeInfo):
|
||||
info.OriginalType = OriginalClass
|
||||
elif OriginalType_kind == 'typedef' and OriginalClass and isinstance(OriginalClass, str) and ('*' in OriginalClass):
|
||||
OriginalType = OriginalClass
|
||||
OriginalType: str = OriginalClass
|
||||
if OriginalType == 'CVoid *':
|
||||
OriginalType = 'void *'
|
||||
info.OriginalType = OriginalType
|
||||
@@ -393,15 +556,15 @@ class SymbolTable:
|
||||
|
||||
self._symbols[FullName] = info
|
||||
|
||||
def _InsertModuleSymbol(self, name: str, lineno: int, FilePath: str):
|
||||
info = CTypeInfo()
|
||||
def _InsertModuleSymbol(self, name: str, lineno: int, FilePath: str) -> None:
|
||||
info: CTypeInfo = CTypeInfo()
|
||||
info.IsModuleAlias = True
|
||||
info.Lineno = lineno
|
||||
info.file = FilePath
|
||||
self._symbols[name] = info
|
||||
|
||||
def _InsertFuncSymbol(self, FullName: str, RetType, ParamTypes: list, lineno: int, FilePath: str, IsVariadic: bool = False, IsInline: bool = False):
|
||||
info = CTypeInfo()
|
||||
def _InsertFuncSymbol(self, FullName: str, RetType: str | CTypeInfo | None, ParamTypes: list[str], lineno: int, FilePath: str, IsVariadic: bool = False, IsInline: bool = False) -> None:
|
||||
info: CTypeInfo = CTypeInfo()
|
||||
info.IsFunction = True
|
||||
if isinstance(RetType, str):
|
||||
info.FuncPtrReturn = CTypeInfo.FromTypeName(RetType) if RetType else CTypeInfo.VoidTypeInfo()
|
||||
@@ -418,21 +581,20 @@ class SymbolTable:
|
||||
info.file = FilePath
|
||||
self._symbols[FullName] = info
|
||||
|
||||
def _InsertDefineSymbol(self, FullName: str, DefineValue, lineno: int, FilePath: str):
|
||||
info = CTypeInfo()
|
||||
def _InsertDefineSymbol(self, FullName: str, DefineValue: int | str | float | bool | None, lineno: int, FilePath: str) -> None:
|
||||
info: CTypeInfo = CTypeInfo()
|
||||
info.IsDefine = True
|
||||
info.DefineValue = DefineValue
|
||||
info.Lineno = lineno
|
||||
info.file = FilePath
|
||||
self._symbols[FullName] = info
|
||||
|
||||
def _eval_const_expr(self, node):
|
||||
def _eval_const_expr(self, node: ast.AST) -> int | float | str | None:
|
||||
"""计算常量表达式的值(委托到 ConstEvaluator)"""
|
||||
from lib.core.ConstEvaluator import ConstEvaluator
|
||||
return ConstEvaluator.eval_with_symtab(node, self)
|
||||
|
||||
def _InsertAnonymousSymbol(self, FullName: str, IsUnion: bool, members: dict, lineno: int, FilePath: str):
|
||||
info = CTypeInfo()
|
||||
def _InsertAnonymousSymbol(self, FullName: str, IsUnion: bool, members: dict[str, CTypeInfo], lineno: int, FilePath: str) -> None:
|
||||
info: CTypeInfo = CTypeInfo()
|
||||
if IsUnion:
|
||||
info.IsUnion = True
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user