f4bc05c7ae97b2c54519a31984847d776fff7363
[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_GTYPE = 'GType'
52 TYPE_FLOAT = 'float'
53 TYPE_DOUBLE = 'double'
54 TYPE_STRING = 'utf8' # requires zero-terminated
55 TYPE_FILENAME = 'filename'
56
57 BASIC_GIR_TYPES = [TYPE_BOOLEAN, TYPE_INT8, TYPE_UINT8, TYPE_INT16,
58                    TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_INT64,
59                    TYPE_UINT64, TYPE_INT, TYPE_UINT, TYPE_LONG,
60                    TYPE_ULONG, TYPE_SSIZET, TYPE_SIZET, TYPE_FLOAT,
61                    TYPE_DOUBLE, TYPE_TIMET, TYPE_GTYPE]
62 GIR_TYPES = [TYPE_NONE, TYPE_ANY]
63 GIR_TYPES.extend(BASIC_GIR_TYPES)
64 GIR_TYPES.extend([TYPE_STRING, TYPE_FILENAME])
65
66 # Higher-level data types
67 TYPE_SEQUENCE = 'sequence' # Sequence of something
68
69 # Wide/Unicode
70 TYPE_UCHAR = 'uchar'
71 TYPE_USTRING = 'ustring'
72
73 ##
74 ## Parameters
75 ##
76
77 PARAM_DIRECTION_IN = 'in'
78 PARAM_DIRECTION_OUT = 'out'
79 PARAM_DIRECTION_INOUT = 'inout'
80
81 type_names = {}
82 for name in GIR_TYPES:
83     type_names[name] = name
84
85 # C
86 type_names['char'] = TYPE_INT8
87 type_names['signed char'] = TYPE_INT8
88 type_names['unsigned char'] = TYPE_UINT8
89 type_names['short'] = TYPE_INT16
90 type_names['signed short'] = TYPE_INT16
91 type_names['unsigned short'] = TYPE_UINT16
92 type_names['int'] = TYPE_INT
93 type_names['signed int'] = TYPE_INT
94 type_names['signed'] = TYPE_INT
95 type_names['unsigned int'] = TYPE_UINT
96 type_names['unsigned'] = TYPE_UINT
97 type_names['long'] = TYPE_LONG
98 type_names['signed long'] = TYPE_LONG
99 type_names['unsigned long'] = TYPE_ULONG
100 type_names['float'] = TYPE_FLOAT
101 type_names['double'] = TYPE_DOUBLE
102 type_names['char*'] = TYPE_STRING
103 type_names['void*'] = TYPE_ANY
104 type_names['void'] = TYPE_NONE
105 type_names['size_t'] = TYPE_SIZET
106 type_names['ssize_t'] = TYPE_SSIZET
107 type_names['off_t'] = TYPE_SIZET
108 # FIXME - can we make libraries use GPid?
109 type_names['pid_t'] = TYPE_INT
110
111 # Suppress some GLib names
112 type_names['uchar'] = TYPE_UINT8
113 type_names['ushort'] = TYPE_UINT16
114 type_names['size'] = TYPE_SIZET
115 type_names['ssize'] = TYPE_SSIZET
116 type_names['pointer'] = TYPE_ANY
117 type_names['constpointer'] = TYPE_ANY
118
119
120 # These types, when seen by reference, are converted into an Array()
121 # by default
122 default_array_types = {}
123 default_array_types['uint8*'] = TYPE_UINT8
124 default_array_types['char**'] = TYPE_STRING
125
126 # These types, when seen by reference, are interpreted as out parameters
127 default_out_types = (TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
128                      TYPE_FLOAT, TYPE_DOUBLE)
129
130
131 def type_name_from_ctype(ctype):
132     return type_names.get(ctype, ctype)
133
134
135 class Node(object):
136
137     def __init__(self, name=None):
138         self.name = name
139         self.deprecated = None
140         self.deprecated_version = None
141
142     def __repr__(self):
143         return '%s(%r)' % (self.__class__.__name__, self.name)
144
145
146 class Namespace(Node):
147
148     def __init__(self, name, version):
149         Node.__init__(self, name)
150         self.version = version
151         self.nodes = []
152
153     def __repr__(self):
154         return '%s(%r, %r, %r)' % (self.__class__.__name__, self.name,
155                                    self.version, self.nodes)
156
157
158 class Include(Node):
159
160     def __init__(self, name, version):
161         Node.__init__(self, 'include')
162         self.name = name
163         self.version = version
164
165     @classmethod
166     def from_string(self, string):
167         return Include(*string.split('-', 1))
168
169     def __cmp__(self, other):
170         if not isinstance(other, Include):
171             return cmp(self, other)
172         namecmp = cmp(self.name, other.name)
173         if namecmp != 0:
174             return namecmp
175         return cmp(self.version, other.version)
176
177     def __hash__(self):
178         return hash((self.name, self.version))
179
180     def __str__(self):
181         return '%s-%s' % (self.name, self.version)
182
183
184 class Function(Node):
185
186     def __init__(self, name, retval, parameters, symbol):
187         Node.__init__(self, name)
188         self.retval = retval
189         self.parameters = parameters
190         self.symbol = symbol
191
192     def __repr__(self):
193         return '%s(%r, %r, %r)' % (self.__class__.__name__,
194                                    self.name, self.retval,
195                                    self.parameters)
196
197
198 class VFunction(Function):
199     pass
200
201
202 class Type(Node):
203
204     def __init__(self, name, ctype=None):
205         Node.__init__(self, name)
206         self.ctype = ctype
207         self.resolved = False
208
209
210 class Varargs(Type):
211
212     def __init__(self):
213         Type.__init__(self, '<varargs>')
214
215
216 class Array(Type):
217
218     def __init__(self, ctype, element_type):
219         Type.__init__(self, '<carray>', ctype)
220         self.element_type = element_type
221         self.zeroterminated = True
222         self.length_param_index = -1
223         self.length_param_name = None
224
225     def __repr__(self):
226         return 'Array(%r of %r)' % (self.name, self.element_type, )
227
228
229 class List(Type):
230
231     def __init__(self, name, ctype, element_type):
232         Type.__init__(self, name, ctype)
233         self.element_type = element_type
234
235     def __repr__(self):
236         return 'List(%r of %r)' % (self.name, self.element_type, )
237
238
239 class Map(Type):
240
241     def __init__(self, name, ctype, key_type, value_type):
242         Type.__init__(self, name, ctype)
243         self.key_type = key_type
244         self.value_type = value_type
245
246     def __repr__(self):
247         return 'Map(%r <%r,%r.)' % (self.name, self.key_type, self.value_type)
248
249
250 class Alias(Node):
251
252     def __init__(self, name, target, ctype=None):
253         Node.__init__(self, name)
254         self.target = target
255         self.ctype = ctype
256
257     def __repr__(self):
258         return 'Alias(%r, %r)' % (self.name, self.target)
259
260
261 class Parameter(Node):
262
263     def __init__(self, name, typenode):
264         Node.__init__(self, name)
265         self.type = typenode
266         self.direction = PARAM_DIRECTION_IN
267         self.transfer = None
268         self.allow_none = False
269
270     def __repr__(self):
271         return 'Parameter(%r, %r)' % (self.name, self.type)
272
273
274 class Enum(Node):
275
276     def __init__(self, name, symbol, members):
277         Node.__init__(self, name)
278         self.symbol = symbol
279         self.members = members
280
281     def __repr__(self):
282         return 'Enum(%r, %r)' % (self.name, self.members)
283
284
285 class Member(Node):
286
287     def __init__(self, name, value, symbol):
288         Node.__init__(self, name)
289         self.value = value
290         self.symbol = symbol
291
292     def __repr__(self):
293         return 'Member(%r, %r)' % (self.name, self.value)
294
295
296 class Struct(Node):
297
298     def __init__(self, name, symbol):
299         Node.__init__(self, name)
300         self.fields = []
301         self.constructors = []
302         self.symbol = symbol
303
304
305 class Field(Node):
306
307     def __init__(self, name, typenode, symbol, bits=None):
308         Node.__init__(self, name)
309         self.type = typenode
310         self.symbol = symbol
311         self.bits = bits
312
313     def __repr__(self):
314         if self.bits:
315             return 'Field(%r, %r, %r)' % (self.name, self.type, self.bits)
316         else:
317             return 'Field(%r, %r)' % (self.name, self.type)
318
319
320 class Return(Node):
321
322     def __init__(self, rtype, transfer=None):
323         Node.__init__(self)
324         self.type = rtype
325         if transfer is None and rtype.name in ['utf8', 'filename']:
326             self.transfer = 'full'
327         else:
328             self.transfer = transfer
329
330     def __repr__(self):
331         return 'Return(%r)' % (self.type, )
332
333
334 class Class(Node):
335
336     def __init__(self, name, parent):
337         Node.__init__(self, name)
338         self.ctype = name
339         self.parent = parent
340         self.methods = []
341         self.interfaces = []
342         self.constructors = []
343         self.properties = []
344         self.fields = []
345
346     def __repr__(self):
347         return '%s(%r, %r, %r)' % (
348             self.__class__.__name__,
349             self.name, self.parent, self.methods)
350
351
352 class Interface(Node):
353
354     def __init__(self, name, parent):
355         Node.__init__(self, name)
356         self.parent = parent
357         self.methods = []
358         self.properties = []
359         self.fields = []
360
361     def __repr__(self):
362         return '%s(%r, %r)' % (
363             self.__class__.__name__,
364             self.name, self.methods)
365
366
367 class Constant(Node):
368
369     def __init__(self, name, type_name, value):
370         Node.__init__(self, name)
371         self.type = Type(type_name)
372         self.value = value
373
374     def __repr__(self):
375         return 'Constant(%r, %r, %r)' % (
376             self.name, self.type, self.value)
377
378
379 class Property(Node):
380
381     def __init__(self, name, type_name, readable, writable,
382                  construct, construct_only, ctype=None):
383         Node.__init__(self, name)
384         self.type = Type(type_name, ctype)
385         self.readable = readable
386         self.writable = writable
387         self.construct = construct
388         self.construct_only = construct_only
389
390     def __repr__(self):
391         return '%s(%r, %r, %r)' % (
392             self.__class__.__name__,
393             self.name, self.type, self.value)
394
395
396 # FIXME: Inherit from Function
397
398
399 class Callback(Node):
400
401     def __init__(self, name, retval, parameters, ctype=None):
402         Node.__init__(self, name)
403         self.retval = retval
404         self.parameters = parameters
405         self.ctype = ctype
406
407     def __repr__(self):
408         return 'Callback(%r, %r, %r)' % (
409             self.name, self.retval, self.parameters)
410
411
412 class Union(Node):
413
414     def __init__(self, name, symbol):
415         Node.__init__(self, name)
416         self.fields = []
417         self.constructors = []
418         self.symbol = symbol
419
420     def __repr__(self):
421         return 'Union(%r, %r)' % (self.name, self.fields, )