feat(generic): 泛型函数类型实参推断与单态化
支持 def f[T](x: T) -> T 及 f(x)/f[T](x):模板注册(Phase1Scan/Phase2 顶层 FunctionDef,键 {sha1}.{name})、按形参注解对齐从实参推断类型实参(无来源即 fail-fast,不静默默认 int)、克隆模板并 set_generic_context 后翻译生成特化体(名字 {sha1}.f[int],规范化复用 _mangle_generic_class_name)、同签名去重、跨模块按模板签名补 declare。泛型函数模板不再发 vpi(模板签名含未绑定 T),也不再发射 int 兜底版本。已知限制(未静默):bound [T: bound] 解析期已被丢弃;t.CExport/t.CExtern/t.State 泛型函数、关键字/默认参数调用、mod.f[T](x) 显式下标等暂 fail-fast 或走既有报错。
This commit is contained in:
1 parent
1fbebb2a62
commit
692998820c
10 files changed
+886
-57
No files matched your search
@@ -245,6 +245,50 @@ def _BufHasGenericClassMarker(buf: bytes, blen: sizet) -> int:
|
||||
pos += 1
|
||||
return 0
|
||||
# ============================================================
|
||||
# _BufHasGenericFuncMarker - 文本扫描检测文件是否含泛型函数标记
|
||||
#
|
||||
# 泛型函数(PEP 695)语法: def name[(函数名后紧跟 '[',如 def f[T](...):)。
|
||||
# 与 _BufHasGenericClassMarker 同款逐字节词边界扫描;用于泛型函数模板的
|
||||
# 轻量预筛(避免为无泛型函数的文件 parse AST)。误报无害、漏报有害(模板未
|
||||
# 预注册),故保守只匹配单行形式。
|
||||
# ============================================================
|
||||
def _BufHasGenericFuncMarker(buf: bytes, blen: sizet) -> int:
|
||||
"""文本扫描:buf 中是否有 'def 标识符[' 泛型函数标记,返回 1/0"""
|
||||
if buf is None or blen <= 4:
|
||||
return 0
|
||||
pos: sizet = 0
|
||||
while pos + 3 < blen:
|
||||
if buf[pos] == 'd' and buf[pos + 1] == 'e' and buf[pos + 2] == 'f':
|
||||
# def 前是词边界(行首或非标识符字符)
|
||||
prev_ok: int = 1
|
||||
if pos > 0:
|
||||
pc: char = buf[pos - 1]
|
||||
if(pc >= 'a' and pc <= 'z') or(pc >= 'A' and pc <= 'Z') \
|
||||
or(pc >= '0' and pc <= '9') or pc == '_':
|
||||
prev_ok = 0
|
||||
if prev_ok != 0:
|
||||
p: sizet = pos + 3
|
||||
# 跳过空白
|
||||
while p < blen and(buf[p] == ' ' or buf[p] == '\t'):
|
||||
p += 1
|
||||
# 读函数名标识符
|
||||
if p < blen and((buf[p] >= 'a' and buf[p] <= 'z')
|
||||
or(buf[p] >= 'A' and buf[p] <= 'Z') or buf[p] == '_'):
|
||||
while p < blen and((buf[p] >= 'a' and buf[p] <= 'z')
|
||||
or(buf[p] >= 'A' and buf[p] <= 'Z')
|
||||
or(buf[p] >= '0' and buf[p] <= '9')
|
||||
or buf[p] == '_'):
|
||||
p += 1
|
||||
# 函数名后非空白是 '[' → 泛型函数
|
||||
while p < blen and(buf[p] == ' ' or buf[p] == '\t'):
|
||||
p += 1
|
||||
if p < blen and buf[p] == '[':
|
||||
return 1
|
||||
pos += 1
|
||||
else:
|
||||
pos += 1
|
||||
return 0
|
||||
# ============================================================
|
||||
# _PreRegisterAllGenericTemplates - 预注册 includes 泛型类模板(mark1 前)
|
||||
#
|
||||
# 泛型模板表(GenericClassNames/GenericClassNodes/GenericClassSha1s/GenericClassFiles + 模板节点)是懒分配的跨文件持久表,
|
||||
@@ -289,8 +333,10 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*,
|
||||
continue
|
||||
if bytes_read_pg < Phase1.SRC_BUF_SIZE:
|
||||
src_buf_pg[bytes_read_pg] = 0
|
||||
# 文本扫描筛选:非泛型文件跳过(不 parse、不驻留,防 OOM)
|
||||
if _BufHasGenericClassMarker(src_buf_pg, bytes_read_pg) == 0:
|
||||
# 文本扫描筛选:非泛型文件跳过(不 parse、不驻留,防 OOM)。
|
||||
# 泛型类(class X[)与泛型函数(def f[)任一命中即进入 parse。
|
||||
if _BufHasGenericClassMarker(src_buf_pg, bytes_read_pg) == 0 \
|
||||
and _BufHasGenericFuncMarker(src_buf_pg, bytes_read_pg) == 0:
|
||||
stdlib.free(src_buf_pg)
|
||||
continue
|
||||
# 泛型文件:永久池解析 → 注册模板(节点/表进 perm_pool,跨 reset 存活)
|
||||
@@ -304,26 +350,38 @@ def _PreRegisterAllGenericTemplates(mb: memhub.MemBuddy*,
|
||||
if tree_pg is None:
|
||||
stdlib.free(src_buf_pg)
|
||||
continue
|
||||
# 遍历顶层 ClassDef,注册泛型模板(type_params 非 None)
|
||||
# 遍历顶层 ClassDef/FunctionDef,注册泛型模板(type_params 非 None)
|
||||
ch_pg: list[ast.AST*]* = tree_pg.children
|
||||
if ch_pg is not None:
|
||||
cn_pg: sizet = len(ch_pg)
|
||||
for ci_pg in range(cn_pg):
|
||||
child_pg: ast.AST* = ch_pg.get(ci_pg)
|
||||
if child_pg is None or child_pg.kind() != ast.ASTKind.ClassDef:
|
||||
if child_pg is None:
|
||||
continue
|
||||
cd_pg: ast.ClassDef* = ast.ClassDef*(child_pg)
|
||||
if cd_pg is None or cd_pg.name is None:
|
||||
continue
|
||||
tp_pg: list[str]* = cd_pg.type_params
|
||||
if tp_pg is None:
|
||||
continue
|
||||
GenApi.set_current_file_type(file_path_pg)
|
||||
GenApi._register_generic_template(perm, cd_pg, entry_pg.Sha1)
|
||||
handled_count += 1
|
||||
ck_pg: int = child_pg.kind()
|
||||
if ck_pg == ast.ASTKind.ClassDef:
|
||||
cd_pg: ast.ClassDef* = ast.ClassDef*(child_pg)
|
||||
if cd_pg is None or cd_pg.name is None:
|
||||
continue
|
||||
tp_pg: list[str]* = cd_pg.type_params
|
||||
if tp_pg is None:
|
||||
continue
|
||||
GenApi.set_current_file_type(file_path_pg)
|
||||
GenApi._register_generic_template(perm, cd_pg, entry_pg.Sha1)
|
||||
handled_count += 1
|
||||
elif ck_pg == ast.ASTKind.FunctionDef:
|
||||
fd_pg: ast.FunctionDef* = ast.FunctionDef*(child_pg)
|
||||
if fd_pg is None or fd_pg.name is None:
|
||||
continue
|
||||
tf_pg: list[str]* = fd_pg.type_params
|
||||
if tf_pg is None:
|
||||
continue
|
||||
GenApi.set_current_file_type(file_path_pg)
|
||||
GenApi._register_generic_func_template(perm, fd_pg, entry_pg.Sha1)
|
||||
handled_count += 1
|
||||
stdlib.free(src_buf_pg)
|
||||
if handled_count > 0:
|
||||
VLogger.info(f"mark1 前永久池预注册 {handled_count} 个 includes 泛型类模板", "Phase1")
|
||||
VLogger.info(f"mark1 前永久池预注册 {handled_count} 个 includes 泛型模板(类+函数)", "Phase1")
|
||||
else:
|
||||
VLogger.info(f"mark1 前永久池预注册 0 个泛型模板(扫描 {result.Count} 个文件,可能 marker 未命中或全量扫描失败)", "Phase1")
|
||||
return handled_count
|
||||
|
||||
@@ -303,26 +303,38 @@ def _PreRegisterAppGenericTemplates(mb: memhub.MemBuddy*,
|
||||
if tree_pa is None:
|
||||
stdlib.free(src_buf_pa)
|
||||
continue
|
||||
# 遍历顶层 ClassDef,注册泛型模板(type_params 非 None)
|
||||
# 遍历顶层 ClassDef/FunctionDef,注册泛型模板(type_params 非 None)
|
||||
ch_pa: list[ast.AST*]* = tree_pa.children
|
||||
if ch_pa is not None:
|
||||
cn_pa: sizet = len(ch_pa)
|
||||
for ci_pa in range(cn_pa):
|
||||
child_pa: ast.AST* = ch_pa.get(ci_pa)
|
||||
if child_pa is None or child_pa.kind() != ast.ASTKind.ClassDef:
|
||||
if child_pa is None:
|
||||
continue
|
||||
cd_pa: ast.ClassDef* = ast.ClassDef*(child_pa)
|
||||
if cd_pa is None or cd_pa.name is None:
|
||||
continue
|
||||
tp_pa: list[str]* = cd_pa.type_params
|
||||
if tp_pa is None:
|
||||
continue
|
||||
GenApi.set_current_file_type(ent_pa.Path)
|
||||
GenApi._register_generic_template(perm_pa, cd_pa, ent_pa.Sha1)
|
||||
handled += 1
|
||||
ck_pa: int = child_pa.kind()
|
||||
if ck_pa == ast.ASTKind.ClassDef:
|
||||
cd_pa: ast.ClassDef* = ast.ClassDef*(child_pa)
|
||||
if cd_pa is None or cd_pa.name is None:
|
||||
continue
|
||||
tp_pa: list[str]* = cd_pa.type_params
|
||||
if tp_pa is None:
|
||||
continue
|
||||
GenApi.set_current_file_type(ent_pa.Path)
|
||||
GenApi._register_generic_template(perm_pa, cd_pa, ent_pa.Sha1)
|
||||
handled += 1
|
||||
elif ck_pa == ast.ASTKind.FunctionDef:
|
||||
fd_pa: ast.FunctionDef* = ast.FunctionDef*(child_pa)
|
||||
if fd_pa is None or fd_pa.name is None:
|
||||
continue
|
||||
tf_pa: list[str]* = fd_pa.type_params
|
||||
if tf_pa is None:
|
||||
continue
|
||||
GenApi.set_current_file_type(ent_pa.Path)
|
||||
GenApi._register_generic_func_template(perm_pa, fd_pa, ent_pa.Sha1)
|
||||
handled += 1
|
||||
stdlib.free(src_buf_pa)
|
||||
if handled > 0:
|
||||
VLogger.info(f"mark2 前预注册 {handled} 个 App 泛型类模板", "PhaseA")
|
||||
VLogger.info(f"mark2 前预注册 {handled} 个 App 泛型模板(类+函数)", "PhaseA")
|
||||
return handled
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user