Define socklen_t as an alias for int32.
[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 library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2 of the License, or (at your option) any later version.
9 #
10 # This library 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 GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the
17 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 # Boston, MA 02111-1307, 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 PARAM_TRANSFER_NONE = 'none'
82 PARAM_TRANSFER_CONTAINER = 'container'
83 PARAM_TRANSFER_FULL = 'full'
84
85 type_names = {}
86 for name in GIR_TYPES:
87     type_names[name] = name
88
89 # C builtin
90 type_names['char'] = TYPE_INT8
91 type_names['signed char'] = TYPE_INT8
92 type_names['unsigned char'] = TYPE_UINT8
93 type_names['short'] = TYPE_INT16
94 type_names['signed short'] = TYPE_INT16
95 type_names['unsigned short'] = TYPE_UINT16
96 type_names['int'] = TYPE_INT
97 type_names['signed int'] = TYPE_INT
98 type_names['signed'] = TYPE_INT
99 type_names['unsigned int'] = TYPE_UINT
100 type_names['unsigned'] = TYPE_UINT
101 type_names['long'] = TYPE_LONG
102 type_names['signed long'] = TYPE_LONG
103 type_names['unsigned long'] = TYPE_ULONG
104 type_names['float'] = TYPE_FLOAT
105 type_names['double'] = TYPE_DOUBLE
106 type_names['char*'] = TYPE_STRING
107 type_names['void*'] = TYPE_ANY
108 type_names['void'] = TYPE_NONE
109
110 # C unix types
111 type_names['off_t'] = TYPE_SIZET
112 type_names['pid_t'] = TYPE_INT
113 type_names['size_t'] = TYPE_SIZET
114 type_names['ssize_t'] = TYPE_SSIZET
115 type_names['socklen_t'] = TYPE_INT32
116
117 # Obj-C
118 type_names['id'] = TYPE_ANY
119
120 # Suppress some GLib names
121 type_names['uchar'] = TYPE_UINT8
122 type_names['ushort'] = TYPE_UINT16
123 type_names['size'] = TYPE_SIZET
124 type_names['ssize'] = TYPE_SSIZET
125 type_names['pointer'] = TYPE_ANY
126 type_names['constpointer'] = TYPE_ANY
127
128
129 # These types, when seen by reference, are converted into an Array()
130 # by default
131 # If you add/change these, be sure to update glibast.py too
132 default_array_types = {}
133 default_array_types['uint8*'] = TYPE_UINT8
134 default_array_types['utf8*'] = TYPE_STRING
135
136 # These types, when seen by reference, are interpreted as out parameters
137 default_out_types = (TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
138                      TYPE_FLOAT, TYPE_DOUBLE, TYPE_SIZET, TYPE_SSIZET)
139
140
141 def type_name_from_ctype(ctype):
142     return type_names.get(ctype, ctype)
143
144
145 class Node(object):
146
147     def __init__(self, name=None):
148         self.name = name
149         self.deprecated = None
150         self.deprecated_version = None
151
152     def __repr__(self):
153         return '%s(%r)' % (self.__class__.__name__, self.name)
154
155
156 class Namespace(Node):
157
158     def __init__(self, name, version):
159         Node.__init__(self, name)
160         self.version = version
161         self.nodes = []
162
163     def __repr__(self):
164         return '%s(%r, %r, %r)' % (self.__class__.__name__, self.name,
165                                    self.version, self.nodes)
166
167
168 class Include(Node):
169
170     def __init__(self, name, version):
171         Node.__init__(self, 'include')
172         self.name = name
173         self.version = version
174
175     @classmethod
176     def from_string(self, string):
177         return Include(*string.split('-', 1))
178
179     def __cmp__(self, other):
180         if not isinstance(other, Include):
181             return cmp(self, other)
182         namecmp = cmp(self.name, other.name)
183         if namecmp != 0:
184             return namecmp
185         return cmp(self.version, other.version)
186
187     def __hash__(self):
188         return hash((self.name, self.version))
189
190     def __str__(self):
191         return '%s-%s' % (self.name, self.version)
192
193
194 class Function(Node):
195
196     def __init__(self, name, retval, parameters, symbol, throws=None):
197         Node.__init__(self, name)
198         self.retval = retval
199         self.parameters = parameters
200         self.symbol = symbol
201         self.throws = not not throws
202
203     def __repr__(self):
204         return '%s(%r, %r, %r)' % (self.__class__.__name__,
205                                    self.name, self.retval,
206                                    self.parameters)
207
208
209 class VFunction(Function):
210     pass
211
212
213 class Type(Node):
214
215     def __init__(self, name, ctype=None):
216         Node.__init__(self, name)
217         self.ctype = ctype
218         self.resolved = False
219
220
221 class Varargs(Type):
222
223     def __init__(self):
224         Type.__init__(self, '<varargs>')
225
226
227 class Array(Type):
228
229     def __init__(self, ctype, element_type):
230         Type.__init__(self, '<carray>', ctype)
231         self.element_type = element_type
232         self.zeroterminated = True
233         self.length_param_index = -1
234         self.length_param_name = None
235         self.size = None
236
237     def __repr__(self):
238         return 'Array(%r of %r)' % (self.name, self.element_type, )
239
240
241 class List(Type):
242
243     def __init__(self, name, ctype, element_type):
244         Type.__init__(self, name, ctype)
245         self.element_type = element_type
246
247     def __repr__(self):
248         return 'List(%r of %r)' % (self.name, self.element_type, )
249
250
251 class Map(Type):
252
253     def __init__(self, name, ctype, key_type, value_type):
254         Type.__init__(self, name, ctype)
255         self.key_type = key_type
256         self.value_type = value_type
257
258     def __repr__(self):
259         return 'Map(%r <%r,%r.)' % (self.name, self.key_type, self.value_type)
260
261
262 class Alias(Node):
263
264     def __init__(self, name, target, ctype=None):
265         Node.__init__(self, name)
266         self.target = target
267         self.ctype = ctype
268
269     def __repr__(self):
270         return 'Alias(%r, %r)' % (self.name, self.target)
271
272
273 class TypeContainer(Node):
274
275     def __init__(self, name, typenode, transfer):
276         Node.__init__(self, name)
277         self.type = typenode
278         if transfer in [PARAM_TRANSFER_NONE, PARAM_TRANSFER_CONTAINER,
279                         PARAM_TRANSFER_FULL]:
280             self.transfer = transfer
281         else:
282             self.transfer = None
283
284         # transformer.py overrides this as needed
285         self.transfer_inferred = False
286
287
288 class Parameter(TypeContainer):
289
290     def __init__(self, name, typenode, direction=PARAM_DIRECTION_IN,
291                  transfer=None, allow_none=False):
292         TypeContainer.__init__(self, name, typenode, transfer)
293         if direction in [PARAM_DIRECTION_IN, PARAM_DIRECTION_OUT,
294                          PARAM_DIRECTION_INOUT]:
295             self.direction = direction
296         else:
297             self.direction = PARAM_DIRECTION_IN
298
299         self.allow_none = not not allow_none
300
301     def __repr__(self):
302         return 'Parameter(%r, %r)' % (self.name, self.type)
303
304
305 class Enum(Node):
306
307     def __init__(self, name, symbol, members):
308         Node.__init__(self, name)
309         self.symbol = symbol
310         self.members = members
311
312     def __repr__(self):
313         return 'Enum(%r, %r)' % (self.name, self.members)
314
315
316 class Member(Node):
317
318     def __init__(self, name, value, symbol):
319         Node.__init__(self, name)
320         self.value = value
321         self.symbol = symbol
322
323     def __repr__(self):
324         return 'Member(%r, %r)' % (self.name, self.value)
325
326
327 class Struct(Node):
328
329     def __init__(self, name, symbol, disguised=False):
330         Node.__init__(self, name)
331         self.fields = []
332         self.constructors = []
333         self.symbol = symbol
334         self.disguised = disguised
335
336
337 class Field(Node):
338
339     def __init__(self, name, typenode, symbol, readable, writable, bits=None):
340         Node.__init__(self, name)
341         self.type = typenode
342         self.symbol = symbol
343         self.readable = readable
344         self.writable = writable
345         self.bits = bits
346
347     def __repr__(self):
348         if self.bits:
349             return 'Field(%r, %r, %r)' % (self.name, self.type, self.bits)
350         else:
351             return 'Field(%r, %r)' % (self.name, self.type)
352
353
354 class Return(TypeContainer):
355
356     def __init__(self, rtype, transfer=None):
357         TypeContainer.__init__(self, None, rtype, transfer)
358
359     def __repr__(self):
360         return 'Return(%r)' % (self.type, )
361
362
363 class Class(Node):
364
365     def __init__(self, name, parent, is_abstract):
366         Node.__init__(self, name)
367         self.ctype = name
368         self.parent = parent
369         self.is_abstract = is_abstract
370         self.methods = []
371         self.interfaces = []
372         self.constructors = []
373         self.properties = []
374         self.fields = []
375
376     def __repr__(self):
377         return '%s(%r, %r, %r)' % (
378             self.__class__.__name__,
379             self.name, self.parent, self.methods)
380
381
382 class Interface(Node):
383
384     def __init__(self, name, parent):
385         Node.__init__(self, name)
386         self.parent = parent
387         self.methods = []
388         self.properties = []
389         self.fields = []
390         self.prerequisites = []
391
392     def __repr__(self):
393         return '%s(%r, %r)' % (
394             self.__class__.__name__,
395             self.name, self.methods)
396
397
398 class Constant(Node):
399
400     def __init__(self, name, type_name, value):
401         Node.__init__(self, name)
402         self.type = Type(type_name)
403         self.value = value
404
405     def __repr__(self):
406         return 'Constant(%r, %r, %r)' % (
407             self.name, self.type, self.value)
408
409
410 class Property(Node):
411
412     def __init__(self, name, type_name, readable, writable,
413                  construct, construct_only, ctype=None):
414         Node.__init__(self, name)
415         self.type = Type(type_name, ctype)
416         self.readable = readable
417         self.writable = writable
418         self.construct = construct
419         self.construct_only = construct_only
420
421     def __repr__(self):
422         return '%s(%r, %r)' % (
423             self.__class__.__name__,
424             self.name, self.type)
425
426
427 # FIXME: Inherit from Function
428
429
430 class Callback(Node):
431
432     def __init__(self, name, retval, parameters, ctype=None):
433         Node.__init__(self, name)
434         self.retval = retval
435         self.parameters = parameters
436         self.ctype = ctype
437         self.throws = False
438
439     def __repr__(self):
440         return 'Callback(%r, %r, %r)' % (
441             self.name, self.retval, self.parameters)
442
443
444 class Union(Node):
445
446     def __init__(self, name, symbol):
447         Node.__init__(self, name)
448         self.fields = []
449         self.constructors = []
450         self.symbol = symbol
451
452     def __repr__(self):
453         return 'Union(%r, %r)' % (self.name, self.fields, )