Bug 556433 – assume direction = out for int * parameters
[platform/upstream/gobject-introspection.git] / 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 Function(Node):
159
160     def __init__(self, name, retval, parameters, symbol):
161         Node.__init__(self, name)
162         self.retval = retval
163         self.parameters = parameters
164         self.symbol = symbol
165
166     def __repr__(self):
167         return '%s(%r, %r, %r)' % (self.__class__.__name__,
168                                    self.name, self.retval,
169                                    self.parameters)
170
171
172 class VFunction(Function):
173     pass
174
175
176 class Type(Node):
177
178     def __init__(self, name, ctype=None):
179         Node.__init__(self, name)
180         self.ctype = ctype
181         self.resolved = False
182
183
184 class Varargs(Type):
185
186     def __init__(self):
187         Type.__init__(self, '<varargs>')
188
189
190 class Array(Type):
191
192     def __init__(self, ctype, element_type):
193         Type.__init__(self, '<carray>', ctype)
194         self.element_type = element_type
195         self.zeroterminated = True
196         self.length_param_index = -1
197         self.length_param_name = None
198
199     def __repr__(self):
200         return 'Array(%r of %r)' % (self.name, self.element_type, )
201
202
203 class List(Type):
204
205     def __init__(self, name, ctype, element_type):
206         Type.__init__(self, name, ctype)
207         self.element_type = element_type
208
209     def __repr__(self):
210         return 'List(%r of %r)' % (self.name, self.element_type, )
211
212
213 class Map(Type):
214
215     def __init__(self, name, ctype, key_type, value_type):
216         Type.__init__(self, name, ctype)
217         self.key_type = key_type
218         self.value_type = value_type
219
220     def __repr__(self):
221         return 'Map(%r <%r,%r.)' % (self.name, self.key_type, self.value_type)
222
223
224 class Alias(Node):
225
226     def __init__(self, name, target, ctype=None):
227         Node.__init__(self, name)
228         self.target = target
229         self.ctype = ctype
230
231     def __repr__(self):
232         return 'Alias(%r, %r)' % (self.name, self.target)
233
234
235 class Parameter(Node):
236
237     def __init__(self, name, typenode):
238         Node.__init__(self, name)
239         self.type = typenode
240         self.direction = PARAM_DIRECTION_IN
241         self.transfer = None
242         self.allow_none = False
243
244     def __repr__(self):
245         return 'Parameter(%r, %r)' % (self.name, self.type)
246
247
248 class Enum(Node):
249
250     def __init__(self, name, symbol, members):
251         Node.__init__(self, name)
252         self.symbol = symbol
253         self.members = members
254
255     def __repr__(self):
256         return 'Enum(%r, %r)' % (self.name, self.members)
257
258
259 class Member(Node):
260
261     def __init__(self, name, value, symbol):
262         Node.__init__(self, name)
263         self.value = value
264         self.symbol = symbol
265
266     def __repr__(self):
267         return 'Member(%r, %r)' % (self.name, self.value)
268
269
270 class Struct(Node):
271
272     def __init__(self, name, symbol):
273         Node.__init__(self, name)
274         self.fields = []
275         self.constructors = []
276         self.symbol = symbol
277
278
279 class Field(Node):
280
281     def __init__(self, name, typenode, symbol, bits=None):
282         Node.__init__(self, name)
283         self.type = typenode
284         self.symbol = symbol
285         self.bits = bits
286
287     def __repr__(self):
288         if self.bits:
289             return 'Field(%r, %r, %r)' % (self.name, self.type, self.bits)
290         else:
291             return 'Field(%r, %r)' % (self.name, self.type)
292
293
294 class Return(Node):
295
296     def __init__(self, rtype, transfer=None):
297         Node.__init__(self)
298         self.type = rtype
299         if transfer is None and rtype.name in ['utf8', 'filename']:
300             self.transfer = 'full'
301         else:
302             self.transfer = transfer
303
304     def __repr__(self):
305         return 'Return(%r)' % (self.type, )
306
307
308 class Class(Node):
309
310     def __init__(self, name, parent):
311         Node.__init__(self, name)
312         self.ctype = name
313         self.parent = parent
314         self.methods = []
315         self.interfaces = []
316         self.constructors = []
317         self.properties = []
318         self.fields = []
319
320     def __repr__(self):
321         return '%s(%r, %r, %r)' % (
322             self.__class__.__name__,
323             self.name, self.parent, self.methods)
324
325
326 class Interface(Node):
327
328     def __init__(self, name, parent):
329         Node.__init__(self, name)
330         self.parent = parent
331         self.methods = []
332         self.properties = []
333         self.fields = []
334
335     def __repr__(self):
336         return '%s(%r, %r)' % (
337             self.__class__.__name__,
338             self.name, self.methods)
339
340
341 class Constant(Node):
342
343     def __init__(self, name, type_name, value):
344         Node.__init__(self, name)
345         self.type = Type(type_name)
346         self.value = value
347
348     def __repr__(self):
349         return 'Constant(%r, %r, %r)' % (
350             self.name, self.type, self.value)
351
352
353 class Property(Node):
354
355     def __init__(self, name, type_name, readable, writable,
356                  construct, construct_only, ctype=None):
357         Node.__init__(self, name)
358         self.type = Type(type_name, ctype)
359         self.readable = readable
360         self.writable = writable
361         self.construct = construct
362         self.construct_only = construct_only
363
364     def __repr__(self):
365         return '%s(%r, %r, %r)' % (
366             self.__class__.__name__,
367             self.name, self.type, self.value)
368
369
370 # FIXME: Inherit from Function
371
372
373 class Callback(Node):
374
375     def __init__(self, name, retval, parameters, ctype=None):
376         Node.__init__(self, name)
377         self.retval = retval
378         self.parameters = parameters
379         self.ctype = ctype
380
381     def __repr__(self):
382         return 'Callback(%r, %r, %r)' % (
383             self.name, self.retval, self.parameters)
384
385
386 class Union(Node):
387
388     def __init__(self, name, symbol):
389         Node.__init__(self, name)
390         self.fields = []
391         self.constructors = []
392         self.symbol = symbol
393
394     def __repr__(self):
395         return 'Union(%r, %r)' % (self.name, self.fields, )