diff --git a/App/lib/core/Handles/HandlesType.vp b/App/lib/core/Handles/HandlesType.vp index 427d86e..e79e2c5 100644 --- a/App/lib/core/Handles/HandlesType.vp +++ b/App/lib/core/Handles/HandlesType.vp @@ -1526,6 +1526,100 @@ def extract_class_name_from_annotation(node: ast.AST | t.CPtr, return None +# ============================================================ +# _resolve_generic_subscript_ty - 解析泛型类类型注解 +# (list[int] / numpy.ndarray[t.CDouble]) +# +# 收集 slice 类型实参,构造 mangled name("list[int]"),查找已特化结构体; +# 未特化时检查是否泛型模板并主动触发特化。Name 泛型类与模块限定泛型类 +# (Attribute value,如 numpy.ndarray[t.CDouble])共用此逻辑。 +# ============================================================ +def _resolve_generic_subscript_ty(pool: memhub.MemBuddy | t.CPtr, + sub: ast.Subscript | t.CPtr, + gen_cls_name: str, + trans: HT.Translator | t.CPtr, + imported_modules: str, + from_imports: str) -> llvmlite.LLVMType | t.CPtr: + """解析泛型类类型注解(特化或查找已注册结构体),失败返回 None""" + if pool is None or sub is None or gen_cls_name is None: + return None + # tuple[...] 类型注解:TransPyV 暂不支持 tuple 返回类型,返回 None 让上层默认处理 + # 避免走到 list[str](pool, 4) 构造路径崩溃(tuple 未定义为泛型类) + if string.strcmp(gen_cls_name, "tuple") == 0: + return None + # 先收集类型实参名,再分配缓冲区拼接 mangled name(elem_size=8:str 是指针) + gen_arg_names: list[str] | t.CPtr = list[str](pool, 8) + if sub.slice.kind() == ast.ASTKind.Tuple: + gen_tp: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(sub.slice) + gen_elts: list[ast.AST | t.CPtr] | t.CPtr = gen_tp.elts + if gen_elts is not None: + gen_en: t.CSizeT = gen_elts.__len__() + gen_ei: t.CSizeT + for gen_ei in range(gen_en): + gen_elt: ast.AST | t.CPtr = gen_elts.get(gen_ei) + gen_tn: str = _get_type_name_from_annotation(pool, gen_elt) + gen_arg_names.append(gen_tn) + else: + gen_tn_single: str = _get_type_name_from_annotation(pool, sub.slice) + gen_arg_names.append(gen_tn_single) + # 计算总长度并分配缓冲区 + gen_total: t.CSizeT = string.strlen(gen_cls_name) + 2 # "[" 和 "]" + gen_an: t.CSizeT = gen_arg_names.__len__() + gen_ai: t.CSizeT + for gen_ai in range(gen_an): + if gen_ai > 0: + gen_total += 1 # "," + gen_atn: str = gen_arg_names.get(gen_ai) + if gen_atn is not None: + gen_total += string.strlen(gen_atn) + gen_total += 1 # NUL + gen_mangled: str = pool.alloc(gen_total) + if gen_mangled is None: + return None + gen_mangled[0] = '\0' + string.strcat(gen_mangled, gen_cls_name) + string.strcat(gen_mangled, "[") + for gen_ai in range(gen_an): + if gen_ai > 0: + string.strcat(gen_mangled, ",") + gen_atn: str = gen_arg_names.get(gen_ai) + if gen_atn is not None: + string.strcat(gen_mangled, gen_atn) + string.strcat(gen_mangled, "]") + # 查找已特化的 struct(特化由实例化调用 list[int](pool) 触发) + gen_spec_ty: llvmlite.LLVMType | t.CPtr = HandlesStruct.get_struct_type(gen_mangled) + if gen_spec_ty is not None: + # 治本修复:Phase B 补译泛型特化类方法体 + # Phase 1a(declare_only==1)特化时只注册结构体不译方法体(MethodsEmitted==0), + # Phase B(declare_only==0)解析字段类型命中已注册结构体时本会早返回, + # 导致方法体永远不生成 → GSList[Line].append 等符号只有 declare 无 define → 链接失败。 + # 此处 Phase B 且方法体未译时,调用 _specialize_generic_class 走其已注册分支补译方法体。 + if trans is not None and trans._declare_only == 0: + import lib.core.Handles.HandlesClassDef as HandlesClassDef + gen_spec_entry: HandlesStruct.StructEntry | t.CPtr = HandlesStruct.find_struct(gen_mangled) + if gen_spec_entry is not None and gen_spec_entry.MethodsEmitted == 0: + HandlesClassDef._specialize_generic_class(trans, gen_cls_name, gen_arg_names) + return gen_spec_ty + # 未特化:尝试主动触发泛型特化(与 TPC _HandleSubscript 对齐) + # 当 trans 可用时,检查是否是泛型模板并触发特化 + if trans is not None: + import lib.core.Handles.HandlesClassDef as HandlesClassDef + import lib.core.Handles.HandlesExprCall as HandlesExprCall + template_cd_chk: ast.ClassDef | t.CPtr = HandlesClassDef._find_generic_template(gen_cls_name) + if template_cd_chk is not None: + type_args_chk: list[str] | t.CPtr = HandlesExprCall._extract_type_args_from_slice( + pool, sub.slice) + if type_args_chk is not None and type_args_chk.__len__() > 0: + spec_name_chk: str = HandlesClassDef._specialize_generic_class( + trans, gen_cls_name, type_args_chk) + if spec_name_chk is not None: + gen_spec_ty = HandlesStruct.get_struct_type(gen_mangled) + if gen_spec_ty is not None: + return gen_spec_ty + # 未特化:返回 None(不报错,让后续流程处理) + return None + + # ============================================================ # 解析类型注解节点为 LLVMType # @@ -1771,92 +1865,25 @@ def resolve_annotation_type(pool: memhub.MemBuddy | t.CPtr, sub: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(node) if sub.value is None or sub.slice is None: fatal_type_error(node, "Subscript 节点缺少 value 或 slice") - # 泛型类类型注解: list[int] → 查找已特化的 struct - # value 是 Name(泛型类名),slice 是类型实参 + # 泛型类类型注解: list[int] → 查找已特化的 struct(value 是 Name 泛型类名) if sub.value.kind() == ast.ASTKind.Name: gen_nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(sub.value) - # tuple[...] 类型注解:TransPyV 暂不支持 tuple 返回类型,返回 None 让上层默认处理 - # 避免走到 list[str](pool, 4) 构造路径崩溃(tuple 未定义为泛型类) if gen_nm.id is not None: - if string.strcmp(gen_nm.id, "tuple") == 0: - return None - # 先收集类型实参名,再分配缓冲区拼接 mangled name(elem_size=8:str 是指针) - gen_arg_names: list[str] | t.CPtr = list[str](pool, 8) - if sub.slice.kind() == ast.ASTKind.Tuple: - gen_tp: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(sub.slice) - gen_elts: list[ast.AST | t.CPtr] | t.CPtr = gen_tp.elts - if gen_elts is not None: - gen_en: t.CSizeT = gen_elts.__len__() - gen_ei: t.CSizeT - for gen_ei in range(gen_en): - gen_elt: ast.AST | t.CPtr = gen_elts.get(gen_ei) - gen_tn: str = _get_type_name_from_annotation(pool, gen_elt) - gen_arg_names.append(gen_tn) - else: - gen_tn_single: str = _get_type_name_from_annotation(pool, sub.slice) - gen_arg_names.append(gen_tn_single) - # 计算总长度并分配缓冲区 - gen_total: t.CSizeT = string.strlen(gen_nm.id) + 2 # "[" 和 "]" - gen_an: t.CSizeT = gen_arg_names.__len__() - gen_ai: t.CSizeT - for gen_ai in range(gen_an): - if gen_ai > 0: - gen_total += 1 # "," - gen_atn: str = gen_arg_names.get(gen_ai) - if gen_atn is not None: - gen_total += string.strlen(gen_atn) - gen_total += 1 # NUL - gen_mangled: str = pool.alloc(gen_total) - if gen_mangled is None: - return None - gen_mangled[0] = '\0' - string.strcat(gen_mangled, gen_nm.id) - string.strcat(gen_mangled, "[") - for gen_ai in range(gen_an): - if gen_ai > 0: - string.strcat(gen_mangled, ",") - gen_atn: str = gen_arg_names.get(gen_ai) - if gen_atn is not None: - string.strcat(gen_mangled, gen_atn) - string.strcat(gen_mangled, "]") - # 查找已特化的 struct(特化由实例化调用 list[int](pool) 触发) - gen_spec_ty: llvmlite.LLVMType | t.CPtr = HandlesStruct.get_struct_type(gen_mangled) - if gen_spec_ty is not None: - # 治本修复:Phase B 补译泛型特化类方法体 - # Phase 1a(declare_only==1)特化时只注册结构体不译方法体(MethodsEmitted==0), - # Phase B(declare_only==0)解析字段类型命中已注册结构体时本会早返回, - # 导致方法体永远不生成 → GSList[Line].append 等符号只有 declare 无 define → 链接失败。 - # 此处 Phase B 且方法体未译时,调用 _specialize_generic_class 走其已注册分支补译方法体。 - if trans is not None and trans._declare_only == 0: - import lib.core.Handles.HandlesClassDef as HandlesClassDef - gen_spec_entry: HandlesStruct.StructEntry | t.CPtr = HandlesStruct.find_struct(gen_mangled) - if gen_spec_entry is not None and gen_spec_entry.MethodsEmitted == 0: - HandlesClassDef._specialize_generic_class(trans, gen_nm.id, gen_arg_names) - return gen_spec_ty - # 未特化:尝试主动触发泛型特化(与 TPC _HandleSubscript 对齐) - # 当 trans 可用时,检查是否是泛型模板并触发特化 - if trans is not None: - import lib.core.Handles.HandlesClassDef as HandlesClassDef - import lib.core.Handles.HandlesExprCall as HandlesExprCall - template_cd_chk: ast.ClassDef | t.CPtr = HandlesClassDef._find_generic_template(gen_nm.id) - if template_cd_chk is not None: - type_args_chk: list[str] | t.CPtr = HandlesExprCall._extract_type_args_from_slice( - pool, sub.slice) - if type_args_chk is not None and type_args_chk.__len__() > 0: - spec_name_chk: str = HandlesClassDef._specialize_generic_class( - trans, gen_nm.id, type_args_chk) - if spec_name_chk is not None: - gen_spec_ty = HandlesStruct.get_struct_type(gen_mangled) - if gen_spec_ty is not None: - return gen_spec_ty - # 未特化:返回 None(不报错,让后续流程处理) - return None - # 检查 value 是否是 Attribute(Name('t'), 'CArray'/'Callable') + return _resolve_generic_subscript_ty(pool, sub, gen_nm.id, trans, + imported_modules, from_imports) + # 检查 value 是否是 Attribute(t.CArray / t.Callable / 模块限定泛型类如 numpy.ndarray[T]) if sub.value.kind() != ast.ASTKind.Attribute: fatal_type_error(node, "不支持的 Subscript 类型注解(仅支持 t.CArray / t.Callable)") arr_at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(sub.value) if arr_at.attr is None: fatal_type_error(node, "Subscript Attribute 缺少 attr") + # 模块限定泛型类: numpy.ndarray[t.CDouble] → 裸类名 ndarray 走泛型特化 + # (在 t.CArray / t.Callable 检查之前;模板已注册即视为泛型类) + if trans is not None: + import lib.core.Handles.HandlesClassDef as HandlesClassDef + if HandlesClassDef._find_generic_template(arr_at.attr) is not None: + return _resolve_generic_subscript_ty(pool, sub, arr_at.attr, trans, + imported_modules, from_imports) if arr_at.value is None or arr_at.value.kind() != ast.ASTKind.Name: fatal_type_error(node, "t.CArray / t.Callable 必须通过模块名限定") arr_val_name: ast.Name | t.CPtr = (ast.Name | t.CPtr)(arr_at.value)