diff --git a/.gitignore b/.gitignore index 415386a..63fdcb7 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ __pycache__ *.pywz *.pyzw *.pyzwz + +.vscode/ \ No newline at end of file diff --git a/parser-Python/test/test_type_annotations.py b/parser-Python/test/test_type_annotations.py new file mode 100644 index 0000000..4a2776e --- /dev/null +++ b/parser-Python/test/test_type_annotations.py @@ -0,0 +1,321 @@ +"""测试 Python typing 模块支持的所有类型注解 + +根据 Python typing 文档 (PEP 484, 526, 544, 586, 593, 612, 613, 647, 655, 673, 675, 681, 692, 695, 742) +测试以下类型注解场景: + +1. 基本类型:int, float, str, bool, None +2. 容器类型:List, Dict, Tuple, Set +3. 特殊类型:Optional, Union, Literal, Any +4. 泛型类型:Generic, TypeVar, 用户定义的泛型类 +5. 其他:Callable, Type, NewType, Protocol 等 +""" + +from __future__ import annotations +from typing import ( + List, Dict, Optional, Union, Tuple, Literal, Generic, TypeVar, + Set, Any, Callable, Type, NewType, Protocol, TypedDict +) + +# ========== 1. 基本类型 (PEP 484) ========== +# 测试:int, float, str, bool, None + +def test_int() -> int: + """测试 int 类型注解""" + return 1 + +def test_float() -> float: + """测试 float 类型注解""" + return 3.14 + +def test_str() -> str: + """测试 str 类型注解""" + return "hello" + +def test_bool() -> bool: + """测试 bool 类型注解""" + return True + +def test_none() -> None: + """测试 None 类型注解""" + pass + +# ========== 2. 容器类型 (PEP 484, PEP 585) ========== +# 测试:List[T], Dict[K, V], Tuple[T1, T2, ...], Set[T] + +def test_list_int() -> List[int]: + """测试 List[int] 类型注解""" + return [1, 2, 3] + +def test_list_str() -> List[str]: + """测试 List[str] 类型注解""" + return ["a", "b"] + +# Python 3.9+ 语法 (PEP 585) +def test_list_int_new() -> list[int]: + """测试 Python 3.9+ 的 list[int] 语法""" + return [1, 2, 3] + +def test_dict_str_int() -> Dict[str, int]: + """测试 Dict[str, int] 类型注解""" + return {"a": 1, "b": 2} + +def test_dict_int_str() -> Dict[int, str]: + """测试 Dict[int, str] 类型注解""" + return {1: "a", 2: "b"} + +# Python 3.9+ 语法 (PEP 585) +def test_dict_str_int_new() -> dict[str, int]: + """测试 Python 3.9+ 的 dict[str, int] 语法""" + return {"a": 1} + +def test_tuple_int_str() -> Tuple[int, str]: + """测试 Tuple[int, str] 类型注解""" + return (1, "hello") + +def test_tuple_three() -> Tuple[int, str, bool]: + """测试 Tuple[int, str, bool] 类型注解""" + return (1, "a", True) + +# Python 3.9+ 语法 (PEP 585) +def test_tuple_new() -> tuple[int, str]: + """测试 Python 3.9+ 的 tuple[int, str] 语法""" + return (1, "hello") + +def test_tuple_variable_length() -> tuple[int, ...]: + """测试 tuple[int, ...] 可变长度元组类型注解""" + return (1, 2, 3, 4, 5) + +def test_set_int() -> Set[int]: + """测试 Set[int] 类型注解""" + return {1, 2, 3} + +# Python 3.9+ 语法 (PEP 585) +def test_set_int_new() -> set[int]: + """测试 Python 3.9+ 的 set[int] 语法""" + return {1, 2, 3} + +# ========== 3. Optional 类型 (PEP 484) ========== +# 测试:Optional[T] 等价于 Union[T, None] + +def test_optional_str() -> Optional[str]: + """测试 Optional[str] 类型注解""" + return None + +def test_optional_int() -> Optional[int]: + """测试 Optional[int] 类型注解""" + return 42 + +# ========== 4. Union 类型 (PEP 484) ========== +# 测试:Union[T1, T2, ...] 表示 T1 或 T2 类型 + +def test_union_int_str() -> Union[int, str]: + """测试 Union[int, str] 类型注解""" + return 1 + +def test_union_with_none() -> Union[str, None]: + """测试 Union[str, None] 类型注解""" + return None + +def test_union_three() -> Union[int, str, bool]: + """测试 Union[int, str, bool] 类型注解""" + return True + +# Python 3.10+ 语法 (PEP 604) +def test_union_pipe() -> int | str: + """测试 Python 3.10+ 的 int | str 语法""" + return 1 + +# ========== 5. Literal 类型 (PEP 586) ========== +# 测试:Literal["a", "b", ...] 表示字面量值的联合类型 + +def test_literal_str() -> Literal["success", "error"]: + """测试 Literal["success", "error"] 类型注解""" + return "success" + +def test_literal_int() -> Literal[1, 2, 3]: + """测试 Literal[1, 2, 3] 类型注解""" + return 1 + +def test_literal_bool() -> Literal[True, False]: + """测试 Literal[True, False] 类型注解""" + return True + +def test_literal_mixed() -> Literal["a", 1, True]: + """测试混合类型的 Literal["a", 1, True] 类型注解""" + return "a" + +# ========== 6. Any 类型 (PEP 484) ========== +# 测试:Any 表示任意类型 + +def test_any() -> Any: + """测试 Any 类型注解""" + return "anything" + +# ========== 7. 嵌套类型 ========== +# 测试:嵌套的容器类型和特殊类型 + +def test_list_of_dict() -> List[Dict[str, int]]: + """测试 List[Dict[str, int]] 嵌套类型注解""" + return [{"a": 1}] + +def test_dict_of_list() -> Dict[str, List[int]]: + """测试 Dict[str, List[int]] 嵌套类型注解""" + return {"nums": [1, 2, 3]} + +def test_optional_list() -> Optional[List[int]]: + """测试 Optional[List[int]] 嵌套类型注解""" + return [1, 2, 3] + +def test_union_list() -> Union[List[int], List[str]]: + """测试 Union[List[int], List[str]] 嵌套类型注解""" + return [1, 2, 3] + +# ========== 8. 用户定义的泛型类型 (PEP 484, PEP 695) ========== +# 测试:Generic[T], TypeVar, 用户定义的泛型类 + +# 定义类型变量 +T = TypeVar('T') + +class MyClass(Generic[T]): + """用户定义的泛型类""" + pass + +def test_custom_type() -> MyClass: + """测试自定义类型 MyClass 类型注解""" + return MyClass() + +def test_custom_generic() -> MyClass[str]: + """测试 MyClass[str] 泛型类型注解""" + return MyClass() + +def test_custom_literal() -> MyClass[Literal["test"]]: + """测试 MyClass[Literal["test"]] 复杂泛型类型注解""" + return MyClass() + +def test_custom_list() -> MyClass[List[str]]: + """测试 MyClass[List[str]] 嵌套泛型类型注解""" + return MyClass() + +def test_custom_dict() -> MyClass[Dict[str, int]]: + """测试 MyClass[Dict[str, int]] 嵌套泛型类型注解""" + return MyClass() + +def test_custom_nested() -> MyClass[Optional[List[Dict[str, int]]]]: + """测试 MyClass[Optional[List[Dict[str, int]]]] 多层嵌套泛型类型注解""" + return MyClass() + +def test_custom_double() -> MyClass[MyClass[str]]: + """测试 MyClass[MyClass[str]] 双重泛型类型注解""" + return MyClass() + +# ========== 9. Callable 类型 (PEP 484) ========== +# 测试:Callable[[Args], ReturnType] 用于标注可调用对象 + +def test_callable() -> Callable[[int, str], bool]: + """测试 Callable[[int, str], bool] 类型注解""" + def func(x: int, y: str) -> bool: + return True + return func + +def test_callable_ellipsis() -> Callable[..., str]: + """测试 Callable[..., str] 类型注解(任意参数)""" + def func(*args, **kwargs) -> str: + return "result" + return func + +def test_callable_no_args() -> Callable[[], bool]: + """测试 Callable[[], bool] 类型注解(无参数)""" + def func() -> bool: + return True + return func + +# ========== 10. Type 类型 (PEP 484) ========== +# 测试:Type[C] 用于标注类对象本身 + +class User: + pass + +def test_type() -> Type[User]: + """测试 Type[User] 类型注解""" + return User + +def test_type_union() -> Type[User] | Type[str]: + """测试 Type[User] | Type[str] 类型注解""" + return User + +# ========== 11. NewType (PEP 484) ========== +# 测试:NewType 用于创建独有类型 + +UserId = NewType('UserId', int) + +def test_newtype() -> UserId: + """测试 NewType UserId 类型注解""" + return UserId(1) + +# ========== 12. Protocol (PEP 544) ========== +# 测试:Protocol 用于结构子类型(静态鸭子类型) + +class Drawable(Protocol): + """Protocol 定义""" + def draw(self) -> None: + ... + +def test_protocol() -> Drawable: + """测试 Protocol 类型注解""" + class Circle: + def draw(self) -> None: + pass + return Circle() + +# ========== 13. TypedDict (PEP 589) ========== +# 测试:TypedDict 用于类型化字典 + +class Movie(TypedDict): + """TypedDict 定义""" + title: str + year: int + +def test_typeddict() -> Movie: + """测试 TypedDict 类型注解""" + return {"title": "Matrix", "year": 1999} + +# ========== 14. 函数参数类型注解 ========== +# 测试:函数参数的类型注解 + +def test_param_annotations( + x: int, + y: str = "default", + z: Optional[List[int]] = None +) -> Dict[str, int]: + """测试函数参数的类型注解""" + return {"result": 1} + +# ========== 15. 变量类型注解 (PEP 526) ========== +# 测试:变量声明的类型注解 + +x: int = 1 +y: List[str] = ["a", "b"] +z: Optional[Dict[str, int]] = None + +# ========== 16. 复杂组合类型 ========== +# 测试:各种类型的复杂组合 + +def test_complex_combination() -> Dict[str, List[Union[int, str]]]: + """测试复杂的组合类型注解""" + return {"nums": [1, "two", 3]} + +def test_literal_in_generic() -> MyClass[Literal["chart_generator", "END"]]: + """测试泛型中的 Literal 类型""" + END = "END" + return MyClass() + +def test_union_in_list() -> List[Union[int, str, bool]]: + """测试 List 中的 Union 类型""" + return [1, "two", True] + +# ========== 17. 无类型注解 ========== +# 测试:没有类型注解的函数 + +def test_no_annotation(): + """测试无类型注解的函数""" + return "no type" diff --git a/parser-Python/uast/asttype.py b/parser-Python/uast/asttype.py index c698b7d..0f8ff82 100644 --- a/parser-Python/uast/asttype.py +++ b/parser-Python/uast/asttype.py @@ -427,6 +427,7 @@ class DynamicType(BaseNode): , IfStatement , ImportExpression , Literal + , MapType , MemberAccess , NewExpression , Noop diff --git a/parser-Python/uast/visitor.py b/parser-Python/uast/visitor.py index fa66258..3945ca4 100644 --- a/parser-Python/uast/visitor.py +++ b/parser-Python/uast/visitor.py @@ -8,6 +8,265 @@ class UASTTransformer(ast.NodeTransformer): tmpVarIndex = 0 sourcefile = "" + def _parse_type_annotation(self, node): + """解析类型注解,支持以下类型注解: + 1. 基本类型:int, float, str, bool, None + 2. 容器类型:List[T], Dict[K, V], Tuple[T1, T2, ...], Set[T] + 3. 特殊类型:Optional[T], Union[T1, T2, ...], Literal[value, ...], Any + 4. Python 3.10+ 管道联合语法:int | str (PEP 604) + 5. 泛型类型:Generic[T], TypeVar, 用户定义的泛型类 + 6. 其他:Callable, Type[C], NewType, Protocol 等 + + Args: + annotation_node: AST 节点,可能是 ast.Name, ast.Subscript, ast.BinOp, ast.Constant 等 + + Returns: + UAST Type 节点 (PrimitiveType, ArrayType, MapType, DynamicType, Identifier 等) + """ + if node is None: + return UNode.DynamicType(UNode.SourceLocation(), UNode.Meta()) + + # ========== 1. 处理基本类型名称 ========== + # 根据 PEP 484: 基本类型 int, float, str, bool + # 不包括 None 类型, 因为 None 节点是 Constant 类型而不是 ast.Name + if isinstance(node, ast.Name): + if node.id == "float" or node.id == "int": + # int 和 float 都映射为 number 类型 + return self.packPos(node, + UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), kind="number")) + elif node.id == "str": + return self.packPos(node, + UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), kind="string")) + elif node.id == "bool": + return self.packPos(node, + UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), kind="boolean")) + elif node.id == "Any": + # typing.Any: 特殊类型,表示任意类型 (PEP 484) + return self.packPos(node, + UNode.DynamicType(UNode.SourceLocation(), UNode.Meta(), id="Any")) + else: + # 其他类型名称(自定义类型、类名等),使用 Identifier + return self.packPos(node, + UNode.Identifier(UNode.SourceLocation(), UNode.Meta(), name=node.id)) + + # ========== 2. 处理泛型类型(使用 ast.Subscript) ========== + # 根据 PEP 484, PEP 585: 支持 List[T], Dict[K, V], Tuple[T1, T2, ...] 等 + # 支持限定名称:typing.List[int], collections.abc.Mapping[str, int] 等 + elif isinstance(node, ast.Subscript): + # 提取类型名称:支持 ast.Name (如 List) 和 ast.Attribute (如 typing.List) + type_name = None + if isinstance(node.value, ast.Name): + type_name = node.value.id + elif isinstance(node.value, ast.Attribute): + # 对于限定名称(如 typing.List),提取最后的属性名 + type_name = node.value.attr + + if type_name: + + # ========== 2.1 Dict 类型: Dict[K, V] 或 dict[K, V] ========== + # PEP 484: Dict 接受两个类型参数,键类型和值类型 + # Python 3.9+ 支持 dict[K, V] 语法 (PEP 585) + if type_name in ("dict", "Dict"): + keyType = valType = None + if isinstance(node.slice, ast.Tuple): + if len(node.slice.elts) == 2: + # 解析键类型 + keyType = self._parse_type_annotation(node.slice.elts[0]) + # 解析值类型 + valType = self._parse_type_annotation(node.slice.elts[1]) + + # 返回: UAST MapType (keyType=键类型, valueType=值类型) + return self.packPos(node, UNode.MapType(UNode.SourceLocation(), UNode.Meta(), + keyType=keyType, valueType=valType)) + + # ========== 2.2 List 类型: List[T] 或 list[T] ========== + # PEP 484: List 接受一个类型参数,表示元素类型 + # Python 3.9+ 支持 list[T] 语法 (PEP 585) + elif type_name in ("list", "List"): + type_arg = self._parse_type_annotation(node.slice) + # 返回: UAST ArrayType (element=元素类型) + return self.packPos(node, UNode.ArrayType(UNode.SourceLocation(), UNode.Meta(), + element=type_arg)) + + # ========== 2.3 Tuple 类型: Tuple[T1, T2, ...] 或 tuple[T1, T2, ...] ========== + # PEP 484: Tuple 可以接受任意数量的类型参数 + # Tuple[int, str] 表示固定长度元组,第一个元素是 int,第二个是 str + # tuple[int, ...] 表示任意长度的元组,所有元素类型为 int + # Python 3.9+ 支持 tuple[T1, T2, ...] 语法 (PEP 585) + elif type_name in ("tuple", "Tuple"): + type_args = [] + if isinstance(node.slice, ast.Tuple): + # 处理多个类型参数的情况:Tuple[int, str] 或 tuple[int, ...] + for elt in node.slice.elts: + type_args.append(self._parse_type_annotation(elt)) + else: + # 单个参数:Tuple[int],slice 直接是类型节点 + type_args.append(self._parse_type_annotation(node.slice)) + + # 返回: UAST DynamicType (id="Tuple"/"tuple", typeArguments=[元素类型列表, 可能包含 Ellipsis 标记]) + return self.packPos(node, UNode.DynamicType(UNode.SourceLocation(), UNode.Meta(), + id=type_name, typeArguments=type_args if type_args else None)) + + # ========== 2.4 Set 类型: Set[T] 或 set[T] ========== + # PEP 484: Set 接受一个类型参数,表示元素类型 + # Python 3.9+ 支持 set[T] 语法 (PEP 585) + elif type_name in ("set", "Set"): + type_arg = self._parse_type_annotation(node.slice) + + # 返回: UAST DynamicType (id="Set"/"set", typeArguments=[元素类型]) + return self.packPos(node, UNode.DynamicType(UNode.SourceLocation(), UNode.Meta(), + id=type_name, typeArguments=[type_arg] if type_arg else None)) + + # ========== 2.5 Optional 类型: Optional[T] ========== + # PEP 484: Optional[T] 等价于 Union[T, None] + # Optional 只接受一个类型参数,slice 直接是类型节点(ast.Name 或 ast.Subscript) + elif type_name == "Optional": + type_arg = self._parse_type_annotation(node.slice) + # 返回: UAST DynamicType (id="Optional", typeArguments=[类型参数]) + return self.packPos(node, UNode.DynamicType(UNode.SourceLocation(), UNode.Meta(), + id=type_name, typeArguments=[type_arg] if type_arg else None)) + + # ========== 2.6 Union 类型: Union[T1, T2, ...] ========== + # PEP 484: Union[X, Y] 表示 X 或 Y 类型 + # Python 3.10+ 支持 X | Y 语法 (PEP 604) + # 使用 DynamicType 保存所有联合类型,以保留完整的类型信息 + elif type_name == "Union": + type_args = [] + if isinstance(node.slice, ast.Tuple): + for elt in node.slice.elts: + type_args.append(self._parse_type_annotation(elt)) + else: + type_args.append(self._parse_type_annotation(node.slice)) + + # 返回: UAST DynamicType (id="Union", typeArguments=[所有联合类型]) + return self.packPos(node, UNode.DynamicType(UNode.SourceLocation(), + UNode.Meta(), id=type_name, typeArguments=type_args if type_args else None)) + + # ========== 2.7 Literal 类型: Literal["a", "b", ...] ========== + # PEP 586: Literal 用于定义"字面值类型" + # Literal["a", "b"] 表示值只能是 "a" 或 "b" + elif type_name == "Literal": + literal_values = [] + if isinstance(node.slice, ast.Tuple): + for elt in node.slice.elts: + literal_values.append(self._parse_type_annotation(elt)) + else: + literal_values.append(self._parse_type_annotation(node.slice)) + + # 返回: UAST DynamicType (id="Literal", typeArguments=[Literal值列表,每个值可能是PrimitiveType或Identifier]) + return self.packPos(node, UNode.DynamicType(UNode.SourceLocation(), + UNode.Meta(), id=type_name, typeArguments=literal_values if literal_values else None)) + + # ========== 2.8 Callable 类型: Callable[[Args], ReturnType] ========== + # PEP 484: Callable 用于标注可调用对象 + # Callable[[int, str], bool] 表示接受 int 和 str 参数,返回 bool 的函数 + # slice 是 ast.Tuple,包含两个元素:[参数列表(ast.List), 返回类型] + # 需要区分参数类型列表和返回类型 + elif type_name == "Callable": + param_types_list = None + return_type = None + + if isinstance(node.slice, ast.Tuple): + if len(node.slice.elts) >= 2: + # 第一个元素是参数列表,第二个是返回类型 + param_list_node = node.slice.elts[0] + return_type_node = node.slice.elts[1] + + # 处理参数列表 + if isinstance(param_list_node, ast.List): + # 解析参数类型列表 + param_types = [] + for param_type in param_list_node.elts: + param_types.append(self._parse_type_annotation(param_type)) + # 将参数类型列表包装为 DynamicType,id 为 "Params" + # 空列表 [] 表示无参数, None 表示任意参数(..., 非空列表表示具体参数类型 + # Callable[[], bool] → Params 包装器, typeArguments=[](空列表,表示无参数) + # Callable[..., bool] → Params 包装器, typeArguments=None(None,表示任意参数) + # Callable[[int, str], bool] → Params 包装器, typeArguments=[int, str](具体参数类型) + param_types_list = self.packPos(param_list_node, UNode.DynamicType(UNode.SourceLocation(), + UNode.Meta(), id="Params", typeArguments=param_types if param_types else [])) + elif isinstance(param_list_node, ast.Constant) and param_list_node.value == ...: + # Callable[..., ReturnType] 表示任意参数 + param_types_list = self.packPos(param_list_node, UNode.DynamicType(UNode.SourceLocation(), + UNode.Meta(), id="Params", typeArguments=["Any"])) # Any 表示任意参数 + + # 处理返回类型 + return_type = self._parse_type_annotation(return_type_node) + elif len(node.slice.elts) == 1: + # 只有一个元素,可能是返回类型 + return_type = self._parse_type_annotation(node.slice.elts[0]) + else: + # 单个元素,可能是返回类型 + return_type = self._parse_type_annotation(node.slice) + + # typeArguments: [参数类型列表, 返回类型] + type_args = [] + if param_types_list: + type_args.append(param_types_list) + if return_type: + type_args.append(return_type) + + # 返回: UAST DynamicType (id="Callable", typeArguments=[DynamicType(id="Params", typeArguments=[参数类型列表]), 返回类型]) + return self.packPos(node, UNode.DynamicType(UNode.SourceLocation(), UNode.Meta(), + id=type_name, typeArguments=type_args if type_args else None)) + + # ========== 2.9 其他泛型类型(用户定义的泛型类、Generic[T] 等) ========== + # 包括:用户定义的泛型类、Protocol、TypedDict 等 + else: + type_args = [] + if isinstance(node.slice, ast.Tuple): + for elt in node.slice.elts: + type_args.append(self._parse_type_annotation(elt)) + else: + type_args.append(self._parse_type_annotation(node.slice)) + + # 返回: UAST DynamicType (id=类型名称, typeArguments=[类型参数列表]) + return self.packPos(node, UNode.DynamicType(UNode.SourceLocation(), UNode.Meta(), + id=type_name, typeArguments=type_args if type_args else None)) + + else: + # 返回: 根据 annotation_node.value 的类型返回相应的 UAST 节点 + return self.packPos(node, self.visit(node.value)) + + # ========== 3. 处理 Python 3.10+ 管道联合语法 (PEP 604) ========== + # int | str 等价于 Union[int, str] + # 使用 ast.BinOp 表示,操作符是 ast.BitOr + elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr): + # 递归收集所有联合类型 + # 对于 int | str | bool,AST 结构是嵌套的 BinOp: + # BinOp(left=BinOp(left=int, op=BitOr(), right=str), op=BitOr(), right=bool) + type_args = [] + + def collect_union_types(node): + if isinstance(node, ast.BinOp) and isinstance(node.op, ast.BitOr): + # 递归处理左侧 + collect_union_types(node.left) + # 递归处理右侧 + collect_union_types(node.right) + else: + # 叶子节点,解析为类型 + type_args.append(self._parse_type_annotation(node)) + + collect_union_types(node) + + # 返回: UAST DynamicType (id="Union", typeArguments=[所有联合类型列表]) + return self.packPos(node, UNode.DynamicType(UNode.SourceLocation(), UNode.Meta(), + id="Union", typeArguments=type_args if type_args else None)) + + # ========== 4. 处理 None 常量 ========== + # PEP 484: None 可以作为类型注解,表示 None 类型 + # Python 3.8+ 使用 ast.Constant(value=None) + elif isinstance(node, ast.Constant) and node.value is None: + # 返回: UAST PrimitiveType (kind="null") + return self.packPos(node, UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), "null")) + + # ========== 5. 其他情况 ========== + # 对于无法识别的类型注解,使用默认的 visit 方法处理 + # 这可能包括:复杂的表达式、前向引用等 + else: + # 返回: 根据 annotation_node 的类型返回相应的 UAST 节点(可能是 BinaryExpression、Identifier 等) + return self.packPos(node, self.visit(node)) + def visit_Module(self, node): self.sourcefile = node.sourcefile body = [] @@ -54,23 +313,8 @@ def visit_FunctionDef(self, node): id = UNode.Identifier(UNode.SourceLocation(), UNode.Meta(), node.name) id.loc = UNode.SourceLocation(UNode.Position(node.lineno, None), UNode.Position(node.lineno, None), self.sourcefile) - if isinstance(node.returns, ast.Name): - if node.returns.id == 'int' or node.returns.id == 'float': - return_type = self.packPos(node.returns, - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), 'PrimitiveType', - 'number', None)) - elif node.returns.id == 'str': - return_type = self.packPos(node.returns, - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), 'PrimitiveType', - 'string', None)) - elif node.returns.id == 'bool': - return_type = self.packPos(node.returns, - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), 'PrimitiveType', - 'boolean', None)) - else: - return_type = self.packPos(node.returns, self.visit(node.returns)) - else: - return_type = None + # 使用统一的类型注解解析方法,支持所有类型 + return_type = self._parse_type_annotation(node.returns) if node.returns is not None else None function_def = self.packPos(node, UNode.FunctionDefinition(UNode.SourceLocation(), UNode.Meta(), params, return_type, UNode.ScopedStatement(body_loc, UNode.Meta(), @@ -369,9 +613,8 @@ def visit_arguments(self, node): default_index = i - num_non_default # 计算默认值索引 default_value = self.packPos(node.defaults[default_index], self.visit(node.defaults[default_index])) - varType = UNode.DynamicType(UNode.SourceLocation(), UNode.Meta()) - if node.args[i].annotation is not None: - varType = self.packPos(node.args[i].annotation, self.visit(node.args[i].annotation)) + # 使用统一的类型注解解析方法,支持所有类型 + varType = self._parse_type_annotation(node.args[i].annotation) arg_id = self.visit(node.args[i]) var_decl = UNode.VariableDeclaration( @@ -852,77 +1095,8 @@ def visit_Starred(self, node): self.packPos(node.value, self.visit(node.value)))) def visit_AnnAssign(self, node): - vartype = UNode.DynamicType(UNode.SourceLocation(), UNode.Meta()) - if node.annotation is not None: - if isinstance(node.annotation, ast.Name): - if node.annotation.id == "float" or node.annotation.id == "int": - vartype = self.packPos(node.annotation, - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), "number")) - elif node.annotation.id == "str": - vartype = self.packPos(node.annotation, - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), "string")) - elif node.annotation.id == "bool": - vartype = self.packPos(node.annotation, - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), "boolean")) - elif isinstance(node.annotation, ast.Subscript): - keyType = valType = None - if isinstance(node.annotation.value, ast.Name): - if node.annotation.value.id == "dict": - if isinstance(node.annotation.slice, ast.Tuple): - if len(node.annotation.slice.elts) == 2: - if isinstance(node.annotation.slice.elts[0], ast.Name): - if node.annotation.slice.elts[0].id == "float" or node.annotation.slice.elts[ - 0].id == "int": - keyType = self.packPos(node.annotation.slice.elts[0], - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), - "number")) - elif node.annotation.slice.elts[0].id == "str": - keyType = self.packPos(node.annotation.slice.elts[0], - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), - "string")) - elif node.annotation.slice.elts[0].id == "bool": - keyType = self.packPos(node.annotation.slice.elts[0], - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), - "boolean")) - if isinstance(node.annotation.slice.elts[0], ast.Subscript): - if isinstance(node.annotation.slice.elts[0].value, ast.Name) and \ - node.annotation.slice.elts[0].value.id == 'tuple': - keyType = self.packPos(node.annotation.slice.elts[0], - UNode.ArrayType(UNode.SourceLocation(), UNode.Meta(), - UNode.Identifier(UNode.SourceLocation(), - UNode.Meta(), - node.annotation.slice.elts[ - 0].slice.elts[ - 0].id))) - if isinstance(node.annotation.slice.elts[1], ast.Name): - if node.annotation.slice.elts[1].id == "float" or node.annotation.slice.elts[ - 1].id == "int": - valType = self.packPos(node.annotation.slice.elts[1], - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), - "number")) - elif node.annotation.slice.elts[1].id == "str": - valType = self.packPos(node.annotation.slice.elts[1], - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), - "string")) - elif node.annotation.slice.elts[1].id == "bool": - valType = self.packPos(node.annotation.slice.elts[1], - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), - "boolean")) - vartype = UNode.MapType(UNode.SourceLocation(), UNode.Meta(), keyType, valType) - elif isinstance(node.annotation, ast.List): - eleType = None - if node.annotation.elts is not None and len(node.annotation.elts) > 0: - if isinstance(node.annotation.elts[0], ast.Name): - if node.annotation.elts[0].id == "float" or node.annotation.elts[0].id == "int": - eleType = self.packPos(node.annotation.elts[0], - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), "number")) - elif node.annotation.elts[0].id == "str": - eleType = self.packPos(node.annotation.elts[0], - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), "string")) - elif node.annotation.elts[0].id == "bool": - eleType = self.packPos(node.annotation.elts[0], - UNode.PrimitiveType(UNode.SourceLocation(), UNode.Meta(), "boolean")) - vartype = UNode.ArrayType(UNode.SourceLocation(), UNode.Meta(), eleType) + # 使用统一的类型注解解析方法 + vartype = self._parse_type_annotation(node.annotation) init = None if node.value is not None: