Add support for Callbacks
[platform/upstream/gobject-introspection.git] / giscanner / treebuilder.py
1 import giscanner
2
3
4 class Node(object):
5     pass
6
7
8 class Function(Node):
9     def __init__(self, name, retval, parameters, symbol):
10         self.name = name
11         self.retval = retval
12         self.parameters = parameters
13         self.symbol = symbol
14
15     def __repr__(self):
16         return 'Function(%r, %r, %r)' % (self.name, self.retval,
17                                          self.parameters)
18
19
20 class Parameter(Node):
21     def __init__(self, name, type):
22         self.name = name
23         self.type = type
24
25     def __repr__(self):
26         return 'Parameter(%r, %r)' % (self.name, self.type)
27
28
29 class Enum(Node):
30     def __init__(self, name, members):
31         self.name = name
32         self.members = members
33
34     def __repr__(self):
35         return 'Enum(%r, %r)' % (self.name, self.members)
36
37
38 class Member(Node):
39     def __init__(self, name, value):
40         self.name = name
41         self.value = value
42
43     def __repr__(self):
44         return 'Member(%r, %r)' % (self.name, self.value)
45
46
47 class Struct(Node):
48     def __init__(self, name):
49         self.name = name
50
51     def __repr__(self):
52         return 'Struct(%r)' % (self.name,)
53
54
55 class Return(Node):
56     def __init__(self, type):
57         self.type = type
58
59     def __repr__(self):
60         return 'Return(%r)' % (self.type,)
61
62
63 class Class(Node):
64     def __init__(self, name, parent):
65         self.name = name
66         self.parent = parent
67         self.methods = []
68         self.constructors = []
69         self.properties = []
70
71     def __repr__(self):
72         return '%s(%r, %r, %r)' % (
73             self.__class__.__name__,
74             self.name, self.parent, self.methods)
75
76
77 class Interface(Node):
78     def __init__(self, name):
79         self.name = name
80         self.methods = []
81         self.properties = []
82
83     def __repr__(self):
84         return '%s(%r, %r)' % (
85             self.__class__.__name__,
86             self.name, self.methods)
87
88
89 class Constant(Node):
90     def __init__(self, name, type, value):
91         self.name = name
92         self.type = type
93         self.value = value
94
95     def __repr__(self):
96         return 'Constant(%r, %r, %r)' % (
97             self.name, self.type, self.value)
98
99
100 class Property(Node):
101     def __init__(self, name, type):
102         self.name = name
103         self.type = type
104
105     def __repr__(self):
106         return '%s(%r, %r, %r)' % (
107             self.__class__.__name__,
108             self.name, self.type, self.value)
109
110
111 class Callback(Node):
112     def __init__(self, name, retval, parameters):
113         self.name = name
114         self.retval = retval
115         self.parameters = parameters
116
117     def __repr__(self):
118         return 'Callback(%r, %r, %r)' % (
119             self.name, self.retval, self.parameters)
120
121
122 class TreeBuilder(object):
123     def __init__(self, generator):
124         self.generator = generator
125         self.nodes = []
126
127         self._traverse()
128
129     def get_nodes(self):
130         for node in self.nodes:
131             yield node
132
133     def _traverse(self):
134         for symbol in self.generator.get_symbols():
135             node = self._traverse_one(symbol)
136             if node is not None:
137                 self.nodes.append(node)
138
139     def _traverse_one(self, symbol, stype=None):
140         # Skip private symbols
141         if symbol.ident.startswith('_'):
142             return
143         if stype is None:
144             stype = symbol.type
145         if stype == giscanner.CSYMBOL_TYPE_FUNCTION:
146             return self._create_function(symbol)
147         elif stype == giscanner.CSYMBOL_TYPE_TYPEDEF:
148             if (symbol.base_type.type == giscanner.CTYPE_POINTER and
149                 symbol.base_type.base_type.type == giscanner.CTYPE_FUNCTION):
150                 return self._create_callback(symbol)
151             else:
152                 return self._traverse_one(symbol, symbol.base_type.type)
153         elif stype == giscanner.CSYMBOL_TYPE_STRUCT:
154             return self._create_struct(symbol)
155         elif stype == giscanner.CSYMBOL_TYPE_ENUM:
156             return self._create_enum(symbol)
157         else:
158             print 'BUILDER: unhandled symbol', symbol.type
159
160     def _create_enum(self, symbol):
161         members = []
162         for child in symbol.base_type.child_list:
163             members.append(Member(child.ident,
164                                   child.const_int))
165
166         return Enum(symbol.ident, members)
167
168     def _create_function(self, symbol):
169         parameters = self._create_parameters(symbol.base_type)
170         retval = Return(self._create_source_type(symbol.base_type.base_type))
171         return Function(symbol.ident, retval, list(parameters), symbol.ident)
172
173     def _create_source_type(self, source_type):
174         if source_type.type == giscanner.CTYPE_VOID:
175             value = 'void'
176         elif source_type.type == giscanner.CTYPE_BASIC_TYPE:
177             value = source_type.name
178         elif source_type.type == giscanner.CTYPE_TYPEDEF:
179             value = source_type.name
180         elif source_type.type == giscanner.CTYPE_POINTER:
181             value = self._create_source_type(source_type.base_type) + '*'
182         else:
183             print 'BUILDER: Unhandled source type: %d' % (source_type.type,)
184             value = '???'
185         return value
186
187     def _create_parameters(self, base_type):
188         for child in base_type.child_list:
189             yield self._create_parameter(child)
190
191     def _create_parameter(self, symbol):
192         return Parameter(symbol.ident,
193                          self._create_source_type(symbol.base_type))
194
195     def _create_struct(self, symbol):
196         return Struct(symbol.ident)
197
198     def _create_callback(self, symbol):
199         parameters = self._create_parameters(symbol.base_type.base_type)
200         retval = Return(self._create_source_type(symbol.base_type.base_type.base_type))
201         return Callback(symbol.ident, retval, list(parameters))