feat(type): 支持 T | None,等价于 T

仅允许一侧为 None 的联合;解析时剥离 None 后按剩余类型处理,其他联合仍 fail-fast。
This commit is contained in:
TermiNexus committed 2026-10-18 18:10:01 +08:00
1 parent 7911b4de54
commit ceb557314a
2 files changed
+30 -8

No files matched your search

+15 -4
View File
@@ -131,10 +131,21 @@ class TypeAnnotationResolver:
SymbolTable: 符号表字典
"""
if isinstance(Node, ast.BinOp) and isinstance(Node.op, ast.BitOr):
Line: int = getattr(Node, 'lineno', 0) or 0
raise TypeError(
f"[TPC] 不支持类型联合 'T1 | T2'(第 {Line} 行);"
f"类型注解只能是单一类型:指针请写 CPtr[T],修饰符请用关键字")
def _is_none_literal(n: ast.AST) -> bool:
if isinstance(n, ast.Constant):
return getattr(n, 'value', ...) is None
return isinstance(n, ast.Name) and getattr(n, 'id', '') == 'None'
_left_none: bool = _is_none_literal(Node.left)
_right_none: bool = _is_none_literal(Node.right)
if _left_none != _right_none:
# `T | None` / `None | T` 等价于 T
Node = Node.right if _left_none else Node.left
else:
Line: int = getattr(Node, 'lineno', 0) or 0
raise TypeError(
f"[TPC] 不支持类型联合 'T1 | T2'(第 {Line} 行);"
f"类型注解只能是单一类型:指针请写 CPtr[T],修饰符请用关键字")
if isinstance(Node, ast.Constant):
Info: CTypeInfo = TypeAnnotationResolver._from_node_constant(Node, SymbolTable)
elif isinstance(Node, ast.Name):
+15 -4
View File
@@ -1783,10 +1783,21 @@ class ExprParserMixin(TokenStream):
"[vast] 类型注解的修饰词后缺少类型(如 `x: const int`)。")
return None
if isinstance(expr, N.BinOp) and isinstance(expr.op, N.BitOr):
Line: int = getattr(expr, 'lineno', 0) or 0
raise TypeError(
f"[TPC] 不支持类型联合 'T1 | T2'(第 {Line} 行);"
f"类型注解只能是单一类型:指针请写 CPtr[T],修饰符请用关键字")
def _is_none_literal(n: N.AST) -> bool:
if isinstance(n, N.Constant):
return getattr(n, 'value', ...) is None
return isinstance(n, N.Name) and getattr(n, 'id', '') == 'None'
_left_none: bool = _is_none_literal(expr.left)
_right_none: bool = _is_none_literal(expr.right)
if _left_none != _right_none:
# `T | None` / `None | T` 等价于 T
expr = expr.right if _left_none else expr.left
else:
Line: int = getattr(expr, 'lineno', 0) or 0
raise TypeError(
f"[vast] 不支持类型联合 'T1 | T2'(第 {Line} 行);"
f"类型注解只能是单一类型:指针请写 CPtr[T],修饰符请用关键字")
if self._AtPtrSuffix(expr):
expr = self._ConsumePtrSuffix(expr)
tok: Token = self._Peek()