44from clang_bind .clang_utils import ClangUtils
55
66
7- class Node :
7+ class ParsedInfo :
8+ """This is a data holder class containing parsed info, to be used while constructing the tree.
9+
10+ :param cursor: An object of :class:`clang.cindex.Cursor`
11+ :type cursor: class:`clang.cindex.Cursor`
12+ :param verbose: Add additional information about the cursor, defaults to False
13+ :type verbose: bool, optional
14+ """
15+
816 def __init__ (self , cursor , verbose = False ):
917 self .cursor = cursor
1018 if verbose :
@@ -19,11 +27,16 @@ def __repr__(self) -> str:
1927
2028
2129class Parse :
22- """
23- Class to parse a file and generate an AST from it.
30+ """This is a class which parses a file and generate an abstract syntax tree from it.
31+
32+ :param file: File to parse
33+ :type file: str
34+ :param compiler_arguments: Compiler arguments to use while parsing
35+ :type compiler_arguments: list, optional
2436 """
2537
26- def __init__ (self , file , compiler_arguments ):
38+ def __init__ (self , file , compiler_arguments = []):
39+ self ._parsed_info_map = {}
2740 index = clang .Index .create ()
2841 """
2942 - Why parse using the option `PARSE_DETAILED_PROCESSING_RECORD`?
@@ -38,40 +51,124 @@ def __init__(self, file, compiler_arguments):
3851 )
3952 self .filename = source_ast .spelling
4053 self .tree = Tree ()
41- self .root_node = self .tree .create_node (
42- identifier = Node (source_ast .cursor ), tag = repr (Node (source_ast .cursor ))
43- )
54+ parsed_info = ParsedInfo (source_ast .cursor )
55+ self .root_node = self .tree .create_node (tag = repr (parsed_info ))
56+ self ._parsed_info_map [self .root_node .identifier ] = parsed_info
57+ self ._construct_tree (self .root_node )
4458
4559 @staticmethod
46- def is_node_from_file (node , filename ):
47- """
48- Check if the node belongs in the file.
60+ def is_cursor_in_file (cursor , filename ):
61+ """Checks if the cursor belongs in the file.
62+
63+ :param cursor: An object of :class:`clang.cindex.Cursor`
64+ :type cursor: class:`clang.cindex.Cursor`
65+ :param filename: Filename to search the cursor
66+ :type filename: str
67+ :return: `True` if cursor in file, else `False`
68+ :rtype: bool
4969 """
50- return node .location .file and node .location .file .name == filename
70+ return cursor .location .file and cursor .location .file .name == filename
5171
5272 def _is_valid_child (self , child_cursor ):
73+ """Checks if the child is valid (child should be in the same file as the parent).
74+
75+ :param child_cursor: The child cursor to check, an object of :class:`clang.cindex.Cursor`
76+ :type child_cursor: class:`clang.cindex.Cursor`
77+ :return: `True` if child cursor in file, else `False`
78+ :rtype: bool
5379 """
54- Check if the child is valid (child should be in the same file as the parent).
55- """
56- return self .is_node_from_file (child_cursor , self .filename )
80+ return self .is_cursor_in_file (child_cursor , self .filename )
5781
5882 def _construct_tree (self , node ):
83+ """Recursively generates tree by traversing the AST of the node.
84+
85+ :param node: An object of :class:`treelib.Node`
86+ :type node: class:`treelib.Node`
5987 """
60- Recursively generates tree by traversing the AST of the node.
61- """
62- cursor = node .identifier .cursor
88+ cursor = self .get_parsed_info_from_node_id (node .identifier ).cursor
6389 for child_cursor in cursor .get_children ():
6490 if self ._is_valid_child (child_cursor ):
91+ parsed_info = ParsedInfo (child_cursor )
6592 child_node = self .tree .create_node (
66- identifier = Node (child_cursor ),
6793 parent = node ,
68- tag = repr (Node ( child_cursor ) ),
94+ tag = repr (parsed_info ),
6995 )
96+ self ._parsed_info_map [child_node .identifier ] = parsed_info
7097 self ._construct_tree (child_node )
7198
7299 def get_tree (self ):
100+ """Returns the constructed AST.
101+
102+ :return: Constructed AST
103+ :rtype: class:`treelib.Tree`
73104 """
74- Returns the constructed tree.
75- """
76- self ._construct_tree (self .root_node )
77105 return self .tree
106+
107+ def get_node_id_from_parsed_info (self , parsed_info ):
108+ """Returns node identifier by performing a value based search of `_parsed_info_map`.
109+
110+ :param parsed_info: An object of :class:`clang_bind.parse.ParsedInfo`
111+ , the value to get the corresponding key from `_parsed_info_map`
112+ :type parsed_info`: class:`clang_bind.parse.ParsedInfo`
113+ :return node_id: Node identifier corresponding to `parsed_info`
114+ :rtype: `treelib.Tree.identifier`
115+ """
116+ for node_id , parsed_info_ in self ._parsed_info_map .items ():
117+ if parsed_info_ == parsed_info :
118+ return node_id
119+
120+ def get_children_nodes_from_parent_parsed_info (self , parent_parsed_info ):
121+ """Returns a list of children nodes from parent parsed infos.
122+
123+ :param parent_parsed_info: The parent object of :class:`clang_bind.parse.ParsedInfo`
124+ :type parent_parsed_info: class:`clang_bind.parse.ParsedInfo`
125+ :return: Children nodes of :class:`treelib.Node`
126+ :rtype: list
127+ """
128+ return self .tree .children (self .get_node_id_from_parsed_info (parent_parsed_info ))
129+
130+ def get_parsed_infos_from_node_ids (self , node_ids ):
131+ """Returns a list of parsed infos from a list of node identifiers
132+ , by getting the values from `_parsed_info_map`
133+
134+ :param node_ids: Node identifiers of :class:`treelib.Node`
135+ :type node_ids: list
136+ :return: Parsed infos of :class:`clang_bind.parse.ParsedInfo`
137+ :rtype: list
138+ """
139+ return list (map (lambda node_id : self ._parsed_info_map .get (node_id ), node_ids ))
140+
141+ def get_parsed_info_from_node_id (self , node_id ):
142+ """Returns parsed info from node identifier, by getting the value from `_parsed_info_map`
143+
144+ :param node_id: Node identifier
145+ :type node_id: class:`treelib.Node`
146+ :return: Parsed info corresponding to `node_id`
147+ :rtype: class:`clang_bind.parse.ParsedInfo`
148+ """
149+ return self .get_parsed_infos_from_node_ids ([node_id ])[0 ]
150+
151+ @staticmethod
152+ def get_node_ids_from_nodes (nodes ):
153+ """Returns a list of node identifiers from a list of nodes.
154+
155+ :param nodes: A list of objects of :class:`treelib.Node`
156+ :type nodes: class:`treelib.Node`
157+ :return: A list of node identifiers of `treelib.Tree.identifier`
158+ :rtype: list
159+ """
160+ return list (map (lambda node : node .identifier , nodes ))
161+
162+ def get_children_parsed_infos_from_parent_parsed_info (self , parent_parsed_info ):
163+ """Returns children parsed infos from parent parsed infos.
164+
165+ :param parent_parsed_info: The parent object of :class:`clang_bind.parse.ParsedInfo`
166+ :type parent_parsed_info: class:`clang_bind.parse.ParsedInfo`
167+ :return: Children parsed infos of :class:`clang_bind.parse.ParsedInfo`
168+ :rtype: list
169+ """
170+ return self .get_parsed_infos_from_node_ids (
171+ self .get_node_ids_from_nodes (
172+ self .get_children_nodes_from_parent_parsed_info (parent_parsed_info )
173+ )
174+ )
0 commit comments