Bug 556489 – callback annotations
[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 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         self.version = None
152
153     def __repr__(self):
154         return '%s(%r)' % (self.__class__.__name__, self.name)
155
156
157 class Namespace(Node):
158
159     def __init__(self, name, version):
160         Node.__init__(self, name)
161         self.version = version
162         self.nodes = []
163
164     def __repr__(self):
165         return '%s(%r, %r, %r)' % (self.__class__.__name__, self.name,
166                                    self.version, self.nodes)
167
168
169 class Include(Node):
170
171     def __init__(self, name, version):
172         Node.__init__(self, 'include')
173         self.name = name
174         self.version = version
175
176     @classmethod
177     def from_string(self, string):
178         return Include(*string.split('-', 1))
179
180     def __cmp__(self, other):
181         if not isinstance(other, Include):
182             return cmp(self, other)
183         namecmp = cmp(self.name, other.name)
184         if namecmp != 0:
185             return namecmp
186         return cmp(self.version, other.version)
187
188     def __hash__(self):
189         return hash((self.name, self.version))
190
191     def __str__(self):
192         return '%s-%s' % (self.name, self.version)
193
194
195 class Function(Node):
196
197     def __init__(self, name, retval, parameters, symbol, throws=None):
198         Node.__init__(self, name)
199         self.retval = retval
200         self.parameters = parameters
201         self.symbol = symbol
202         self.throws = not not throws
203
204     def __repr__(self):
205         return '%s(%r, %r, %r)' % (self.__class__.__name__,
206                                    self.name, self.retval,
207                                    self.parameters)
208
209
210 class VFunction(Function):
211     pass
212
213
214 class Type(Node):
215
216     def __init__(self, name, ctype=None):
217         Node.__init__(self, name)
218         self.ctype = ctype
219         self.resolved = False
220
221
222 class Varargs(Type):
223
224     def __init__(self):
225         Type.__init__(self, '<varargs>')
226
227
228 class Array(Type):
229
230     def __init__(self, ctype, element_type):
231         Type.__init__(self, '<carray>', ctype)
232         self.element_type = element_type
233         self.zeroterminated = True
234         self.length_param_index = -1
235         self.length_param_name = None
236         self.size = None
237
238     def __repr__(self):
239         return 'Array(%r of %r)' % (self.name, self.element_type, )
240
241
242 class List(Type):
243
244     def __init__(self, name, ctype, element_type):
245         Type.__init__(self, name, ctype)
246         self.element_type = element_type
247
248     def __repr__(self):
249         return 'List(%r of %r)' % (self.name, self.element_type, )
250
251
252 class Map(Type):
253
254     def __init__(self, name, ctype, key_type, value_type):
255         Type.__init__(self, name, ctype)
256         self.key_type = key_type
257         self.value_type = value_type
258
259     def __repr__(self):
260         return 'Map(%r <%r,%r.)' % (self.name, self.key_type, self.value_type)
261
262
263 class Alias(Node):
264
265     def __init__(self, name, target, ctype=None):
266         Node.__init__(self, name)
267         self.target = target
268         self.ctype = ctype
269
270     def __repr__(self):
271         return 'Alias(%r, %r)' % (self.name, self.target)
272
273
274 class TypeContainer(Node):
275
276     def __init__(self, name, typenode, transfer):
277         Node.__init__(self, name)
278         self.type = typenode
279         if transfer in [PARAM_TRANSFER_NONE, PARAM_TRANSFER_CONTAINER,
280                         PARAM_TRANSFER_FULL]:
281             self.transfer = transfer
282         else:
283             self.transfer = None
284
285         # transformer.py overrides this as needed
286         self.transfer_inferred = False
287
288
289 class Parameter(TypeContainer):
290
291     def __init__(self, name, typenode, direction=PARAM_DIRECTION_IN,
292                  transfer=None, allow_none=False, scope=None):
293         TypeContainer.__init__(self, name, typenode, transfer)
294         if direction in [PARAM_DIRECTION_IN, PARAM_DIRECTION_OUT,
295                          PARAM_DIRECTION_INOUT]:
296             self.direction = direction
297         else:
298             self.direction = PARAM_DIRECTION_IN
299
300         self.allow_none = not not allow_none
301         self.scope = scope
302         self.closure_index = -1
303         self.destroy_index = -1
304
305     def __repr__(self):
306         return 'Parameter(%r, %r)' % (self.name, self.type)
307
308
309 class Enum(Node):
310
311     def __init__(self, name, symbol, members):
312         Node.__init__(self, name)
313         self.symbol = symbol
314         self.members = members
315
316     def __repr__(self):
317         return 'Enum(%r, %r)' % (self.name, self.members)
318
319
320 class Member(Node):
321
322     def __init__(self, name, value, symbol):
323         Node.__init__(self, name)
324         self.value = value
325         self.symbol = symbol
326
327     def __repr__(self):
328         return 'Member(%r, %r)' % (self.name, self.value)
329
330
331 class Struct(Node):
332
333     def __init__(self, name, symbol, disguised=False):
334         Node.__init__(self, name)
335         self.fields = []
336         self.constructors = []
337         self.symbol = symbol
338         self.disguised = disguised
339
340
341 class Field(Node):
342
343     def __init__(self, name, typenode, symbol, readable, writable, bits=None):
344         Node.__init__(self, name)
345         self.type = typenode
346         self.symbol = symbol
347         self.readable = readable
348         self.writable = writable
349         self.bits = bits
350
351     def __repr__(self):
352         if self.bits:
353             return 'Field(%r, %r, %r)' % (self.name, self.type, self.bits)
354         else:
355             return 'Field(%r, %r)' % (self.name, self.type)
356
357
358 class Return(TypeContainer):
359
360     def __init__(self, rtype, transfer=None):
361         TypeContainer.__init__(self, None, rtype, transfer)
362
363     def __repr__(self):
364         return 'Return(%r)' % (self.type, )
365
366
367 class Class(Node):
368
369     def __init__(self, name, parent, is_abstract):
370         Node.__init__(self, name)
371         self.ctype = name
372         self.parent = parent
373         self.is_abstract = is_abstract
374         self.methods = []
375         self.static_methods = []
376         self.interfaces = []
377         self.constructors = []
378         self.properties = []
379         self.fields = []
380
381     def __repr__(self):
382         return '%s(%r, %r, %r)' % (
383             self.__class__.__name__,
384             self.name, self.parent, self.methods)
385
386
387 class Interface(Node):
388
389     def __init__(self, name, parent):
390         Node.__init__(self, name)
391         self.parent = parent
392         self.methods = []
393         self.properties = []
394         self.fields = []
395         self.prerequisites = []
396
397     def __repr__(self):
398         return '%s(%r, %r)' % (
399             self.__class__.__name__,
400             self.name, self.methods)
401
402
403 class Constant(Node):
404
405     def __init__(self, name, type_name, value):
406         Node.__init__(self, name)
407         self.type = Type(type_name)
408         self.value = value
409
410     def __repr__(self):
411         return 'Constant(%r, %r, %r)' % (
412             self.name, self.type, self.value)
413
414
415 class Property(Node):
416
417     def __init__(self, name, type_name, readable, writable,
418                  construct, construct_only, ctype=None):
419         Node.__init__(self, name)
420         self.type = Type(type_name, ctype)
421         self.readable = readable
422         self.writable = writable
423         self.construct = construct
424         self.construct_only = construct_only
425
426     def __repr__(self):
427         return '%s(%r, %r)' % (
428             self.__class__.__name__,
429             self.name, self.type)
430
431
432 # FIXME: Inherit from Function
433
434 class Callback(Node):
435
436     def __init__(self, name, retval, parameters, ctype=None):
437         Node.__init__(self, name)
438         self.retval = retval
439         self.parameters = parameters
440         self.ctype = ctype
441         self.throws = False
442
443     def __repr__(self):
444         return 'Callback(%r, %r, %r)' % (
445             self.name, self.retval, self.parameters)
446
447
448 class Union(Node):
449
450     def __init__(self, name, symbol):
451         Node.__init__(self, name)
452         self.fields = []
453         self.constructors = []
454         self.symbol = symbol
455
456     def __repr__(self):
457         return 'Union(%r, %r)' % (self.name, self.fields, )