feat(type): 支持 T | None,等价于 T
仅允许一侧为 None 的联合;解析时剥离 None 后按剩余类型处理,其他联合仍 fail-fast。
This commit is contained in:
1 parent
7911b4de54
commit
ceb557314a
2 files changed
+30
-8
No files matched your search
@@ -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
@@ -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()
|
||||
|
||||
Reference in new issue
Block a user