File: namespace_node.py

package info (click to toggle)
opencv 4.10.0%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 282,092 kB
  • sloc: cpp: 1,178,079; xml: 682,621; python: 49,092; lisp: 31,150; java: 25,469; ansic: 11,039; javascript: 6,085; sh: 1,214; cs: 601; perl: 494; objc: 210; makefile: 173
file content (113 lines) | stat: -rw-r--r-- 4,375 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import itertools
import weakref
from collections import defaultdict
from typing import Dict, List, Optional, Sequence, Tuple

from .class_node import ClassNode, ClassProperty
from .constant_node import ConstantNode
from .enumeration_node import EnumerationNode
from .function_node import FunctionNode
from .node import ASTNode, ASTNodeType
from .type_node import TypeResolutionError


class NamespaceNode(ASTNode):
    """Represents C++ namespace that treated as module in Python.

    NamespaceNode can have other namespaces, classes, functions, enumerations
    and global constants as its children nodes.
    """
    def __init__(self, name: str, parent: Optional[ASTNode] = None,
                 export_name: Optional[str] = None) -> None:
        super().__init__(name, parent, export_name)
        self.reexported_submodules: List[str] = []
        """List of reexported submodules"""

        self.reexported_submodules_symbols: Dict[str, List[str]] = defaultdict(list)
        """Mapping between submodules export names and their symbols re-exported
        in this module"""


    @property
    def node_type(self) -> ASTNodeType:
        return ASTNodeType.Namespace

    @property
    def children_types(self) -> Tuple[ASTNodeType, ...]:
        return (ASTNodeType.Namespace, ASTNodeType.Class, ASTNodeType.Function,
                ASTNodeType.Enumeration, ASTNodeType.Constant)

    @property
    def namespaces(self) -> Dict[str, "NamespaceNode"]:
        return self._children[ASTNodeType.Namespace]

    @property
    def classes(self) -> Dict[str, ClassNode]:
        return self._children[ASTNodeType.Class]

    @property
    def functions(self) -> Dict[str, FunctionNode]:
        return self._children[ASTNodeType.Function]

    @property
    def enumerations(self) -> Dict[str, EnumerationNode]:
        return self._children[ASTNodeType.Enumeration]

    @property
    def constants(self) -> Dict[str, ConstantNode]:
        return self._children[ASTNodeType.Constant]

    def add_namespace(self, name: str) -> "NamespaceNode":
        return self._add_child(NamespaceNode, name)

    def add_class(self, name: str,
                  bases: Sequence["weakref.ProxyType[ClassNode]"] = (),
                  properties: Sequence[ClassProperty] = ()) -> "ClassNode":
        return self._add_child(ClassNode, name, bases=bases,
                               properties=properties)

    def add_function(self, name: str, arguments: Sequence[FunctionNode.Arg] = (),
                     return_type: Optional[FunctionNode.RetType] = None) -> FunctionNode:
        return self._add_child(FunctionNode, name, arguments=arguments,
                               return_type=return_type)

    def add_enumeration(self, name: str) -> EnumerationNode:
        return self._add_child(EnumerationNode, name)

    def add_constant(self, name: str, value: str) -> ConstantNode:
        return self._add_child(ConstantNode, name, value=value)

    def resolve_type_nodes(self, root: Optional[ASTNode] = None) -> None:
        """Resolves type nodes for all children nodes in 2 steps:
            1. Resolve against `self` as a tree root
            2. Resolve against `root` as a tree root
        Type resolution errors are postponed until all children nodes are
        examined.

        Args:
            root (Optional[ASTNode], optional): Root of the AST sub-tree.
                Defaults to None.
        """
        errors = []
        for child in itertools.chain(self.functions.values(),
                                     self.classes.values(),
                                     self.namespaces.values()):
            try:
                try:
                    child.resolve_type_nodes(self)  # type: ignore
                except TypeResolutionError:
                    if root is not None:
                        child.resolve_type_nodes(root)  # type: ignore
                    else:
                        raise
            except TypeResolutionError as e:
                errors.append(str(e))
        if len(errors) > 0:
            raise TypeResolutionError(
                'Failed to resolve "{}" namespace against "{}". '
                'Errors: {}'.format(
                    self.full_export_name,
                    root if root is None else root.full_export_name,
                    errors
                )
            )