diff --git a/App/lib/core/Gen/Class/ClassGenBase.vp b/App/lib/core/Gen/Class/ClassGenBase.vp index ef1db27..8ad60ee 100644 --- a/App/lib/core/Gen/Class/ClassGenBase.vp +++ b/App/lib/core/Gen/Class/ClassGenBase.vp @@ -888,11 +888,18 @@ novirtual class ClassGenBase: return 1 return 0 def _get_base_name(self, base_node: ast.AST*, - pool: memhub.MemBuddy* = None) -> str: + pool: memhub.MemBuddy* = None, + from_imports: str = None) -> str: """从 base AST 节点提取基类名,返回 None=失败 对于 Subscript 节点,需要 pool 分配内存拼接特化名; pool=None 时降级返回基类名(不含类型实参) + + 类型实参必须与**唯一生成器**(ClassGenGeneric._mangle_generic_class_name) + 同口径:本函数产出的父类特化名要拿去 find_struct_by_module 查、并写入 + `entry.ParentName`,而注册名由生成器(内部经 _norm_type_arg_name 归一) + 产出 ⇒ 这里同样归一,否则父类 `GSListNode[Value]` 与注册的 + `GSListNode[{sha1}.Value]` 不同名 ⇒ 父类查找落空/继承链断裂。 """ if base_node is None: return None @@ -911,10 +918,10 @@ novirtual class ClassGenBase: if sub is None or sub.value is None or sub.slice is None: return None # 提取基类名(如 "GSListNode") - base_nm: str = self._get_base_name(sub.value, pool) + base_nm: str = self._get_base_name(sub.value, pool, from_imports) if base_nm is None: return None - # 提取类型实参名(如 "Value") + # 提取类型实参名(如 "Value"),并与唯一生成器同口径归一 slice_k: int = sub.slice.kind() arg_nm: str = None if slice_k == ast.ASTKind.Name: @@ -926,6 +933,9 @@ novirtual class ClassGenBase: # 无 pool 时返回基类名(降级,无法拼接特化名) if pool is None: return base_nm + arg_norm: str = self.Gen.TypeGenResolve._norm_type_arg_name(pool, arg_nm, from_imports) + if arg_norm is not None: + arg_nm = arg_norm # 拼接特化名 "GSListNode[Value]" base_len: sizet = string.strlen(base_nm) arg_len: sizet = string.strlen(arg_nm) @@ -956,7 +966,10 @@ novirtual class ClassGenBase: base_node: ast.AST* = bases.get(bi) if base_node is None: continue - bname: str = self._get_base_name(base_node, pool) + _fi_pc: str = None + if trans is not None: + _fi_pc = trans._from_imports + bname: str = self._get_base_name(base_node, pool, _fi_pc) if bname is not None: # 基类别名解析(from t import CStruct as cs → cs 实际是 CStruct)。 # 不解析会把别名当真实父类 → find_struct("cs") 失败 → 类 defer 永不注册。 @@ -1008,7 +1021,10 @@ novirtual class ClassGenBase: base_node: ast.AST* = bases.get(bi) if base_node is None: continue - bname: str = self._get_base_name(base_node, pool) + _fi_cp: str = None + if trans is not None: + _fi_cp = trans._from_imports + bname: str = self._get_base_name(base_node, pool, _fi_cp) if bname is not None: # 基类别名解析(同 _get_parent_class,见 _resolve_base_alias) bname = self._resolve_base_alias(bname, trans) diff --git a/App/lib/core/Gen/Class/ClassGenGeneric.vp b/App/lib/core/Gen/Class/ClassGenGeneric.vp index baae092..ebe5d9c 100644 --- a/App/lib/core/Gen/Class/ClassGenGeneric.vp +++ b/App/lib/core/Gen/Class/ClassGenGeneric.vp @@ -241,23 +241,49 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): return None def _mangle_generic_class_name(self, pool: memhub.MemBuddy*, class_name: str, - type_args: list[str]*) -> str: + type_args: list[str]*, + from_imports: str = None) -> str: """生成特化类名: list + [int] -> list[int] + **唯一生成器 + 唯一规范化点**:所有特化名(结构体注册名、方法符号里的 + 后缀段、查找键)都由这里产出,故类型实参的 SHA1 规范化只在这里做一次 —— + 每个实参经 `TypeGenResolve._norm_type_arg_name` 归一到 + `{定义模块SHA1}.{Class}`(该函数对已规范化的串**幂等**:规则 2/3/6 原样 + 返回,嵌套 `rawptr[X]` 也递归同形)⇒ 无论调用方(注解侧 / 构造侧 / + 基类侧 / 字面量推断侧)传进来的实参是裸名还是已带前缀,注册名与查找名 + **必然同形**。此前裸露名与已带前缀的两侧会分裂成两个特化结构体,已出现 + 三种现场:形参侧/实参侧(stmts.vp:60)、字段侧/构造侧(base.vp:357)、 + 基类侧/注解侧(ClassGenBase._get_base_name 的裸 Name.id)。 + 分配新缓冲区拼接,避免原地 strcat 导致缓冲区溢出 """ if class_name is None or type_args is None or pool is None: return class_name n: sizet = len(type_args) + if n == 0: + return class_name + # 逐实参规范化(幂等):先归一成新列表,长度计算与拼接都用归一后的串 + norm_args: list[str]* = list[str](pool, 8) + if norm_args is None: + return class_name + i: sizet + for i in range(n): + ta_raw: str = type_args.get(i) + if ta_raw is None: + continue + ta_norm: str = self.Gen.TypeGenResolve._norm_type_arg_name(pool, ta_raw, from_imports) + if ta_norm is None: + ta_norm = ta_raw + norm_args.append(ta_norm) + n = len(norm_args) if n == 0: return class_name # 计算总长度: class_name + "[" + arg0 + "," + arg1 + ... + "]" + NUL total_len: sizet = string.strlen(class_name) + 2 # "[" 和 "]" - i: sizet for i in range(n): if i > 0: total_len += 1 # "," - ta: str = type_args.get(i) + ta: str = norm_args.get(i) if ta is not None: total_len += string.strlen(ta) total_len += 1 # NUL @@ -271,7 +297,7 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): for i in range(n): if i > 0: string.strcat(mangled, ",") - ta: str = type_args.get(i) + ta: str = norm_args.get(i) if ta is not None: string.strcat(mangled, ta) string.strcat(mangled, "]") @@ -566,8 +592,11 @@ novirtual class ClassGenGeneric(ClassGenBase.ClassGenBase): self.GenericSpecDepth -= 1 return None - # 2. 生成特化名 - spec_name: str = self._mangle_generic_class_name(pool, class_name, type_args) + # 2. 生成特化名(唯一生成器内部逐实参规范化:裸名/带前缀在此收敛为同一名) + _from_imports: str = None + if trans is not None: + _from_imports = trans._from_imports + spec_name: str = self._mangle_generic_class_name(pool, class_name, type_args, _from_imports) if spec_name is None: self.GenericSpecDepth -= 1 return None