阶段 2 完成

This commit is contained in:
2026-06-18 12:42:44 +08:00
parent 599335e93d
commit f99666420b
19 changed files with 874 additions and 641 deletions

View File

@@ -7,7 +7,8 @@ from lib.includes import t
import ast
from typing import List, Dict
from enum import IntFlag, auto
from enum import IntFlag, auto
from lib.core.TypeSpec import TypeSpec, SymbolMeta, FIELD_ROUTES
EXCEPTION_CODE_MAP = {
@@ -66,57 +67,72 @@ class CTypeInfo:
"""
def __init__(self):
self._BaseType: t.CType = None
self.PtrCount: int = 0
self.VarConst: bool = False
self.VarVolatile: bool = False
self.DataConst: bool = False
self.DataVolatile: bool = False
self.ArrayDims: List[str] = []
self.Storage: t.CType = None
self.IsFuncPtr: bool = False
self.FuncPtrParams: List[Tuple[str, 'CTypeInfo']] = [] # 函数指针参数列表:(参数名, 参数类型)
self.FuncParamNames: List[str] = [] # 函数参数名列表
self.FuncPtrReturn: "CTypeInfo" = None
self.IsBitField: bool = False
self.BitWidth: int = 0
self.ByteOrder: str = "" # "big", "little", or ""
self.IsTypedef: bool = False
self.IsStruct: bool = False
self.IsEnum: bool = False
self.IsUnion: bool = False
self.IsRenum: bool = False
self.RenumVariants: list = []
self.Name: str = ""
self.Members: Dict[str, 'CTypeInfo'] = {}
self.OriginalType: "CTypeInfo" = None
self.DeclaredType: str = ""
self.CreturnTypes: list = []
self.Lineno: int = 0
self.file: str = ""
self.IsAnonymous: bool = False
self.IsCpythonObject: bool = False
self.IsEnumMember: bool = False
self.IsVariadic: bool = False
self.IsVariable: bool = False
self.IsFunction: bool = False
self.MetaList: FuncMeta = FuncMeta.NONE
self.IsArrayPtr: bool = False
self.ArrayPtr: 'CTypeInfo' = None
self.IsState: bool = False
self.IsDefine: bool = False
self.DefineValue = None
self.IsInline: bool = False
self.InlineBody: list = None
self.InlineParams: list = None
self.ModuleName: str = ""
self._extra: dict = {}
object.__setattr__(self, '_ts', TypeSpec())
sm = SymbolMeta()
sm.meta_list = FuncMeta.NONE
object.__setattr__(self, '_sm', sm)
# --- 新公共 API供新代码直接访问 TypeSpec / SymbolMeta / SymbolKind ---
@property
def ts(self) -> TypeSpec:
"""TypeSpec — 纯类型描述(只读)"""
return self._ts
@property
def sm(self) -> SymbolMeta:
"""SymbolMeta — 符号表元数据(只读)"""
return self._sm
@property
def kind(self) -> 'SymbolKind':
"""SymbolKind — 符号类型种类枚举"""
return self._sm.kind
def __setattr__(self, name, value):
"""属性设置路由 — 将旧字段名委托到 _ts/_sm/_kind_flags"""
if name == 'BaseType':
# BaseType 有复杂的 property setter自动设置 IsStruct/IsEnum/IsUnion
CTypeInfo.BaseType.fset(self, value)
return
if name in ('_ts', '_sm', 'ts', 'sm', 'kind'):
# _ts/_sm 内部字段直接设置ts/sm/kind 是只读 property禁止设置
if name in ('ts', 'sm', 'kind'):
raise AttributeError(f"'CTypeInfo' attribute '{name}' is read-only")
object.__setattr__(self, name, value)
return
if name in FIELD_ROUTES:
target, field = FIELD_ROUTES[name]
if target == 'ts':
setattr(self._ts, field, value)
elif target == 'sm':
setattr(self._sm, field, value)
elif target == 'kf':
self._sm._kind_flags[field] = value
return
object.__setattr__(self, name, value)
def __getattr__(self, name):
"""属性读取路由 — 将旧字段名委托到 _ts/_sm/_kind_flags"""
try:
ts = object.__getattribute__(self, '_ts')
sm = object.__getattribute__(self, '_sm')
except AttributeError:
raise AttributeError(f"'CTypeInfo' object has no attribute '{name}'")
if name in FIELD_ROUTES:
target, field = FIELD_ROUTES[name]
if target == 'ts':
return getattr(ts, field)
elif target == 'sm':
return getattr(sm, field)
elif target == 'kf':
return sm._kind_flags.get(field, False)
raise AttributeError(f"'CTypeInfo' object has no attribute '{name}'")
@property
def BaseType(self) -> t.CType | tuple:
return self._BaseType
return self._ts._base_type
@BaseType.setter
def BaseType(self, value: t.CType | type | tuple | List):
@@ -127,54 +143,57 @@ class CTypeInfo:
- type (CType 子类): 如 t.CStruct自动实例化
- tuple/list of t.CType: 多个组合类型
"""
ts = self._ts
kf = self._sm._kind_flags
if value is None:
self._BaseType = None
self.IsStruct = False
self.IsEnum = False
self.IsUnion = False
self.IsRenum = False
ts._base_type = None
kf['IsStruct'] = False
kf['IsEnum'] = False
kf['IsUnion'] = False
kf['IsRenum'] = False
return
if isinstance(value, (tuple, list)):
self._BaseType = tuple(value)
ts._base_type = tuple(value)
for v in value:
if isinstance(v, t.CStruct):
self.IsStruct = True
kf['IsStruct'] = True
elif isinstance(v, t.CEnum):
self.IsEnum = True
kf['IsEnum'] = True
elif isinstance(v, t.CUnion):
self.IsUnion = True
kf['IsUnion'] = True
elif isinstance(v, t.REnum):
self.IsRenum = True
self.IsEnum = True
kf['IsRenum'] = True
kf['IsEnum'] = True
return
if isinstance(value, type) and issubclass(value, t.CType):
self._BaseType = value()
ts._base_type = value()
return
if isinstance(value, t.CType):
self._BaseType = value
ts._base_type = value
if isinstance(value, t.CStruct):
self.IsStruct = True
self.IsEnum = False
self.IsUnion = False
self.IsRenum = False
kf['IsStruct'] = True
kf['IsEnum'] = False
kf['IsUnion'] = False
kf['IsRenum'] = False
elif isinstance(value, t.REnum):
self.IsRenum = True
self.IsEnum = True
self.IsStruct = False
self.IsUnion = False
kf['IsRenum'] = True
kf['IsEnum'] = True
kf['IsStruct'] = False
kf['IsUnion'] = False
elif isinstance(value, t.CEnum):
self.IsEnum = True
self.IsStruct = False
self.IsUnion = False
self.IsRenum = False
kf['IsEnum'] = True
kf['IsStruct'] = False
kf['IsUnion'] = False
kf['IsRenum'] = False
elif isinstance(value, t.CUnion):
self.IsUnion = True
self.IsStruct = False
self.IsEnum = False
self.IsRenum = False
kf['IsUnion'] = True
kf['IsStruct'] = False
kf['IsEnum'] = False
kf['IsRenum'] = False
return
raise TypeError(f"BaseType must be t.CType instance, type subclass, or tuple of t.CType, got {type(value)}")
@@ -182,82 +201,92 @@ class CTypeInfo:
@property
def TypeCls(self):
"""获取 CType 类(从 BaseType 推断)"""
if self.BaseType:
return type(self.BaseType)
if self.IsStruct:
bt = self._ts._base_type
if bt:
return type(bt)
kf = self._sm._kind_flags
if kf.get('IsStruct'):
return t.CStruct
if self.IsEnum:
if kf.get('IsEnum'):
return t.CEnum
if self.IsUnion:
if kf.get('IsUnion'):
return t.CUnion
if self.IsTypedef:
if kf.get('IsTypedef'):
return t._CTypedef
return None
@property
def IsPtr(self) -> bool:
return self.PtrCount > 0
return self._ts.ptr_count > 0
@property
def IsVoid(self) -> bool:
return isinstance(self.BaseType, t.CVoid)
return isinstance(self._ts._base_type, t.CVoid)
@property
def IsStr(self) -> bool:
return isinstance(self.BaseType, t.CChar) and self.PtrCount > 0
return isinstance(self._ts._base_type, t.CChar) and self._ts.ptr_count > 0
@property
def IsInt(self) -> bool:
return isinstance(self.BaseType, t.CType) and getattr(self.BaseType, 'IsSigned', None) is not None and self.BaseType.IsSigned is True and not self.IsVoid
bt = self._ts._base_type
return isinstance(bt, t.CType) and getattr(bt, 'IsSigned', None) is not None and bt.IsSigned is True and not isinstance(bt, t.CVoid)
@property
def IsUInt(self) -> bool:
return isinstance(self.BaseType, t.CType) and getattr(self.BaseType, 'IsSigned', None) is False
bt = self._ts._base_type
return isinstance(bt, t.CType) and getattr(bt, 'IsSigned', None) is False
@property
def IsFloat(self) -> bool:
bt = self.BaseType
bt = self._ts._base_type
return isinstance(bt, t.CType) and getattr(bt, 'IsSigned', None) is None and getattr(bt, 'Size', 0) in (32, 64, 128) and not isinstance(bt, t.CVoid)
@property
def IsDouble(self) -> bool:
return isinstance(self.BaseType, t.CDouble) or (isinstance(self.BaseType, t.CFloat64T))
bt = self._ts._base_type
return isinstance(bt, t.CDouble) or isinstance(bt, t.CFloat64T)
@property
def IsPointerToChar(self) -> bool:
return isinstance(self.BaseType, t.CChar) and self.PtrCount > 0
return isinstance(self._ts._base_type, t.CChar) and self._ts.ptr_count > 0
def ToString(self) -> str:
if self.IsFuncPtr:
ts = self._ts
sm = self._sm
kf = sm._kind_flags
bt = ts._base_type
if ts.is_func_ptr:
return 'Callable'
parts = []
if self.Storage and not isinstance(self.Storage, t.CExport):
parts.append(self.Storage.CName)
if ts.storage and not isinstance(ts.storage, t.CExport):
parts.append(ts.storage.CName)
if self.DataConst or self.DataVolatile:
if ts.data_const or ts.data_volatile:
qualifiers = []
if self.DataConst:
if ts.data_const:
qualifiers.append("const")
if self.DataVolatile:
if ts.data_volatile:
qualifiers.append("volatile")
parts.append("_".join(qualifiers))
if self.IsTypedef and self.Name:
return self.Name
elif self.IsRenum and self.Name:
base_name = self.Name
elif self.BaseType:
base_name = getattr(self.BaseType, 'CName', None) or (self.BaseType if isinstance(self.BaseType, str) else str(self.BaseType))
if kf.get('IsTypedef') and sm.name:
return sm.name
elif kf.get('IsRenum') and sm.name:
base_name = sm.name
elif bt:
base_name = getattr(bt, 'CName', None) or (bt if isinstance(bt, str) else str(bt))
else:
base_name = "void"
if self.IsArrayPtr:
if ts.is_array_ptr:
ptr_str = ""
if self.PtrCount > 0:
ptr_str = "*" * self.PtrCount
if self.ArrayPtr:
inner = self.ArrayPtr.ToString()
if ts.ptr_count > 0:
ptr_str = "*" * ts.ptr_count
if ts.array_ptr:
inner = ts.array_ptr.ToString()
if ptr_str:
parts.append(f"{base_name} {ptr_str}({inner})")
else:
@@ -267,22 +296,22 @@ class CTypeInfo:
parts.append(f"{base_name} {ptr_str}()")
else:
parts.append(f"{base_name} ()")
elif self.ArrayPtr:
inner = self.ArrayPtr.ToString()
if self.PtrCount > 0:
parts.append(f"{base_name} {'*' * self.PtrCount}({inner})")
elif ts.array_ptr:
inner = ts.array_ptr.ToString()
if ts.ptr_count > 0:
parts.append(f"{base_name} {'*' * ts.ptr_count}({inner})")
else:
parts.append(f"{base_name} ({inner})")
else:
parts.append(base_name)
if self.PtrCount > 0:
parts.append("*" * self.PtrCount)
if self.VarConst:
if ts.ptr_count > 0:
parts.append("*" * ts.ptr_count)
if ts.var_const:
parts.append("const")
if self.VarVolatile:
if ts.var_volatile:
parts.append("volatile")
for dim in self.ArrayDims:
for dim in ts.array_dims:
if dim:
parts.append(f"[{dim}]")
else:
@@ -1098,58 +1127,28 @@ class CTypeInfo:
def Copy(self) -> "CTypeInfo":
NewInfo = CTypeInfo()
NewInfo.BaseType = self.BaseType
NewInfo.PtrCount = self.PtrCount
NewInfo.VarConst = self.VarConst
NewInfo.VarVolatile = self.VarVolatile
NewInfo.DataConst = self.DataConst
NewInfo.DataVolatile = self.DataVolatile
NewInfo.ArrayDims = list(self.ArrayDims)
NewInfo.Storage = self.Storage
NewInfo.IsFuncPtr = self.IsFuncPtr
NewInfo.FuncPtrParams = list(self.FuncPtrParams)
NewInfo.FuncParamNames = list(self.FuncParamNames)
NewInfo.FuncPtrReturn = self.FuncPtrReturn.Copy() if isinstance(self.FuncPtrReturn, CTypeInfo) else self.FuncPtrReturn
NewInfo.IsBitField = self.IsBitField
NewInfo.BitWidth = self.BitWidth
NewInfo.IsTypedef = self.IsTypedef
NewInfo.IsStruct = self.IsStruct
NewInfo.IsEnum = self.IsEnum
NewInfo.IsUnion = self.IsUnion
NewInfo.IsRenum = self.IsRenum
NewInfo.RenumVariants = list(self.RenumVariants)
NewInfo.Name = self.Name
NewInfo.Members = dict(self.Members)
NewInfo.OriginalType = self.OriginalType.Copy() if isinstance(self.OriginalType, CTypeInfo) else self.OriginalType
NewInfo.DeclaredType = self.DeclaredType
NewInfo.CreturnTypes = list(self.CreturnTypes)
NewInfo.Lineno = self.Lineno
NewInfo.file = self.file
NewInfo.IsAnonymous = self.IsAnonymous
NewInfo.IsCpythonObject = self.IsCpythonObject
NewInfo.IsEnumMember = self.IsEnumMember
NewInfo.IsVariadic = self.IsVariadic
NewInfo.IsVariable = self.IsVariable
NewInfo.IsFunction = self.IsFunction
NewInfo.MetaList = self.MetaList
NewInfo.IsArrayPtr = self.IsArrayPtr
NewInfo.ArrayPtr = self.ArrayPtr.Copy() if self.ArrayPtr else None
NewInfo.IsState = self.IsState
NewInfo.IsDefine = self.IsDefine
NewInfo.DefineValue = self.DefineValue
NewInfo.IsInline = self.IsInline
NewInfo.InlineBody = self.InlineBody
NewInfo.InlineParams = list(self.InlineParams) if self.InlineParams else None
NewInfo._extra = dict(self._extra)
NewInfo._ts = self._ts.copy()
NewInfo._sm = self._sm.copy()
# CTypeInfo 引用字段需要深拷贝
if isinstance(NewInfo._ts.func_ptr_return, CTypeInfo):
NewInfo._ts.func_ptr_return = NewInfo._ts.func_ptr_return.Copy()
if isinstance(NewInfo._ts.original_type, CTypeInfo):
NewInfo._ts.original_type = NewInfo._ts.original_type.Copy()
if NewInfo._ts.array_ptr:
NewInfo._ts.array_ptr = NewInfo._ts.array_ptr.Copy()
# 实例上的动态属性也需要拷贝(如 IsSigned 等)
for key, val in self.__dict__.items():
if key not in ('_ts', '_sm'):
object.__setattr__(NewInfo, key, val)
return NewInfo
def get(self, key, default=None):
"""获取额外属性"""
return self._extra.get(key, default)
return self._sm._extra.get(key, default)
def set(self, key, value):
"""设置额外属性"""
self._extra[key] = value
self._sm._extra[key] = value
@staticmethod
def VoidTypeInfo() -> "CTypeInfo":
@@ -1173,7 +1172,9 @@ class CTypeInfo:
return self.ToString()
def __repr__(self) -> str:
return f"CTypeInfo(BaseType={self.BaseType}, PtrCount={self.PtrCount}, IsTypedef={self.IsTypedef}, OriginalType={self.OriginalType!r}, VarConst={self.VarConst}, DataConst={self.DataConst})"
ts = self._ts
kf = self._sm._kind_flags
return f"CTypeInfo(BaseType={ts._base_type}, PtrCount={ts.ptr_count}, IsTypedef={kf.get('IsTypedef', False)}, OriginalType={ts.original_type!r}, VarConst={ts.var_const}, DataConst={ts.data_const})"
class CTypeHelper: