Fix __repr__ for Property
[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 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
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 type_names['size_t'] = TYPE_SIZET
110 type_names['ssize_t'] = TYPE_SSIZET
111 type_names['off_t'] = TYPE_SIZET
112 # FIXME - can we make libraries use GPid?
113 type_names['pid_t'] = TYPE_INT
114
115 # Suppress some GLib names
116 type_names['uchar'] = TYPE_UINT8
117 type_names['ushort'] = TYPE_UINT16
118 type_names['size'] = TYPE_SIZET
119 type_names['ssize'] = TYPE_SSIZET
120 type_names['pointer'] = TYPE_ANY
121 type_names['constpointer'] = TYPE_ANY
122
123
124 # These types, when seen by reference, are converted into an Array()
125 # by default
126 # If you add/change these, be sure to update glibast.py too
127 default_array_types = {}
128 default_array_types['uint8*'] = TYPE_UINT8
129 default_array_types['char**'] = TYPE_STRING
130
131 # These types, when seen by reference, are interpreted as out parameters
132 default_out_types = (TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG,
133                      TYPE_FLOAT, TYPE_DOUBLE, TYPE_SIZET, TYPE_SSIZET)
134
135
136 def type_name_from_ctype(ctype):
137     return type_names.get(ctype, ctype)
138
139
140 class Node(object):
141
142     def __init__(self, name=None):
143         self.name = name
144         self.deprecated = None
145         self.deprecated_version = None
146
147     def __repr__(self):
148         return '%s(%r)' % (self.__class__.__name__, self.name)
149
150
151 class Namespace(Node):
152
153     def __init__(self, name, version):
154         Node.__init__(self, name)
155         self.version = version
156         self.nodes = []
157
158     def __repr__(self):
159         return '%s(%r, %r, %r)' % (self.__class__.__name__, self.name,
160                                    self.version, self.nodes)
161
162
163 class Include(Node):
164
165     def __init__(self, name, version):
166         Node.__init__(self, 'include')
167         self.name = name
168         self.version = version
169
170     @classmethod
171     def from_string(self, string):
172         return Include(*string.split('-', 1))
173
174     def __cmp__(self, other):
175         if not isinstance(other, Include):
176             return cmp(self, other)
177         namecmp = cmp(self.name, other.name)
178         if namecmp != 0:
179             return namecmp
180         return cmp(self.version, other.version)
181
182     def __hash__(self):
183         return hash((self.name, self.version))
184
185     def __str__(self):
186         return '%s-%s' % (self.name, self.version)
187
188
189 class Function(Node):
190
191     def __init__(self, name, retval, parameters, symbol):
192         Node.__init__(self, name)
193         self.retval = retval
194         self.parameters = parameters
195         self.symbol = symbol
196
197     def __repr__(self):
198         return '%s(%r, %r, %r)' % (self.__class__.__name__,
199                                    self.name, self.retval,
200                                    self.parameters)
201
202
203 class VFunction(Function):
204     pass
205
206
207 class Type(Node):
208
209     def __init__(self, name, ctype=None):
210         Node.__init__(self, name)
211         self.ctype = ctype
212         self.resolved = False
213
214
215 class Varargs(Type):
216
217     def __init__(self):
218         Type.__init__(self, '<varargs>')
219
220
221 class Array(Type):
222
223     def __init__(self, ctype, element_type):
224         Type.__init__(self, '<carray>', ctype)
225         self.element_type = element_type
226         self.zeroterminated = True
227         self.length_param_index = -1
228         self.length_param_name = None
229
230     def __repr__(self):
231         return 'Array(%r of %r)' % (self.name, self.element_type, )
232
233
234 class List(Type):
235
236     def __init__(self, name, ctype, element_type):
237         Type.__init__(self, name, ctype)
238         self.element_type = element_type
239
240     def __repr__(self):
241         return 'List(%r of %r)' % (self.name, self.element_type, )
242
243
244 class Map(Type):
245
246     def __init__(self, name, ctype, key_type, value_type):
247         Type.__init__(self, name, ctype)
248         self.key_type = key_type
249         self.value_type = value_type
250
251     def __repr__(self):
252         return 'Map(%r <%r,%r.)' % (self.name, self.key_type, self.value_type)
253
254
255 class Alias(Node):
256
257     def __init__(self, name, target, ctype=None):
258         Node.__init__(self, name)
259         self.target = target
260         self.ctype = ctype
261
262     def __repr__(self):
263         return 'Alias(%r, %r)' % (self.name, self.target)
264
265
266 class Parameter(Node):
267
268     def __init__(self, name, typenode, direction=PARAM_DIRECTION_IN,
269                  transfer=None, allow_none=False):
270         Node.__init__(self, name)
271         self.type = typenode
272         if direction in [PARAM_DIRECTION_IN, PARAM_DIRECTION_OUT,
273                          PARAM_DIRECTION_INOUT]:
274             self.direction = direction
275         else:
276             self.direction = PARAM_DIRECTION_IN
277
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         self.allow_none = not not allow_none
285
286     def __repr__(self):
287         return 'Parameter(%r, %r)' % (self.name, self.type)
288
289
290 class Enum(Node):
291
292     def __init__(self, name, symbol, members):
293         Node.__init__(self, name)
294         self.symbol = symbol
295         self.members = members
296
297     def __repr__(self):
298         return 'Enum(%r, %r)' % (self.name, self.members)
299
300
301 class Member(Node):
302
303     def __init__(self, name, value, symbol):
304         Node.__init__(self, name)
305         self.value = value
306         self.symbol = symbol
307
308     def __repr__(self):
309         return 'Member(%r, %r)' % (self.name, self.value)
310
311
312 class Struct(Node):
313
314     def __init__(self, name, symbol):
315         Node.__init__(self, name)
316         self.fields = []
317         self.constructors = []
318         self.symbol = symbol
319
320
321 class Field(Node):
322
323     def __init__(self, name, typenode, symbol, readable, writable, bits=None):
324         Node.__init__(self, name)
325         self.type = typenode
326         self.symbol = symbol
327         self.readable = readable
328         self.writable = writable
329         self.bits = bits
330
331     def __repr__(self):
332         if self.bits:
333             return 'Field(%r, %r, %r)' % (self.name, self.type, self.bits)
334         else:
335             return 'Field(%r, %r)' % (self.name, self.type)
336
337
338 class Return(Node):
339
340     def __init__(self, rtype, transfer=None):
341         Node.__init__(self)
342         self.type = rtype
343         if transfer is None and rtype.name in ['utf8', 'filename']:
344             self.transfer = 'full'
345         else:
346             self.transfer = transfer
347
348     def __repr__(self):
349         return 'Return(%r)' % (self.type, )
350
351
352 class Class(Node):
353
354     def __init__(self, name, parent, is_abstract):
355         Node.__init__(self, name)
356         self.ctype = name
357         self.parent = parent
358         self.is_abstract = is_abstract
359         self.methods = []
360         self.interfaces = []
361         self.constructors = []
362         self.properties = []
363         self.fields = []
364
365     def __repr__(self):
366         return '%s(%r, %r, %r)' % (
367             self.__class__.__name__,
368             self.name, self.parent, self.methods)
369
370
371 class Interface(Node):
372
373     def __init__(self, name, parent):
374         Node.__init__(self, name)
375         self.parent = parent
376         self.methods = []
377         self.properties = []
378         self.fields = []
379
380     def __repr__(self):
381         return '%s(%r, %r)' % (
382             self.__class__.__name__,
383             self.name, self.methods)
384
385
386 class Constant(Node):
387
388     def __init__(self, name, type_name, value):
389         Node.__init__(self, name)
390         self.type = Type(type_name)
391         self.value = value
392
393     def __repr__(self):
394         return 'Constant(%r, %r, %r)' % (
395             self.name, self.type, self.value)
396
397
398 class Property(Node):
399
400     def __init__(self, name, type_name, readable, writable,
401                  construct, construct_only, ctype=None):
402         Node.__init__(self, name)
403         self.type = Type(type_name, ctype)
404         self.readable = readable
405         self.writable = writable
406         self.construct = construct
407         self.construct_only = construct_only
408
409     def __repr__(self):
410         return '%s(%r, %r)' % (
411             self.__class__.__name__,
412             self.name, self.type)
413
414
415 # FIXME: Inherit from Function
416
417
418 class Callback(Node):
419
420     def __init__(self, name, retval, parameters, ctype=None):
421         Node.__init__(self, name)
422         self.retval = retval
423         self.parameters = parameters
424         self.ctype = ctype
425
426     def __repr__(self):
427         return 'Callback(%r, %r, %r)' % (
428             self.name, self.retval, self.parameters)
429
430
431 class Union(Node):
432
433     def __init__(self, name, symbol):
434         Node.__init__(self, name)
435         self.fields = []
436         self.constructors = []
437         self.symbol = symbol
438
439     def __repr__(self):
440         return 'Union(%r, %r)' % (self.name, self.fields, )