Rework to use recursive XML
[gnome.gobject-introspection] / giscanner / ast.py
1 # -*- Mode: Python -*-
2 # GObject-Introspection - a framework for introspecting GObject libraries
3 # Copyright (C) 2008  Johan Dahlin
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 # 02110-1301, USA.
19 #
20
21 """AST nodes
22 This file descbribes abstract data type nodes independent on the
23 implementation language.
24
25 These can later on be extended (eg subclassed) with additional information
26 which is language/library/domain specific.
27 """
28
29 ##
30 ## Basic types, modeled on GITypeTag but not equivalent
31 ##
32
33 TYPE_NONE = 'none' # We differ from repository on these first two
34 TYPE_ANY = 'any'
35 TYPE_BOOLEAN = 'boolean'
36 TYPE_INT8 = 'int8'
37 TYPE_UINT8 = 'uint8'
38 TYPE_INT16 = 'int16'
39 TYPE_UINT16 = 'uint16'
40 TYPE_INT = 'int'
41 TYPE_UINT = 'uint'
42 TYPE_INT32 = 'int32'
43 TYPE_UINT32 = 'uint32'
44 TYPE_INT64 = 'int64'
45 TYPE_UINT64 = 'uint64'
46 TYPE_LONG = 'long'
47 TYPE_ULONG = 'ulong'
48 TYPE_SSIZET = 'ssize_t'
49 TYPE_SIZET = 'size_t'
50 TYPE_TIMET = 'time_t'
51 TYPE_FLOAT = 'float'
52 TYPE_DOUBLE = 'double'
53 TYPE_STRING = 'utf8' # requires zero-terminated
54 TYPE_FILENAME = 'filename'
55
56 BASIC_GIR_TYPES = [TYPE_BOOLEAN, TYPE_INT8, TYPE_UINT8, TYPE_INT16,
57                    TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_INT64,
58                    TYPE_UINT64, TYPE_INT, TYPE_UINT, TYPE_LONG,
59                    TYPE_ULONG, TYPE_SSIZET, TYPE_SIZET, TYPE_FLOAT,
60                    TYPE_DOUBLE, TYPE_TIMET]
61 GIR_TYPES = [TYPE_NONE, TYPE_ANY]
62 GIR_TYPES.extend(BASIC_GIR_TYPES)
63 GIR_TYPES.extend([TYPE_STRING, TYPE_FILENAME])
64
65 # Higher-level data types
66 TYPE_SEQUENCE = 'sequence' # Sequence of something
67
68 # Wide/Unicode
69 TYPE_UCHAR = 'uchar'
70 TYPE_USTRING = 'ustring'
71
72 ##
73 ## Parameters
74 ##
75
76 PARAM_DIRECTION_IN = 'in'
77 PARAM_DIRECTION_OUT = 'out'
78 PARAM_DIRECTION_INOUT = 'inout'
79
80 type_names = {}
81 for name in GIR_TYPES:
82     type_names[name] = name
83
84 # C
85 type_names['char'] = TYPE_INT8
86 type_names['unsigned char'] = TYPE_UINT8
87 type_names['short'] = TYPE_INT16
88 type_names['unsigned short'] = TYPE_UINT16
89 type_names['int'] = TYPE_INT
90 type_names['unsigned int'] = TYPE_UINT
91 type_names['long'] = TYPE_LONG
92 type_names['unsigned long'] = TYPE_ULONG
93 type_names['float'] = TYPE_FLOAT
94 type_names['double'] = TYPE_DOUBLE
95 type_names['char*'] = TYPE_STRING
96 type_names['void*'] = TYPE_ANY
97 type_names['void'] = TYPE_NONE
98 type_names['size_t'] = TYPE_SIZET
99 type_names['ssize_t'] = TYPE_SSIZET
100 # FIXME - can we make libraries use GPid?
101 type_names['pid_t'] = TYPE_INT
102
103 # Suppress some GLib names
104 type_names['uchar'] = TYPE_UINT8
105 type_names['ushort'] = TYPE_UINT16
106 type_names['size'] = TYPE_SIZET
107 type_names['ssize'] = TYPE_SSIZET
108 type_names['pointer'] = TYPE_ANY
109 type_names['constpointer'] = TYPE_ANY
110
111
112 # These types, when seen by reference, are converted into an Array()
113 # by default
114 default_array_types = {}
115 default_array_types['uint8*'] = TYPE_UINT8
116 default_array_types['char**'] = TYPE_STRING
117
118
119 def type_name_from_ctype(ctype):
120     return type_names.get(ctype, ctype)
121
122
123 class Node(object):
124
125     def __init__(self, name=None):
126         self.name = name
127         self.deprecated = None
128         self.deprecated_version = None
129
130     def __repr__(self):
131         return '%s(%r)' % (self.__class__.__name__, self.name)
132
133
134 class Namespace(Node):
135
136     def __init__(self, name):
137         Node.__init__(self, name)
138         self.nodes = []
139
140     def __repr__(self):
141         return '%s(%r, %r)' % (self.__class__.__name__, self.name,
142                                self.nodes)
143
144
145 class Function(Node):
146
147     def __init__(self, name, retval, parameters, symbol):
148         Node.__init__(self, name)
149         self.retval = retval
150         self.parameters = parameters
151         self.symbol = symbol
152
153     def __repr__(self):
154         return '%s(%r, %r, %r)' % (self.__class__.__name__,
155                                    self.name, self.retval,
156                                    self.parameters)
157
158
159 class VFunction(Function):
160     pass
161
162
163 class Type(Node):
164
165     def __init__(self, name, ctype=None):
166         Node.__init__(self, name)
167         self.ctype = ctype
168         self.resolved = False
169
170
171 class Array(Type):
172
173     def __init__(self, ctype, element_type):
174         Type.__init__(self, '<carray>', ctype)
175         self.element_type = element_type
176         self.zeroterminated = True
177         self.length_param_index = -1
178
179     def __repr__(self):
180         return 'Array(%r of %r)' % (self.name, self.element_type, )
181
182
183 class List(Type):
184
185     def __init__(self, name, ctype, element_type):
186         Type.__init__(self, name, ctype)
187         self.element_type = element_type
188
189     def __repr__(self):
190         return 'List(%r of %r)' % (self.name, self.element_type, )
191
192
193 class Map(Type):
194
195     def __init__(self, name, ctype, key_type, value_type):
196         Type.__init__(self, name, ctype)
197         self.key_type = key_type
198         self.value_type = value_type
199
200     def __repr__(self):
201         return 'Map(%r <%r,%r.)' % (self.name, self.key_type, self.value_type)
202
203
204 class Alias(Node):
205
206     def __init__(self, name, target, ctype=None):
207         Node.__init__(self, name)
208         self.target = target
209         self.ctype = ctype
210
211     def __repr__(self):
212         return 'Alias(%r, %r)' % (self.name, self.target)
213
214
215 class Parameter(Node):
216
217     def __init__(self, name, typenode):
218         Node.__init__(self, name)
219         self.type = typenode
220         self.direction = PARAM_DIRECTION_IN
221         self.transfer = False
222         self.allow_none = False
223
224     def __repr__(self):
225         return 'Parameter(%r, %r)' % (self.name, self.type)
226
227
228 class Enum(Node):
229
230     def __init__(self, name, symbol, members):
231         Node.__init__(self, name)
232         self.symbol = symbol
233         self.members = members
234
235     def __repr__(self):
236         return 'Enum(%r, %r)' % (self.name, self.members)
237
238
239 class Member(Node):
240
241     def __init__(self, name, value, symbol):
242         Node.__init__(self, name)
243         self.value = value
244         self.symbol = symbol
245
246     def __repr__(self):
247         return 'Member(%r, %r)' % (self.name, self.value)
248
249
250 class Struct(Node):
251
252     def __init__(self, name, symbol):
253         Node.__init__(self, name)
254         self.fields = []
255         self.symbol = symbol
256
257
258 class Field(Node):
259
260     def __init__(self, name, typenode, symbol):
261         Node.__init__(self, name)
262         self.type = typenode
263         self.symbol = symbol
264
265     def __repr__(self):
266         return 'Field(%r, %r)' % (self.name, self.type)
267
268
269 class Return(Node):
270
271     def __init__(self, rtype):
272         Node.__init__(self)
273         self.type = rtype
274         self.transfer = isinstance(rtype, (List, Map, Array)) or \
275             rtype.name in ('utf8', 'filename')
276
277     def __repr__(self):
278         return 'Return(%r)' % (self.type, )
279
280
281 class Class(Node):
282
283     def __init__(self, name, parent):
284         Node.__init__(self, name)
285         self.ctype = name
286         self.parent = parent
287         self.methods = []
288         self.interfaces = []
289         self.constructors = []
290         self.properties = []
291         self.fields = []
292
293     def __repr__(self):
294         return '%s(%r, %r, %r)' % (
295             self.__class__.__name__,
296             self.name, self.parent, self.methods)
297
298
299 class Interface(Node):
300
301     def __init__(self, name, parent):
302         Node.__init__(self, name)
303         self.parent = parent
304         self.methods = []
305         self.properties = []
306         self.fields = []
307
308     def __repr__(self):
309         return '%s(%r, %r)' % (
310             self.__class__.__name__,
311             self.name, self.methods)
312
313
314 class Constant(Node):
315
316     def __init__(self, name, type_name, value):
317         Node.__init__(self, name)
318         self.type = Type(type_name)
319         self.value = value
320
321     def __repr__(self):
322         return 'Constant(%r, %r, %r)' % (
323             self.name, self.type, self.value)
324
325
326 class Property(Node):
327
328     def __init__(self, name, type_name, readable, writable,
329                  construct, construct_only, ctype=None):
330         Node.__init__(self, name)
331         self.type = Type(type_name, ctype)
332         self.readable = readable
333         self.writable = writable
334         self.construct = construct
335         self.construct_only = construct_only
336
337     def __repr__(self):
338         return '%s(%r, %r, %r)' % (
339             self.__class__.__name__,
340             self.name, self.type, self.value)
341
342
343 # FIXME: Inherit from Function
344
345
346 class Callback(Node):
347
348     def __init__(self, name, retval, parameters, ctype=None):
349         Node.__init__(self, name)
350         self.retval = retval
351         self.parameters = parameters
352         self.ctype = ctype
353
354     def __repr__(self):
355         return 'Callback(%r, %r, %r)' % (
356             self.name, self.retval, self.parameters)
357
358
359 class Union(Node):
360
361     def __init__(self, name, symbol):
362         Node.__init__(self, name)
363         self.fields = []
364         self.symbol = symbol
365
366     def __repr__(self):
367         return 'Union(%r, %r)' % (self.name, self.fields, )