Bug 554632: Create type tag for GType
[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['unsigned char'] = TYPE_UINT8
88 type_names['short'] = TYPE_INT16
89 type_names['unsigned short'] = TYPE_UINT16
90 type_names['int'] = TYPE_INT
91 type_names['unsigned int'] = TYPE_UINT
92 type_names['long'] = TYPE_LONG
93 type_names['unsigned long'] = TYPE_ULONG
94 type_names['float'] = TYPE_FLOAT
95 type_names['double'] = TYPE_DOUBLE
96 type_names['char*'] = TYPE_STRING
97 type_names['void*'] = TYPE_ANY
98 type_names['void'] = TYPE_NONE
99 type_names['size_t'] = TYPE_SIZET
100 type_names['ssize_t'] = TYPE_SSIZET
101 # FIXME - can we make libraries use GPid?
102 type_names['pid_t'] = TYPE_INT
103
104 # Suppress some GLib names
105 type_names['uchar'] = TYPE_UINT8
106 type_names['ushort'] = TYPE_UINT16
107 type_names['size'] = TYPE_SIZET
108 type_names['ssize'] = TYPE_SSIZET
109 type_names['pointer'] = TYPE_ANY
110 type_names['constpointer'] = TYPE_ANY
111
112
113 # These types, when seen by reference, are converted into an Array()
114 # by default
115 default_array_types = {}
116 default_array_types['uint8*'] = TYPE_UINT8
117 default_array_types['char**'] = TYPE_STRING
118
119
120 def type_name_from_ctype(ctype):
121     return type_names.get(ctype, ctype)
122
123
124 class Node(object):
125
126     def __init__(self, name=None):
127         self.name = name
128         self.deprecated = None
129         self.deprecated_version = None
130
131     def __repr__(self):
132         return '%s(%r)' % (self.__class__.__name__, self.name)
133
134
135 class Namespace(Node):
136
137     def __init__(self, name):
138         Node.__init__(self, name)
139         self.nodes = []
140
141     def __repr__(self):
142         return '%s(%r, %r)' % (self.__class__.__name__, self.name,
143                                self.nodes)
144
145
146 class Function(Node):
147
148     def __init__(self, name, retval, parameters, symbol):
149         Node.__init__(self, name)
150         self.retval = retval
151         self.parameters = parameters
152         self.symbol = symbol
153
154     def __repr__(self):
155         return '%s(%r, %r, %r)' % (self.__class__.__name__,
156                                    self.name, self.retval,
157                                    self.parameters)
158
159
160 class VFunction(Function):
161     pass
162
163
164 class Type(Node):
165
166     def __init__(self, name, ctype=None):
167         Node.__init__(self, name)
168         self.ctype = ctype
169         self.resolved = False
170
171
172 class Array(Type):
173
174     def __init__(self, ctype, element_type):
175         Type.__init__(self, '<carray>', ctype)
176         self.element_type = element_type
177         self.zeroterminated = True
178         self.length_param_index = -1
179
180     def __repr__(self):
181         return 'Array(%r of %r)' % (self.name, self.element_type, )
182
183
184 class List(Type):
185
186     def __init__(self, name, ctype, element_type):
187         Type.__init__(self, name, ctype)
188         self.element_type = element_type
189
190     def __repr__(self):
191         return 'List(%r of %r)' % (self.name, self.element_type, )
192
193
194 class Map(Type):
195
196     def __init__(self, name, ctype, key_type, value_type):
197         Type.__init__(self, name, ctype)
198         self.key_type = key_type
199         self.value_type = value_type
200
201     def __repr__(self):
202         return 'Map(%r <%r,%r.)' % (self.name, self.key_type, self.value_type)
203
204
205 class Alias(Node):
206
207     def __init__(self, name, target, ctype=None):
208         Node.__init__(self, name)
209         self.target = target
210         self.ctype = ctype
211
212     def __repr__(self):
213         return 'Alias(%r, %r)' % (self.name, self.target)
214
215
216 class Parameter(Node):
217
218     def __init__(self, name, typenode):
219         Node.__init__(self, name)
220         self.type = typenode
221         self.direction = PARAM_DIRECTION_IN
222         self.transfer = False
223         self.allow_none = False
224
225     def __repr__(self):
226         return 'Parameter(%r, %r)' % (self.name, self.type)
227
228
229 class Enum(Node):
230
231     def __init__(self, name, symbol, members):
232         Node.__init__(self, name)
233         self.symbol = symbol
234         self.members = members
235
236     def __repr__(self):
237         return 'Enum(%r, %r)' % (self.name, self.members)
238
239
240 class Member(Node):
241
242     def __init__(self, name, value, symbol):
243         Node.__init__(self, name)
244         self.value = value
245         self.symbol = symbol
246
247     def __repr__(self):
248         return 'Member(%r, %r)' % (self.name, self.value)
249
250
251 class Struct(Node):
252
253     def __init__(self, name, symbol):
254         Node.__init__(self, name)
255         self.fields = []
256         self.symbol = symbol
257
258
259 class Field(Node):
260
261     def __init__(self, name, typenode, symbol):
262         Node.__init__(self, name)
263         self.type = typenode
264         self.symbol = symbol
265
266     def __repr__(self):
267         return 'Field(%r, %r)' % (self.name, self.type)
268
269
270 class Return(Node):
271
272     def __init__(self, rtype):
273         Node.__init__(self)
274         self.type = rtype
275         self.transfer = isinstance(rtype, (List, Map, Array)) or \
276             rtype.name in ('utf8', 'filename')
277
278     def __repr__(self):
279         return 'Return(%r)' % (self.type, )
280
281
282 class Class(Node):
283
284     def __init__(self, name, parent):
285         Node.__init__(self, name)
286         self.ctype = name
287         self.parent = parent
288         self.methods = []
289         self.interfaces = []
290         self.constructors = []
291         self.properties = []
292         self.fields = []
293
294     def __repr__(self):
295         return '%s(%r, %r, %r)' % (
296             self.__class__.__name__,
297             self.name, self.parent, self.methods)
298
299
300 class Interface(Node):
301
302     def __init__(self, name, parent):
303         Node.__init__(self, name)
304         self.parent = parent
305         self.methods = []
306         self.properties = []
307         self.fields = []
308
309     def __repr__(self):
310         return '%s(%r, %r)' % (
311             self.__class__.__name__,
312             self.name, self.methods)
313
314
315 class Constant(Node):
316
317     def __init__(self, name, type_name, value):
318         Node.__init__(self, name)
319         self.type = Type(type_name)
320         self.value = value
321
322     def __repr__(self):
323         return 'Constant(%r, %r, %r)' % (
324             self.name, self.type, self.value)
325
326
327 class Property(Node):
328
329     def __init__(self, name, type_name, readable, writable,
330                  construct, construct_only, ctype=None):
331         Node.__init__(self, name)
332         self.type = Type(type_name, ctype)
333         self.readable = readable
334         self.writable = writable
335         self.construct = construct
336         self.construct_only = construct_only
337
338     def __repr__(self):
339         return '%s(%r, %r, %r)' % (
340             self.__class__.__name__,
341             self.name, self.type, self.value)
342
343
344 # FIXME: Inherit from Function
345
346
347 class Callback(Node):
348
349     def __init__(self, name, retval, parameters, ctype=None):
350         Node.__init__(self, name)
351         self.retval = retval
352         self.parameters = parameters
353         self.ctype = ctype
354
355     def __repr__(self):
356         return 'Callback(%r, %r, %r)' % (
357             self.name, self.retval, self.parameters)
358
359
360 class Union(Node):
361
362     def __init__(self, name, symbol):
363         Node.__init__(self, name)
364         self.fields = []
365         self.symbol = symbol
366
367     def __repr__(self):
368         return 'Union(%r, %r)' % (self.name, self.fields, )