from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from lib.core.translator import Translator
from typing import List
from lib.core.Handles.HandlesBase import BaseHandle, CTypeHelper, CTypeInfo
from lib.core.SymbolUtils import IsTModule, IsListAnnotation
from lib.includes import t
import lib._bootstrap  # noqa: F401  设置 sys.path（项目根 + lib/includes）
import ast


class HandlesTypeMerge(BaseHandle):
    """处理类型合并逻辑 - 所有类型分析的核心模块"""

    def _MakeVoidCTypeInfo(self) -> CTypeInfo:
        Info = CTypeInfo()
        Info.BaseType = t.CVoid
        return Info

    @staticmethod
    def _MakeCTypeInfoFromName(TypeName: str) -> CTypeInfo:
        """直接从类型名构造 CTypeInfo，不经过 FromStr/字符串解析"""
        return CTypeInfo.FromTypeName(TypeName)

    def GetCTypeInfo(self, Node: ast.AST) -> CTypeInfo:
        """获取 CTypeInfo 对象"""
        Result = self._GetCTypeInfoInternal(Node)
        if isinstance(Result, CTypeInfo):
            return Result
        elif isinstance(Result, str):
            return self._MakeCTypeInfoFromName(Result)
        else:
            return self._MakeVoidCTypeInfo()

    def _GetCTypeInfoInternal(self, Node: ast.AST) -> CTypeInfo | str | None:
        """鍐呴儴鏂规硶锛岃繑鍥?CTypeInfo"""
        LineNum = getattr(Node, 'lineno', None)

        self.Trans.DebugPrint(f"[GetCTypeInfo] Node type: {type(Node).__name__}, dump: {ast.dump(Node)[:60]}...")

        if isinstance(Node, ast.Constant):
            TypeName = Node.value
            return self._MakeCTypeInfoFromName(TypeName)

        if isinstance(Node, ast.Name):
            TypeName = Node.id
            t_c_imported = getattr(self.Trans, '_t_c_imported_names', {})
            if TypeName in t_c_imported:
                src_module, src_name = t_c_imported[TypeName]
                virtual_attr = ast.Attribute(
                    value=ast.Name(id=src_module, ctx=ast.Load()),
                    attr=src_name,
                    ctx=ast.Load()
                )
                ast.copy_location(virtual_attr, Node)
                return self.GetCTypeInfo(virtual_attr)
            Entry = self.Trans.SymbolTable.lookup(TypeName)
            if Entry and Entry.IsTypedef:
                if isinstance(Entry, CTypeInfo) and Entry.BaseType:
                    if not isinstance(Entry.BaseType, (t._CTypedef,)) or Entry.PtrCount > 0:
                        Result = Entry.Copy()
                        Result.IsTypedef = True
                        Result.Name = TypeName
                        return Result
                if Entry.OriginalType:
                    if isinstance(Entry.OriginalType, CTypeInfo) and Entry.OriginalType.IsFuncPtr:
                        Result = CTypeInfo()
                        Result.IsFuncPtr = True
                        Result.FuncPtrReturn = Entry.OriginalType.FuncPtrReturn or CTypeInfo.VoidTypeInfo()
                        Result.FuncPtrParams = list(Entry.OriginalType.FuncPtrParams) if Entry.OriginalType.FuncPtrParams else []
                        Result.IsTypedef = True
                        Result.Name = TypeName
                        return Result
                    elif isinstance(Entry.OriginalType, CTypeInfo):
                        Resolved = Entry.OriginalType.Copy()
                        Resolved.IsTypedef = True
                        Resolved.Name = TypeName
                        return Resolved
                    elif isinstance(Entry.OriginalType, str):
                        # 字符串 OriginalType（如 'void *'）需解析为 CTypeInfo，
                        # 否则返回的 Entry BaseType=None 会被下游误判为 i32
                        Resolved = CTypeInfo.FromTypeName(Entry.OriginalType)
                        if Resolved and Resolved.BaseType:
                            Resolved.IsTypedef = True
                            Resolved.Name = TypeName
                            return Resolved
                return Entry
            # REnum 优先于 IsEnum 处理（REnum 同时有 IsEnum=True 和 IsStruct=True）
            # 必须设置 Name 和 PtrCount=1，否则 BinOp `LLVMType | t.CPtr` 合并后丢失 REnum 语义
            if isinstance(Entry, CTypeInfo) and Entry.IsRenum:
                Result = Entry.Copy()
                Result.Name = TypeName
                Result.PtrCount = 1  # REnum 变量默认为指针（和 struct 一致）
                return Result
            # 类名与枚举成员名冲突时（如 Constant 既是 ASTKind.Constant 枚举成员又是结构体类名），
            # 优先检查 Gen.structs：类型注解应解析为结构体而非枚举值
            _Gen = getattr(self.Trans, 'LlvmGen', None)
            if _Gen and TypeName in _Gen.structs:
                Result = CTypeInfo()
                Result.BaseType = t.CStruct(name=TypeName)
                Result.IsStruct = True
                Result.Name = TypeName
                Result.PtrCount = 1
                return Result
            if isinstance(Entry, CTypeInfo) and Entry.IsEnum:
                return Entry.Copy()
            if isinstance(Entry, dict) and Entry.get('IsEnum'):
                Result = CTypeInfo()
                Result.BaseType = t.CEnum(TypeName)
                Result.IsEnum = True
                return Result
            # 检测结构体类型 (CTypeInfo with IsStruct=True, 来自 _InsertClassSymbol)
            if isinstance(Entry, CTypeInfo) and Entry.IsStruct:
                Result = Entry.Copy()
                if Result.BaseType is None:
                    Result.BaseType = t.CStruct(name=TypeName)
                Result.Name = TypeName
                Result.PtrCount = 1  # struct 变量默认为指针
                return Result
            return self._MakeCTypeInfoFromName(TypeName)

        elif isinstance(Node, ast.Attribute):
            ModuleParts = []
            Current = Node
            while isinstance(Current, ast.Attribute):
                ModuleParts.insert(0, Current.attr)
                Current = Current.value

            if isinstance(Current, ast.Name):
                ModuleParts.insert(0, Current.id)

            if len(ModuleParts) >= 2:
                TypeName = ModuleParts[-1]
                ModulePath = '.'.join(ModuleParts[:-1])
            elif len(ModuleParts) == 1:
                TypeName = ModuleParts[0]
                ModulePath = None
            else:
                return self._MakeVoidCTypeInfo()

            # 解析 import 别名: 如 import fat32_types as types -> types -> fat32_types
            if ModulePath:
                import_aliases = self.Trans.SymbolTable.import_aliases
                if ModulePath in import_aliases:
                    ModulePath = import_aliases[ModulePath]
                else:
                    # 也尝试在符号表中查找模块别名
                    entry = self.Trans.SymbolTable.lookup(ModulePath)
                    if isinstance(entry, CTypeInfo) and entry.IsModuleAlias:
                        resolved = entry.ResolvedModule
                        if resolved:
                            ModulePath = resolved

            self.Trans.DebugPrint(f"[GetCTypeInfo-Attribute] 查询: '{TypeName}' ModulePath: {ModulePath}")

            if ModulePath == 't' and TypeName == 'State':
                Info = CTypeInfo()
                Info.BaseType = t.CVoid
                Info.IsState = True
                return Info

            if ModulePath == 't' or (ModulePath and ModulePath.startswith('t.')):
                if self._IsTModuleType(TypeName):
                    TypeClass = CTypeHelper.GetTModuleCType(TypeName) or getattr(t, TypeName, None)
                    if TypeClass == t.CArrayPtr:
                        Info = CTypeInfo()
                        Info.IsArrayPtr = True
                        Info.BaseType = t.CVoid
                        return Info
                    elif TypeClass == t.CPtr:
                        Info = CTypeInfo()
                        Info.PtrCount = 1
                        Info.BaseType = t.CVoid
                        return Info
                    elif TypeClass == t.CConst:
                        Info = CTypeInfo()
                        Info.DataConst = True
                        Info.BaseType = t.CVoid
                        return Info
                    elif TypeClass == t.CVolatile:
                        Info = CTypeInfo()
                        Info.DataVolatile = True
                        Info.BaseType = t.CVoid
                        return Info
                    elif TypeClass == t.CInline:
                        Info = CTypeInfo()
                        Info.Storage = t.CInline()
                        Info.BaseType = t.CVoid
                        return Info
                    elif TypeClass == t.CStatic:
                        Info = CTypeInfo()
                        Info.Storage = t.CStatic()
                        Info.BaseType = t.CVoid
                        return Info
                    elif TypeClass == t.CExtern:
                        Info = CTypeInfo()
                        Info.Storage = t.CExtern()
                        Info.BaseType = t.CVoid
                        return Info
                    elif TypeClass == t.CExport:
                        Info = CTypeInfo()
                        Info.Storage = t.CExport()
                        Info.BaseType = t.CVoid
                        return Info
                    elif TypeClass in (t.BigEndian, t.LittleEndian):
                        Info = CTypeInfo()
                        Info.BaseType = t.CInt()
                        Info.ByteOrder = 'big' if TypeClass == t.BigEndian else 'little'
                        return Info
                    elif TypeClass:
                        Info = CTypeInfo()
                        Info.BaseType = TypeClass
                        return Info
                elif CTypeHelper.GetCName(TypeName):
                    return self._MakeCTypeInfoFromName(CTypeHelper.GetCName(TypeName))

            FullName = f"{ModulePath}.{TypeName}" if ModulePath else TypeName

            # 优先检查 Gen.structs：类名与枚举成员名冲突时（如 Import 既是 ASTKind.Import
            # 枚举成员又是 ast.Import 结构体类名），类型注解应解析为结构体而非枚举值
            # （与 ast.Name 路径 line 100-107 的逻辑一致）
            _Gen = getattr(self.Trans, 'LlvmGen', None)
            if _Gen and TypeName in _Gen.structs:
                Result = CTypeInfo()
                Result.BaseType = t.CStruct(name=TypeName)
                Result.IsStruct = True
                Result.Name = TypeName
                Result.PtrCount = 1
                return Result

            Entry = self.Trans.SymbolTable.lookup(TypeName)
            if Entry and Entry.IsTypedef:
                if isinstance(Entry, CTypeInfo) and Entry.BaseType:
                    if not isinstance(Entry.BaseType, (t._CTypedef,)) or Entry.PtrCount > 0:
                        Result = Entry.Copy()
                        Result.IsTypedef = True
                        Result.Name = TypeName
                        return Result
                if Entry.OriginalType:
                    if isinstance(Entry.OriginalType, CTypeInfo) and Entry.OriginalType.IsFuncPtr:
                        Result = CTypeInfo()
                        Result.IsFuncPtr = True
                        Result.FuncPtrReturn = Entry.OriginalType.FuncPtrReturn or CTypeInfo.VoidTypeInfo()
                        Result.FuncPtrParams = list(Entry.OriginalType.FuncPtrParams) if Entry.OriginalType.FuncPtrParams else []
                        Result.IsTypedef = True
                        Result.Name = TypeName
                        return Result
                    elif isinstance(Entry.OriginalType, CTypeInfo):
                        Resolved = Entry.OriginalType.Copy()
                        Resolved.IsTypedef = True
                        Resolved.Name = TypeName
                        return Resolved
                    elif isinstance(Entry.OriginalType, str):
                        # 字符串 OriginalType（如 'void *'）需解析为 CTypeInfo，
                        # 否则返回的 Result BaseType=_CTypedef 会被下游误判为 i32
                        Resolved = CTypeInfo.FromTypeName(Entry.OriginalType)
                        if Resolved and Resolved.BaseType:
                            Resolved.IsTypedef = True
                            Resolved.Name = TypeName
                            return Resolved
                Result = CTypeInfo()
                Result.BaseType = t._CTypedef(TypeName)
                Result.IsTypedef = True
                Result.Name = TypeName
                return Result
            if Entry:
                # If BaseType is None but this is a class/struct, set BaseType to CStruct
                Result = Entry.Copy()
                if Result.BaseType is None:
                    Result.BaseType = t.CStruct(name=TypeName)
                    Result.IsStruct = True
                # struct 变量默认为指针（与 ast.Name 路径一致，见 line 121）
                # 同时确保 Name 字段被设置，供 ToString() 使用
                if Result.IsStruct:
                    if Result.PtrCount == 0:
                        Result.PtrCount = 1
                    if not Result.Name:
                        Result.Name = TypeName
                return Result
            return CTypeInfo()

        elif isinstance(Node, ast.Call):
            if isinstance(Node.func, ast.Name) and Node.func.id == 'callable':
                ReturnTypeInfo = self._GetCTypeInfoInternal(Node.args[0]) if Node.args else None
                if isinstance(ReturnTypeInfo, CTypeInfo):
                    ReturnType = ReturnTypeInfo
                else:
                    ReturnType = CTypeInfo()
                    ReturnType.BaseType = t.CVoid()

                ParamTypes = []
                ParamNames = []
                for kw in Node.keywords:
                    ParamTypeInfo = self._GetCTypeInfoInternal(kw.value)
                    if not isinstance(ParamTypeInfo, CTypeInfo):
                        ParamTypeInfo = self._MakeCTypeInfoFromName('int')
                    ParamTypes.append(ParamTypeInfo)
                    ParamNames.append(kw.arg)

                for arg in Node.args[1:]:
                    if isinstance(arg, ast.Tuple):
                        for elt in arg.elts:
                            ParamTypeInfo = self._GetCTypeInfoInternal(elt)
                            if not isinstance(ParamTypeInfo, CTypeInfo):
                                ParamTypeInfo = self._MakeCTypeInfoFromName('int')
                            ParamTypes.append(ParamTypeInfo)
                            ParamNames.append('')
                    else:
                        ParamTypeInfo = self._GetCTypeInfoInternal(arg)
                        if not isinstance(ParamTypeInfo, CTypeInfo):
                            ParamTypeInfo = self._MakeCTypeInfoFromName('int')
                        ParamTypes.append(ParamTypeInfo)
                        ParamNames.append('')

                if not ParamTypes:
                    ParamTypes.append(self._MakeCTypeInfoFromName('void'))
                    ParamNames.append('')

                Info = CTypeInfo()
                Info.IsFuncPtr = True
                Info.FuncPtrReturn = ReturnType
                Info.FuncPtrParams = list(zip(ParamNames, ParamTypes))
                return Info

            if isinstance(Node.func, ast.Attribute) and isinstance(Node.func.value, ast.Name):
                ModuleName = Node.func.value.id
                TypeName = Node.func.attr

                if ModuleName == 't' and CTypeHelper.GetTModuleCType(TypeName) == t._CTypedef and Node.args:
                    TypeArg = Node.args[0]
                    if isinstance(TypeArg, ast.Name):
                        return TypeArg.id
                    elif isinstance(TypeArg, ast.Attribute):
                        AttrModule = TypeArg.value.id if isinstance(TypeArg.value, ast.Name) else None
                        AttrName = TypeArg.attr
                        if AttrModule == 't' and getattr(t, AttrName, None):
                            TypeObj = getattr(t, AttrName)
                            if isinstance(TypeObj, type) and issubclass(TypeObj, t.CType):
                                return TypeObj.__name__
                        return AttrName
                    elif isinstance(TypeArg, ast.Constant):
                        return str(TypeArg.value)

                if ModuleName in self.Trans._UserTypeModules:
                    module = self.Trans._UserTypeModules[ModuleName]
                    if getattr(module, TypeName, None):
                        TypeObj = getattr(module, TypeName)
                        if isinstance(TypeObj, type):
                            if issubclass(TypeObj, t.CType):
                                return TypeObj.__name__

                if ModuleName == 't':
                    TypeObj = CTypeHelper.GetTModuleCType(TypeName)
                    if TypeObj is None:
                        TypeObj = getattr(t, TypeName, None)
                    if isinstance(TypeObj, type) and issubclass(TypeObj, t.CType):
                        Result = CTypeInfo()
                        Result.BaseType = TypeObj
                        return Result

                if ModuleName == 't' and TypeName == 'State':
                    Result = CTypeInfo()
                    Result.IsState = True
                    return Result

                if ModuleName == 't' and TypeName == 'Bit':
                    if Node.args and isinstance(Node.args[0], ast.Constant):
                        BitWidth = Node.args[0].value
                        Result = CTypeInfo()
                        Result.IsBitField = True
                        Result.BitWidth = BitWidth
                        Result.BaseType = t.CInt
                        return Result

            Result = CTypeInfo()
            Result.BaseType = t.CVoid
            return Result

        elif isinstance(Node, ast.Subscript):
            if (isinstance(Node.value, ast.Attribute)
                and isinstance(Node.value.value, ast.Name)
                and IsTModule(Node.value.value.id, self.Trans.SymbolTable)
                and Node.value.attr == 'Bit'):
                if isinstance(Node.slice, ast.Constant) and isinstance(Node.slice.value, int):
                    Result = CTypeInfo()
                    Result.IsBitField = True
                    Result.BitWidth = Node.slice.value
                    Result.BaseType = t.CInt
                    return Result
            return self._HandleSubscript(Node)

        elif isinstance(Node, ast.BinOp):
            return self.MergeTypes(Node)

        elif isinstance(Node, ast.List):
            if Node.elts:
                BaseTypes = []
                for elt in Node.elts:
                    EltType = self._GetCTypeInfoInternal(elt)
                    if isinstance(EltType, CTypeInfo) and EltType.BaseType:
                        BaseTypes.append(EltType.BaseType)
                if BaseTypes:
                    Result = CTypeInfo()
                    Result.BaseType = tuple(BaseTypes)
                    return Result
            return self._MakeVoidCTypeInfo()

        return self._MakeVoidCTypeInfo()

    def _HandleSubscript(self, Node: ast.Subscript) -> CTypeInfo:
        """澶勭悊 Subscript 鑺傜偣锛屼娇鐢?CTypeInfo 鏍戝舰缁撴瀯鍒嗘瀽 AST

        例如?
        t.CVoid[5] -> void *[5]
        t.CPtr[t.CPtr[t.CPtr]][5][6] -> void ***[5][6]
        t.CArrayPtr[t.CArrayPtr] -> void *(*)[]
        t.CPtr[t.CArrayPtr[t.CArrayPtr]] -> void *(*(*))[]
        """
        def CollectAll(node: ast.AST, ParentIsArrayPtr: bool = False) -> CTypeInfo:
            """鏀堕泦绫诲瀷淇℃伅锛岃繑鍥?CTypeInfo"""
            if isinstance(node, ast.Subscript):
                value_node = node.value
                slice_node = node.slice

                if isinstance(value_node, ast.Attribute):
                    VtInfo = self.GetCTypeInfo(value_node)

                    if isinstance(value_node, ast.Attribute) and value_node.attr == 'Callable' and isinstance(value_node.value, ast.Name) and IsTModule(value_node.value.id, self.Trans.SymbolTable):
                        if isinstance(slice_node, ast.Tuple) and len(slice_node.elts) == 2:
                            params_list = slice_node.elts[0]
                            return_node = slice_node.elts[1]
                            ParamTypes = []
                            ParamNames = []
                            if isinstance(params_list, ast.List):
                                for elt in params_list.elts:
                                    ParamTypeInfo = self._GetCTypeInfoInternal(elt)
                                    if isinstance(ParamTypeInfo, CTypeInfo):
                                        ParamTypes.append(ParamTypeInfo)
                                        ParamNames.append('')
                                    else:
                                        ParamTypes.append(self._MakeCTypeInfoFromName('int'))
                                        ParamNames.append('')
                            if not ParamTypes:
                                ParamTypes.append(self._MakeCTypeInfoFromName('void'))
                                ParamNames.append('')
                            ReturnTypeInfo = self._GetCTypeInfoInternal(return_node)
                            if isinstance(ReturnTypeInfo, CTypeInfo):
                                ReturnType = ReturnTypeInfo
                            else:
                                ReturnType = CTypeInfo()
                                ReturnType.BaseType = t.CVoid()
                            Info = CTypeInfo()
                            Info.IsFuncPtr = True
                            Info.FuncPtrReturn = ReturnType
                            Info.FuncPtrParams = list(zip(ParamNames, ParamTypes))
                            return Info

                    if VtInfo and VtInfo.IsArrayPtr:
                        ResultInfo = CTypeInfo()
                        ResultInfo.PtrCount = VtInfo.PtrCount
                        ResultInfo.IsArrayPtr = True
                        if isinstance(slice_node, ast.Attribute):
                            SliceVtInfo = self.GetCTypeInfo(slice_node)
                            if SliceVtInfo and SliceVtInfo.IsArrayPtr:
                                ResultInfo.ArrayPtr = CTypeInfo()
                                ResultInfo.ArrayPtr.IsArrayPtr = True
                                ResultInfo.ArrayPtr.PtrCount = SliceVtInfo.PtrCount
                                if SliceVtInfo.ArrayPtr:
                                    ResultInfo.ArrayPtr.ArrayPtr = SliceVtInfo.ArrayPtr
                            elif SliceVtInfo and SliceVtInfo.PtrCount > 0:
                                ResultInfo.ArrayPtr = SliceVtInfo
                            else:
                                ResultInfo.ArrayPtr = CTypeInfo()
                                ResultInfo.ArrayPtr.IsArrayPtr = True
                        elif isinstance(slice_node, ast.Subscript):
                            ResultInfo.ArrayPtr = CollectAll(slice_node)
                        elif isinstance(slice_node, ast.Name):
                            ResultInfo.ArrayPtr = CTypeInfo()
                            ResultInfo.ArrayPtr.BaseType = CTypeInfo.CreateFromTypeName(slice_node.id).BaseType
                        elif isinstance(slice_node, ast.BinOp):
                            ResultInfo.ArrayPtr = CTypeInfo()
                            try:
                                ResultInfo.ArrayPtr.ArrayDims.append(ast.unparse(slice_node))
                            except Exception:  # 回退：unparse 失败时用 'N'
                                ResultInfo.ArrayPtr.ArrayDims.append('N')
                        elif isinstance(slice_node, ast.Constant):
                            ResultInfo.ArrayPtr = CTypeInfo()
                            ResultInfo.ArrayPtr.ArrayDims.append(str(slice_node.value))
                        else:
                            ResultInfo.ArrayPtr = CTypeInfo()
                            ResultInfo.ArrayPtr.IsArrayPtr = True
                    elif VtInfo and VtInfo.PtrCount == 1 and not VtInfo.ArrayPtr:
                        ResultInfo = CTypeInfo()
                        ResultInfo.BaseType = t.CVoid
                        ResultInfo.PtrCount = 1
                        if isinstance(slice_node, ast.Subscript):
                            inner_info = CollectAll(slice_node)
                            if inner_info and inner_info.PtrCount > 0:
                                ResultInfo.PtrCount += inner_info.PtrCount
                                if inner_info.BaseType and not isinstance(inner_info.BaseType, t.CVoid):
                                    ResultInfo.BaseType = inner_info.BaseType
                            elif inner_info and inner_info.ArrayPtr:
                                ResultInfo.ArrayPtr = inner_info
                            elif inner_info and inner_info.BaseType and not isinstance(inner_info.BaseType, t.CVoid):
                                ResultInfo.BaseType = inner_info.BaseType
                        elif isinstance(slice_node, ast.Attribute):
                            SliceVtInfo = self.GetCTypeInfo(slice_node)
                            if SliceVtInfo and SliceVtInfo.PtrCount == 1 and not SliceVtInfo.ArrayPtr:
                                ResultInfo.PtrCount = 2
                                if SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, t.CVoid):
                                    ResultInfo.BaseType = SliceVtInfo.BaseType
                            elif SliceVtInfo and SliceVtInfo.IsArrayPtr:
                                inner = CTypeInfo()
                                inner.ArrayPtr = CTypeInfo()
                                ResultInfo.ArrayPtr = inner
                            elif SliceVtInfo and SliceVtInfo.ArrayPtr:
                                ResultInfo.ArrayPtr = SliceVtInfo
                            elif SliceVtInfo and SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, t.CVoid):
                                ResultInfo.BaseType = SliceVtInfo.BaseType
                        elif isinstance(slice_node, ast.Name):
                            SliceType = getattr(t, slice_node.id, None)
                            if SliceType == t.CPtr:
                                ResultInfo.PtrCount += 1
                            elif SliceType == t.CArrayPtr:
                                inner = CTypeInfo()
                                inner.ArrayPtr = CTypeInfo()
                                ResultInfo.ArrayPtr = inner
                            else:
                                ResultInfo.BaseType = CTypeInfo.CreateFromTypeName(slice_node.id).BaseType
                        elif isinstance(slice_node, ast.BinOp):
                            merged = self.MergeTypes(slice_node)
                            if merged:
                                ResultInfo.PtrCount += merged.PtrCount
                                if merged.BaseType and not isinstance(merged.BaseType, t.CVoid):
                                    ResultInfo.BaseType = merged.BaseType
                                if merged.ArrayPtr:
                                    ResultInfo.ArrayPtr = merged.ArrayPtr
                        elif isinstance(slice_node, ast.Constant):
                            ResultInfo.ArrayDims.append(str(slice_node.value))
                    elif VtInfo:
                        ResultInfo = CTypeInfo()
                        ResultInfo.BaseType = VtInfo.BaseType
                        if isinstance(slice_node, ast.Constant):
                            ResultInfo.ArrayDims.append(str(slice_node.value))
                        elif isinstance(slice_node, ast.Name):
                            ResultInfo.ArrayDims.append(slice_node.id)
                        elif isinstance(slice_node, ast.BinOp):
                            try:
                                ResultInfo.ArrayDims.append(ast.unparse(slice_node))
                            except Exception:  # 回退：unparse 失败时用 'N'
                                ResultInfo.ArrayDims.append('N')
                        elif isinstance(slice_node, ast.Subscript):
                            ResultInfo.ArrayPtr = CollectAll(slice_node)
                    else:
                        ResultInfo = CTypeInfo()
                        if isinstance(slice_node, ast.Constant):
                            ResultInfo.ArrayDims.append(str(slice_node.value))
                        elif isinstance(slice_node, ast.Name):
                            SliceType = getattr(t, slice_node.id, None)
                            if SliceType == t.CPtr:
                                ResultInfo.PtrCount += 1
                            elif SliceType == t.CArrayPtr:
                                ResultInfo.ArrayPtr = CTypeInfo()
                            else:
                                ResultInfo.ArrayDims.append(slice_node.id)
                elif isinstance(value_node, ast.Subscript):
                    ResultInfo = CollectAll(value_node)
                    if isinstance(slice_node, ast.Attribute):
                        SliceVtInfo = self.GetCTypeInfo(slice_node)
                        if SliceVtInfo and SliceVtInfo.PtrCount >= 1 and not SliceVtInfo.ArrayPtr:
                            ResultInfo.PtrCount += SliceVtInfo.PtrCount
                            if SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, t.CVoid):
                                ResultInfo.BaseType = SliceVtInfo.BaseType
                        elif SliceVtInfo and SliceVtInfo.IsArrayPtr:
                            NewInfo = CTypeInfo()
                            NewInfo.ArrayPtr = ResultInfo
                            ResultInfo = NewInfo
                        elif SliceVtInfo and SliceVtInfo.BaseType and not isinstance(SliceVtInfo.BaseType, t.CVoid):
                            ResultInfo.BaseType = SliceVtInfo.BaseType
                    elif isinstance(slice_node, ast.Subscript):
                        InnerNode = CollectAll(slice_node)
                        if ResultInfo.ArrayPtr is None:
                            ResultInfo.ArrayPtr = InnerNode
                        else:
                            current = ResultInfo
                            while current.ArrayPtr is not None:
                                current = current.ArrayPtr
                            current.ArrayPtr = InnerNode
                    elif isinstance(slice_node, ast.Constant):
                        ResultInfo.ArrayDims.append(str(slice_node.value))
                    elif isinstance(slice_node, ast.Name):
                        SliceType = getattr(t, slice_node.id, None)
                        if SliceType == t.CPtr:
                            ResultInfo.PtrCount += 1
                        elif SliceType == t.CArrayPtr:
                            ResultInfo.ArrayPtr = CTypeInfo()
                        else:
                            ResultInfo.ArrayDims.append(slice_node.id)
                    elif isinstance(slice_node, ast.BinOp):
                        try:
                            ResultInfo.ArrayDims.append(ast.unparse(slice_node))
                        except Exception:  # 回退：unparse 失败时用 'N'
                            ResultInfo.ArrayDims.append('N')
                elif isinstance(value_node, ast.Name):
                    ResultInfo = CTypeInfo()
                    if IsListAnnotation(node):
                        if not isinstance(slice_node, ast.Tuple):
                            ElementType = self._GetCTypeInfoInternal(slice_node)
                            if ElementType and isinstance(ElementType, CTypeInfo):
                                ResultInfo.BaseType = ElementType.BaseType if ElementType.BaseType else t.CVoid()
                                ResultInfo.PtrCount = ElementType.PtrCount + 1
                                ResultInfo.IsFuncPtr = ElementType.IsFuncPtr
                                ResultInfo.FuncPtrReturn = ElementType.FuncPtrReturn
                                ResultInfo.FuncPtrParams = ElementType.FuncPtrParams
                            else:
                                ResultInfo.BaseType = t.CVoid()
                                ResultInfo.PtrCount = 1
                        elif isinstance(slice_node, ast.Tuple) and len(slice_node.elts) >= 1:
                            ElementType = self._GetCTypeInfoInternal(slice_node.elts[0])
                            if ElementType and isinstance(ElementType, CTypeInfo):
                                ResultInfo.BaseType = ElementType.BaseType if ElementType.BaseType else t.CVoid()
                                ResultInfo.PtrCount = ElementType.PtrCount
                                ResultInfo.IsFuncPtr = ElementType.IsFuncPtr
                                ResultInfo.FuncPtrReturn = ElementType.FuncPtrReturn
                                ResultInfo.FuncPtrParams = ElementType.FuncPtrParams
                            for elt in slice_node.elts[1:]:
                                if isinstance(elt, ast.Constant):
                                    ResultInfo.ArrayDims.append(str(elt.value))
                                elif isinstance(elt, ast.Name):
                                    ResultInfo.ArrayDims.append(elt.id)
                                else:
                                    try:
                                        ResultInfo.ArrayDims.append(ast.unparse(elt))
                                    except Exception:  # 回退：unparse 失败时用 'N'
                                        ResultInfo.ArrayDims.append('N')
                        else:
                            ResultInfo.BaseType = CTypeInfo.CreateFromTypeName(value_node.id).BaseType
                    else:
                        # 检查是否为泛型类特化（如 list[str]）
                        _is_generic_template: bool = (
                            hasattr(self.Trans, 'ClassHandler')
                            and hasattr(self.Trans.ClassHandler, '_generic_class_templates')
                            and value_node.id in self.Trans.ClassHandler._generic_class_templates
                        )
                        if _is_generic_template:
                            # 走和 _ResolveGenericSlice 同样的规范化路径（_resolve_generic_slice_type），
                            # 确保字段类型名与特化名完全一致：
                            # - ast.Name: 用原始名（如 'Param' → 'Param'，不加 SHA1 前缀），
                            #   与 _resolve_generic_slice_type 的 ast.Name 分支一致
                            # - BinOp/Attribute: 走 _resolve_type_arg_str（加 SHA1 前缀 / 'ptr' 标记）
                            # 避免字段类型用 'GSList[sha1.Param]' 而特化名用 'GSList[Param]' 导致
                            # find_struct_by_pointee 匹配到 opaque 副本，方法分派失败
                            type_arg_str: str
                            if isinstance(slice_node, ast.Tuple):
                                arg_parts: list[str] = []
                                for elt in slice_node.elts:
                                    slice_res = self.Trans.ExprCallHandle._resolve_generic_slice_type(elt)
                                    arg_parts.append(slice_res[0] if slice_res else self.Trans.ExprCallHandle._resolve_type_arg_str(elt))
                                # 必须用 '][' 分隔以匹配 _mangle_generic_class_name 的格式
                                # （class_name + '[' + ']['.join(mangled_args) + ']'）
                                type_arg_str = ']['.join(arg_parts)
                            else:
                                slice_res = self.Trans.ExprCallHandle._resolve_generic_slice_type(slice_node)
                                type_arg_str = slice_res[0] if slice_res else self.Trans.ExprCallHandle._resolve_type_arg_str(slice_node)
                            full_spec_name: str = f'{value_node.id}[{type_arg_str}]'
                            ResultInfo.BaseType = t.CStruct(name=full_spec_name)
                            ResultInfo.Name = full_spec_name
                            ResultInfo.IsStruct = True
                            ResultInfo.PtrCount = 1
                            # 触发泛型特化发射：确保特化的方法被发射 + struct sha1 注册
                            # 与局部变量 AnnAssign 路径一致；否则函数参数注解路径
                            # 只构建 mangled 名，方法调用分派时 class_sha1=None 导致
                            # "Undefined method" 错误（如 lst.__len__() 在 list[T] | t.CPtr 参数上）
                            # _specialize_generic_class 内部有 spec_key 去重，重复调用安全
                            if hasattr(self.Trans, 'ExprCallHandle') and self.Trans.ExprCallHandle is not None:
                                self.Trans.ExprCallHandle._ResolveGenericSlice(node)
                        else:
                            ResultInfo.BaseType = CTypeInfo.CreateFromTypeName(value_node.id).BaseType
                            if isinstance(slice_node, ast.Constant):
                                ResultInfo.ArrayDims.append(str(slice_node.value))
                            elif isinstance(slice_node, ast.Name):
                                SliceType = getattr(t, slice_node.id, None)
                                if SliceType == t.CPtr:
                                    ResultInfo.PtrCount += 1
                                elif SliceType == t.CArrayPtr:
                                    ResultInfo.ArrayPtr = CTypeInfo()
                                else:
                                    ResultInfo.ArrayDims.append(slice_node.id)
                            elif isinstance(slice_node, ast.BinOp):
                                try:
                                    ResultInfo.ArrayDims.append(ast.unparse(slice_node))
                                except Exception:  # 回退：unparse 失败时用 'N'
                                    ResultInfo.ArrayDims.append('N')
                            elif isinstance(slice_node, ast.Subscript):
                                InnerNode = CollectAll(slice_node)
                                ResultInfo.ArrayDims.extend(InnerNode.ArrayDims)
                else:
                    ResultInfo = CTypeInfo()

                return ResultInfo
            elif isinstance(node, ast.Attribute):
                VtInfo = self.GetCTypeInfo(node)
                result = CTypeInfo()
                if VtInfo and VtInfo.IsArrayPtr:
                    result.ArrayPtr = CTypeInfo()
                    return result
                elif VtInfo and VtInfo.PtrCount == 1 and not VtInfo.ArrayPtr:
                    result.BaseType = t.CVoid
                    result.PtrCount = 1
                    return result
                elif VtInfo and VtInfo.BaseType:
                    result.BaseType = VtInfo.BaseType
                    return result
                else:
                    return CTypeInfo()
            elif isinstance(node, ast.Name):
                result = CTypeInfo()
                result.BaseType = CTypeInfo.CreateFromTypeName(node.id).BaseType
                return result
            else:
                return CTypeInfo()

        return CollectAll(Node)

    def _CollectAllOperandTypes(self, Node: ast.AST) -> List:
        """递归收集所有操作数的类型（用于一次性合并）"""
        Types = []

        if isinstance(Node, ast.BinOp) and isinstance(Node.op, ast.BitOr):
            Types.extend(self._CollectAllOperandTypes(Node.left))
            Types.extend(self._CollectAllOperandTypes(Node.right))
        else:
            Types.append(Node)

        return Types

    def _GetTypeFromNode(self, Node: ast.AST) -> CTypeInfo:
        """浠?AST 鑺傜偣鑾峰彇绫诲瀷"""
        if isinstance(Node, ast.Call):
            if isinstance(Node.func, ast.Name) and Node.func.id == 'callable':
                return self.GetCTypeInfo(Node)
            elif isinstance(Node.func, ast.Attribute) and CTypeHelper.GetTModuleCType(Node.func.attr) == t._CTypedef:
                return self.GetCTypeInfo(Node)
            elif isinstance(Node.func, ast.Attribute) and Node.func.attr == 'Bit':
                if Node.args and isinstance(Node.args[0], ast.Constant):
                    Result = CTypeInfo()
                    Result.BaseType = t.CInt
                    Result.IsBitField = True
                    Result.BitWidth = Node.args[0].value
                    return Result
            return self._MakeVoidCTypeInfo()
        elif isinstance(Node, ast.Subscript):
            if (isinstance(Node.value, ast.Attribute)
                and isinstance(Node.value.value, ast.Name)
                and IsTModule(Node.value.value.id, self.Trans.SymbolTable)
                and Node.value.attr == 'Bit'):
                if isinstance(Node.slice, ast.Constant) and isinstance(Node.slice.value, int):
                    Result = CTypeInfo()
                    Result.BaseType = t.CInt
                    Result.IsBitField = True
                    Result.BitWidth = Node.slice.value
                    return Result
            return self.GetCTypeInfo(Node)
        else:
            return self.GetCTypeInfo(Node)

    def MergeTypes(self, Node: ast.BinOp):
        """处理类型组合，如 t.CInt | t.CPtr ?t.CStatic | t.CInt

        这是 | 运算符的类型合并处理函数
        收集所有操作数，一次性合?
        """
        if not isinstance(Node, ast.BinOp) or not isinstance(Node.op, ast.BitOr):
            return None

        AllOperands = self._CollectAllOperandTypes(Node)

        AllTypes = []
        for Operand in AllOperands:
            TypeItem = self._GetTypeFromNode(Operand)
            AllTypes.append(TypeItem)

        if isinstance(Node.left, ast.Attribute):
            LeftParts = []
            current = Node.left
            while isinstance(current, ast.Attribute):
                attr_type = getattr(t, current.attr, None)
                if attr_type and isinstance(attr_type, type) and issubclass(attr_type, t.CType):
                    LeftParts.insert(0, attr_type)
                current = current.value
            if isinstance(current, ast.Name):
                name_type = getattr(t, current.id, None)
                if name_type and isinstance(name_type, type) and issubclass(name_type, t.CType):
                    LeftParts.insert(0, name_type)
            if LeftParts and LeftParts[-1] == t._CTypedef:
                for type_item in AllTypes:
                    if isinstance(type_item, CTypeInfo) and type_item.IsFuncPtr:
                        type_item.IsTypedef = True
                        type_item.OriginalType = CTypeInfo()
                        type_item.OriginalType.IsFuncPtr = True
                        type_item.OriginalType.FuncPtrReturn = type_item.FuncPtrReturn or CTypeInfo.VoidTypeInfo()
                        type_item.OriginalType.FuncPtrParams = list(type_item.FuncPtrParams) if type_item.FuncPtrParams else []
                        return type_item
                Result = CTypeInfo()
                if isinstance(AllTypes[-1], CTypeInfo):
                    Result.BaseType = AllTypes[-1].BaseType
                else:
                    Result.BaseType = t.CInt
                Result.IsTypedef = True
                return Result

        return self._MergeAllComponentTypes(*AllTypes)

    def _MergeAllComponentTypes(self, *Types: CTypeInfo) -> CTypeInfo:
        """合并多个类型 - 直接使用 CTypeInfo 类"""
        if not Types:
            return CTypeInfo()

        Result = CTypeInfo()
        # 统计 t.CPtr（CVoid + PtrCount=1）的个数，用于正确累加指针层数
        # 因为 (AST | t.CPtr) | t.CPtr 展开后会包含多个 t.CPtr，每个都需要累加
        cptr_count: int = 0

        for TypeItem in Types:
            if TypeItem is None:
                continue
            if TypeItem.IsState:
                Result.IsState = True
                if not Result.Storage:
                    Result.Storage = t.CExport()
                continue
            if TypeItem.IsBitField:
                Result.BaseType = t.CInt
                Result.IsBitField = True
                Result.BitWidth = TypeItem.BitWidth
                return Result
            if TypeItem.IsFuncPtr:
                Result.BaseType = t.CVoid
                Result.IsFuncPtr = True
                Result.FuncPtrParams = TypeItem.FuncPtrParams
                Result.FuncPtrReturn = TypeItem.FuncPtrReturn
                return Result
            if TypeItem.IsTypedef:
                if TypeItem.BaseType and (not isinstance(TypeItem.BaseType, (t._CTypedef,)) or TypeItem.PtrCount > 0):
                    if Result.BaseType is None or isinstance(Result.BaseType, (t.CVoid, t._CTypedef)):
                        Result.BaseType = TypeItem.BaseType
                    Result.Name = TypeItem.Name
                    Result.IsTypedef = True
                    Result.PtrCount = max(Result.PtrCount, TypeItem.PtrCount)
                    if TypeItem.OriginalType:
                        Result.OriginalType = TypeItem.OriginalType
                else:
                    Result.IsTypedef = True
                    Result.Name = TypeItem.Name
                    if TypeItem.OriginalType:
                        Result.OriginalType = TypeItem.OriginalType
                continue
            # 统计 t.CPtr（CVoid + PtrCount>0）
            # 注意: t.CPtr[t.CPtr] 的 PtrCount=2（双重指针），需要完整累加
            if TypeItem.PtrCount > 0 and TypeItem.BaseType and (TypeItem.BaseType is t.CVoid or isinstance(TypeItem.BaseType, t.CVoid)):
                cptr_count += TypeItem.PtrCount
                # BaseType 保持不变，只计数，后续统一累加
                if TypeItem.IsRenum and TypeItem.Name:
                    Result.IsRenum = True
                    Result.IsEnum = True
                    Result.IsStruct = True
                    if not Result.Name:
                        Result.Name = TypeItem.Name
                continue
            self._MergeCTypeInfoInto(Result, TypeItem)

        # 对所有 t.CPtr 统一累加指针层数
        # 仅对 struct 类型吸收第一个 CPtr（struct 变量默认是指针，AST | t.CPtr = AST*）。
        # 对于本身已是指针的类型（如 bytes=CChar*），bytes | t.CPtr = i8**（不吸收）。
        base_ptr_count: int = Result.PtrCount
        Result.PtrCount += cptr_count
        if Result.IsStruct and base_ptr_count > 0 and cptr_count > 0:
            Result.PtrCount -= 1

        if Result.BaseType is None:
            Result.BaseType = t.CVoid

        return Result

    def _MergeCTypeInfoInto(self, Target: CTypeInfo, Source: CTypeInfo):
        if Source.PtrCount > 0 and Source.BaseType and (Source.BaseType is t.CVoid or isinstance(Source.BaseType, t.CVoid)):
            # t.CPtr 的处理已提升到 _MergeAllComponentTypes 中统一计数累加，
            # 此处保留仅作为兜底（从其他路径直接调用 _MergeCTypeInfoInto 时）
            if Target.PtrCount < Source.PtrCount:
                Target.PtrCount = Source.PtrCount
        elif Source.PtrCount > 0 and Source.BaseType and Source.BaseType is not t.CVoid and not isinstance(Source.BaseType, t.CVoid):
            if Target.BaseType is None or Target.BaseType is t.CVoid or isinstance(Target.BaseType, t.CVoid):
                Target.BaseType = Source.BaseType
                # 当 Target 已有 PtrCount（来自之前的 t.CPtr），累加而非替换
                Target.PtrCount = Source.PtrCount + Target.PtrCount
            elif Target.PtrCount == 0:
                Target.PtrCount = Source.PtrCount
            elif Source.PtrCount > Target.PtrCount:
                Target.PtrCount = Source.PtrCount
        elif Source.PtrCount > Target.PtrCount:
            Target.PtrCount = Source.PtrCount
        if Source.BaseType and Source.BaseType is not t.CVoid and not isinstance(Source.BaseType, (t.CVoid, t._CTypedef)):
            if Target.BaseType is None:
                Target.BaseType = Source.BaseType
            elif (Target.BaseType is t.CVoid or isinstance(Target.BaseType, t.CVoid)) and Target.PtrCount == 0:
                Target.BaseType = Source.BaseType
        elif (Source.BaseType is t.CVoid or isinstance(Source.BaseType, t.CVoid)) and Target.BaseType is None:
            Target.BaseType = Source.BaseType
        # Struct 名称保留：BinOp `list[AST | t.CPtr] | t.CPtr` 合并时，
        # _HandleSubscript 已在 Source.Name 设置了特化名（如 'list[5dab8cb390496d22.ASTptr]'），
        # 合并后 Target.Name 必须保留此名称，否则 class_member_element_class
        # 无法获取正确的特化类名 → 方法分派 fallback 到错误的类
        if Source.IsStruct and Source.Name and not Target.Name:
            Target.Name = Source.Name
        # REnum 标志和名称保留（BinOp `LLVMType | t.CPtr` 合并时不能丢失 REnum 语义）
        # 同时传播 IsStruct=True，让 CPtr 吸收逻辑生效（REnum 在内存布局上是 struct）
        if Source.IsRenum and Source.Name:
            Target.IsRenum = True
            Target.IsEnum = True
            Target.IsStruct = True
            if not Target.Name:
                Target.Name = Source.Name
        if Source.IsTypedef and Source.Name:
            if Source.BaseType and (not isinstance(Source.BaseType, (t._CTypedef,)) or Source.PtrCount > 0):
                if Target.BaseType is None or isinstance(Target.BaseType, (t.CVoid, t._CTypedef)):
                    Target.BaseType = Source.BaseType
                Target.IsTypedef = True
                Target.Name = Source.Name
                if Source.OriginalType:
                    Target.OriginalType = Source.OriginalType
            elif Target.BaseType is None or isinstance(Target.BaseType, (t.CVoid, t._CTypedef)):
                if Source.OriginalType:
                    if isinstance(Source.OriginalType, CTypeInfo) and Source.OriginalType.BaseType:
                        Target.BaseType = Source.OriginalType.BaseType
                        Target.PtrCount = max(Target.PtrCount, Source.OriginalType.PtrCount)
                        Target.IsTypedef = True
                        Target.Name = Source.Name
                        Target.OriginalType = Source.OriginalType
                    elif isinstance(Source.OriginalType, CTypeInfo):
                        Target.IsTypedef = True
                        Target.Name = Source.Name
                        Target.OriginalType = Source.OriginalType
                    else:
                        Target.BaseType = t.CStruct(name=Source.Name)
                        Target.IsStruct = True
                else:
                    Target.BaseType = t.CStruct(name=Source.Name)
                    Target.IsStruct = True
        if Source.ArrayPtr:
            if Target.ArrayPtr is None:
                Target.ArrayPtr = Source.ArrayPtr
            else:
                if Source.PtrCount > Target.PtrCount:
                    Target.PtrCount = Source.PtrCount
                Target.ArrayPtr = Source.ArrayPtr
        if Source.PtrCount > 0:
            Target.ArrayDims = []
        elif Source.ArrayDims:
            Target.ArrayDims.extend(Source.ArrayDims)
        if Source.VarConst:
            Target.VarConst = True
        if Source.VarVolatile:
            Target.VarVolatile = True
        if Source.DataConst:
            Target.DataConst = True
        if Source.DataVolatile:
            Target.DataVolatile = True
        if Source.IsFuncPtr:
            Target.IsFuncPtr = True
            Target.FuncPtrParams = Source.FuncPtrParams
            Target.FuncPtrReturn = Source.FuncPtrReturn
        if Source.Storage and not Target.Storage:
            Target.Storage = Source.Storage
        if Source.ByteOrder and not Target.ByteOrder:
            Target.ByteOrder = Source.ByteOrder
