feat(gen,type): callable[] / callable[[]] / callable[[A,B],R] 与 t.Callable 逐点等价
- 判据单一真源:_SubscriptAttrIsCallable 扩为 _IsCallableSubscriptValue,同时认 Attribute(attr=Callable) 与裸名 Name(callable | Callable)。 - Subscript 分支在 Name 路径(泛型特化 / CArray / builtins typedef 兜底)之前拦截裸名 callable/Callable → i8*;否则 callable[] 会先撞 slice=None 的 fail-fast、callable[[]] 会被当泛型类名查空。 - TypeGenErr.try_extract_callable_ret 改用同一判据:callable[[A, B], R] 现在也会注册返回类型 R(可间接调用),无签名形态([]、[[]])仍返回 None。
This commit is contained in:
1 parent
a76cf55a2d
commit
9455db0eec
2 files changed
+37
-16
No files matched your search
@@ -184,14 +184,14 @@ novirtual class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
imported_modules: str,
|
||||
from_imports: str,
|
||||
trans: HT.Translator*) -> llvmlite.LLVMType*:
|
||||
"""提取 t.Callable 注解的返回类型 LLVMType;非 Callable 注解返回 None"""
|
||||
"""提取函数指针注解(t.Callable[[A,B], R] / callable[[A,B], R])的返回类型
|
||||
LLVMType;非 Callable 注解或无签名形态([]、[[]])返回 None"""
|
||||
if annot is None or annot.kind() != ast.ASTKind.Subscript:
|
||||
return None
|
||||
sub_cr: ast.Subscript* = ast.Subscript*(annot)
|
||||
if sub_cr.value is None or sub_cr.value.kind() != ast.ASTKind.Attribute:
|
||||
return None
|
||||
at_cr: ast.Attribute* = ast.Attribute*(sub_cr.value)
|
||||
if at_cr.attr is None or string.strcmp(at_cr.attr, "Callable") != 0:
|
||||
# 构造子判据走 TypeGenResolve 单一真源(Attribute 形态 t.Callable 与
|
||||
# 裸名形态 callable / Callable 等价)
|
||||
if self.Gen.TypeGenResolve._IsCallableSubscriptValue(sub_cr.value) == 0:
|
||||
return None
|
||||
# slice 必须是 Tuple(elts=[args_list, ret_node])
|
||||
if sub_cr.slice is None or sub_cr.slice.kind() != ast.ASTKind.Tuple:
|
||||
|
||||
@@ -1366,20 +1366,33 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
return llvmlite.Int32(pool)
|
||||
return llvmlite.Int64(pool)
|
||||
# ============================================================
|
||||
# _SubscriptAttrIsCallable - Subscript 的 value 是否为 t.Callable / c.Callable
|
||||
# _IsCallableSubscriptValue - Subscript 的 value 是否为函数指针类型构造子
|
||||
#
|
||||
# 用于放行"空下标/空参数表"的无签名函数指针注解:
|
||||
# t.Callable[](slice=None)/ t.Callable[[]](slice=空 List)
|
||||
# 与 t.Callable[[A, B], Ret]、裸 t.Callable 同为 i8*。
|
||||
# 两种书写形态逐点等价(同 i8*):
|
||||
# t.Callable[...] / c.Callable[...] → Attribute(attr="Callable")
|
||||
# callable[...] / Callable[...] → Name(内建别名,注解位置生效)
|
||||
# 用于放行"空下标/空参数表"的无签名形态(slice=None / 空 List):
|
||||
# t.Callable[] / t.Callable[[]] / callable[] / callable[[]]
|
||||
# ============================================================
|
||||
def _SubscriptAttrIsCallable(self, value_node: ast.AST*) -> int:
|
||||
if value_node is None or value_node.kind() != ast.ASTKind.Attribute:
|
||||
def _IsCallableSubscriptValue(self, value_node: ast.AST*) -> int:
|
||||
if value_node is None:
|
||||
return 0
|
||||
at: ast.Attribute* = ast.Attribute*(value_node)
|
||||
if at.attr is None:
|
||||
vk: int = value_node.kind()
|
||||
if vk == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute* = ast.Attribute*(value_node)
|
||||
if at.attr is None:
|
||||
return 0
|
||||
if string.strcmp(at.attr, "Callable") == 0:
|
||||
return 1
|
||||
return 0
|
||||
if string.strcmp(at.attr, "Callable") == 0:
|
||||
return 1
|
||||
if vk == ast.ASTKind.Name:
|
||||
nm: ast.Name* = ast.Name*(value_node)
|
||||
if nm.id is None:
|
||||
return 0
|
||||
if string.strcmp(nm.id, "callable") == 0:
|
||||
return 1
|
||||
if string.strcmp(nm.id, "Callable") == 0:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def map_t_type(self, pool: memhub.MemBuddy*,
|
||||
@@ -2774,8 +2787,16 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
self.Gen.TypeGenErr.fatal_type_error(node, "Subscript 节点缺少 value")
|
||||
# 空下标形态(t.Callable[])的 slice 为 None:只有无签名函数指针允许,
|
||||
# 落到下方 Callable 分支按 i8* 处理;其它类型仍要求 slice 存在。
|
||||
if sub.slice is None and self._SubscriptAttrIsCallable(sub.value) == 0:
|
||||
if sub.slice is None and self._IsCallableSubscriptValue(sub.value) == 0:
|
||||
self.Gen.TypeGenErr.fatal_type_error(node, "Subscript 节点缺少 value 或 slice")
|
||||
# 函数指针(裸名形态 callable / Callable):与 t.Callable 逐点等价,
|
||||
# 无签名(callable[] / callable[[]])或有签名(callable[[A, B], R])
|
||||
# 统一 i8*。必须在本分支的 Name 路径(泛型特化 / CArray / builtins
|
||||
# typedef 兜底)之前判定,否则裸名 callable 会被当泛型类名查空。
|
||||
# 完整签名的返回类型注册见 TypeGenErr.try_extract_callable_ret。
|
||||
if sub.value.kind() == ast.ASTKind.Name \
|
||||
and self._IsCallableSubscriptValue(sub.value) != 0:
|
||||
return llvmlite.Ptr(pool, llvmlite.Int8(pool))
|
||||
# 泛型类类型注解: list[int] → 查找已特化的 struct(value 是 Name 泛型类名)
|
||||
if sub.value.kind() == ast.ASTKind.Name:
|
||||
gen_nm: ast.Name* = ast.Name*(sub.value)
|
||||
|
||||
Reference in new issue
Block a user