2 # GObject-Introspection - a framework for introspecting GObject libraries
3 # Copyright (C) 2008 Johan Dahlin
4 # Copyright (C) 2008, 2009 Red Hat, Inc.
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2 of the License, or (at your option) any later version.
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the
18 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 # Boston, MA 02111-1307, USA.
23 This file descbribes abstract data type nodes independent on the
24 implementation language.
26 These can later on be extended (eg subclassed) with additional information
27 which is language/library/domain specific.
31 ## Basic types, modeled on GITypeTag but not equivalent
34 TYPE_NONE = 'none' # We differ from repository on these first two
36 TYPE_BOOLEAN = 'boolean'
40 TYPE_USHORT = 'ushort'
42 TYPE_UINT16 = 'uint16'
46 TYPE_UINT32 = 'uint32'
48 TYPE_UINT64 = 'uint64'
51 TYPE_SSIZET = 'ssize_t'
56 TYPE_DOUBLE = 'double'
57 TYPE_STRING = 'utf8' # requires zero-terminated
58 TYPE_FILENAME = 'filename'
60 BASIC_GIR_TYPES = [TYPE_BOOLEAN, TYPE_INT8, TYPE_UINT8, TYPE_INT16,
61 TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_INT64,
62 TYPE_UINT64, TYPE_SHORT, TYPE_USHORT, TYPE_INT,
63 TYPE_UINT, TYPE_LONG, TYPE_ULONG, TYPE_SSIZET,
64 TYPE_SIZET, TYPE_FLOAT, TYPE_DOUBLE, TYPE_TIMET,
66 GIR_TYPES = [TYPE_NONE, TYPE_ANY]
67 GIR_TYPES.extend(BASIC_GIR_TYPES)
68 GIR_TYPES.extend([TYPE_STRING, TYPE_FILENAME])
70 # Higher-level data types
71 TYPE_SEQUENCE = 'sequence' # Sequence of something
75 TYPE_USTRING = 'ustring'
81 PARAM_DIRECTION_IN = 'in'
82 PARAM_DIRECTION_OUT = 'out'
83 PARAM_DIRECTION_INOUT = 'inout'
85 PARAM_SCOPE_CALL = 'call'
86 PARAM_SCOPE_ASYNC = 'async'
87 PARAM_SCOPE_NOTIFIED = 'notified'
89 PARAM_TRANSFER_NONE = 'none'
90 PARAM_TRANSFER_CONTAINER = 'container'
91 PARAM_TRANSFER_FULL = 'full'
94 for name in GIR_TYPES:
95 type_names[name] = name
98 type_names['char'] = TYPE_INT8
99 type_names['signed char'] = TYPE_INT8
100 type_names['unsigned char'] = TYPE_UINT8
101 type_names['short'] = TYPE_SHORT
102 type_names['signed short'] = TYPE_SHORT
103 type_names['unsigned short'] = TYPE_USHORT
104 type_names['int'] = TYPE_INT
105 type_names['signed int'] = TYPE_INT
106 type_names['signed'] = TYPE_INT
107 type_names['unsigned int'] = TYPE_UINT
108 type_names['unsigned'] = TYPE_UINT
109 type_names['long'] = TYPE_LONG
110 type_names['signed long'] = TYPE_LONG
111 type_names['unsigned long'] = TYPE_ULONG
112 type_names['float'] = TYPE_FLOAT
113 type_names['double'] = TYPE_DOUBLE
114 type_names['char*'] = TYPE_STRING
115 type_names['void*'] = TYPE_ANY
116 type_names['void'] = TYPE_NONE
119 type_names['off_t'] = TYPE_SIZET
120 type_names['pid_t'] = TYPE_INT
121 type_names['size_t'] = TYPE_SIZET
122 type_names['ssize_t'] = TYPE_SSIZET
123 type_names['socklen_t'] = TYPE_INT32
126 type_names['id'] = TYPE_ANY
128 # Suppress some GLib names
129 type_names['uchar'] = TYPE_UINT8
130 type_names['ushort'] = TYPE_USHORT
131 type_names['size'] = TYPE_SIZET
132 type_names['ssize'] = TYPE_SSIZET
133 type_names['pointer'] = TYPE_ANY
134 type_names['constpointer'] = TYPE_ANY
137 # These types, when seen by reference, are converted into an Array()
139 # If you add/change these, be sure to update glibast.py too
140 default_array_types = {}
141 default_array_types['uint8*'] = TYPE_UINT8
142 default_array_types['utf8*'] = TYPE_STRING
144 # These types, when seen by reference, are interpreted as out parameters
145 default_out_types = (TYPE_SHORT, TYPE_USHORT, TYPE_INT, TYPE_UINT,
146 TYPE_LONG, TYPE_ULONG, TYPE_FLOAT, TYPE_DOUBLE,
147 TYPE_SIZET, TYPE_SSIZET)
150 def type_name_from_ctype(ctype):
151 return type_names.get(ctype, ctype)
156 def __init__(self, name=None):
158 self.attributes = [] # (key, value)*
160 self.deprecated = None
161 self.deprecated_version = None
164 def __cmp__(self, other):
165 return cmp(self.name, other.name)
168 return '%s(%r)' % (self.__class__.__name__, self.name)
170 def remove_matching_children(self, pred):
173 class Namespace(Node):
175 def __init__(self, name, version):
176 Node.__init__(self, name)
177 self.version = version
181 return '%s(%r, %r, %r)' % (self.__class__.__name__, self.name,
182 self.version, self.nodes)
184 def remove_matching(self, pred):
186 def recursive_pred(node):
187 node.remove_matching_children(pred)
190 self.nodes = filter(recursive_pred, self.nodes)
194 def __init__(self, name, version):
195 Node.__init__(self, 'include')
197 self.version = version
200 def from_string(self, string):
201 return Include(*string.split('-', 1))
203 def __cmp__(self, other):
204 if not isinstance(other, Include):
205 return cmp(self, other)
206 namecmp = cmp(self.name, other.name)
209 return cmp(self.version, other.version)
212 return hash((self.name, self.version))
215 return '%s-%s' % (self.name, self.version)
217 class Callable(Node):
219 def __init__(self, name, retval, parameters, throws):
220 Node.__init__(self, name)
222 self.parameters = parameters
223 self.throws = not not throws
227 return '%s(%r, %r, %r)' % (self.__class__.__name__,
228 self.name, self.retval,
231 class Function(Callable):
233 def __init__(self, name, retval, parameters, symbol, throws=None):
234 Callable.__init__(self, name, retval, parameters, throws)
236 self.is_method = False
239 def get_parameter_index(self, name):
240 for i, parameter in enumerate(self.parameters):
241 if parameter.name == name:
242 return i + int(self.is_method)
244 def get_parameter(self, name):
245 for parameter in self.parameters:
246 if parameter.name == name:
250 class VFunction(Callable):
252 def __init__(self, name, retval, parameters, throws):
253 Callable.__init__(self, name, retval, parameters, throws)
257 def from_callback(cls, cb):
258 obj = cls(cb.name, cb.retval, cb.parameters[1:],
265 def __init__(self, name, ctype=None):
266 Node.__init__(self, name)
268 self.resolved = False
269 self.is_const = False
270 self.canonical = None
271 self.derefed_canonical = None
277 Type.__init__(self, '<varargs>')
282 def __init__(self, name, ctype, element_type):
285 Type.__init__(self, name, ctype)
286 self.element_type = element_type
287 self.zeroterminated = True
288 self.length_param_index = -1
289 self.length_param_name = None
293 return 'Array(%r, %r)' % (self.name, self.element_type, )
298 def __init__(self, name, ctype, element_type):
299 Type.__init__(self, name, ctype)
300 self.element_type = element_type
303 return 'List(%r of %r)' % (self.name, self.element_type, )
308 def __init__(self, name, ctype, key_type, value_type):
309 Type.__init__(self, name, ctype)
310 self.key_type = key_type
311 self.value_type = value_type
314 return 'Map(%r <%r,%r>)' % (self.name, self.key_type, self.value_type)
319 def __init__(self, name, target, ctype=None):
320 Node.__init__(self, name)
325 return 'Alias(%r, %r)' % (self.name, self.target)
328 class TypeContainer(Node):
330 def __init__(self, name, typenode, transfer):
331 Node.__init__(self, name)
333 if transfer in [PARAM_TRANSFER_NONE, PARAM_TRANSFER_CONTAINER,
334 PARAM_TRANSFER_FULL]:
335 self.transfer = transfer
340 class Parameter(TypeContainer):
342 def __init__(self, name, typenode, direction=None,
343 transfer=None, allow_none=False, scope=None):
344 TypeContainer.__init__(self, name, typenode, transfer)
345 if direction in [PARAM_DIRECTION_IN, PARAM_DIRECTION_OUT,
346 PARAM_DIRECTION_INOUT, None]:
347 self.direction = direction
349 self.direction = PARAM_DIRECTION_IN
351 self.allow_none = allow_none
353 self.closure_index = -1
354 self.destroy_index = -1
358 return 'Parameter(%r, %r)' % (self.name, self.type)
363 def __init__(self, name, symbol, members):
364 Node.__init__(self, name)
366 self.members = members
370 return 'Enum(%r, %r)' % (self.name, self.members)
373 class Bitfield(Node):
375 def __init__(self, name, symbol, members):
376 Node.__init__(self, name)
378 self.members = members
382 return 'Bitfield(%r, %r)' % (self.name, self.members)
387 def __init__(self, name, value, symbol):
388 Node.__init__(self, name)
393 return 'Member(%r, %r)' % (self.name, self.value)
398 def __init__(self, name, symbol, disguised=False):
399 Node.__init__(self, name)
401 self.constructors = []
403 self.disguised = disguised
407 def remove_matching_children(self, pred):
408 self.fields = filter(pred, self.fields)
409 self.constructors = filter(pred, self.constructors)
410 self.methods = filter(pred, self.methods)
418 def __init__(self, name, typenode, symbol, readable, writable, bits=None):
419 Node.__init__(self, name)
422 self.readable = readable
423 self.writable = writable
428 return 'Field(%r, %r, %r)' % (self.name, self.type, self.bits)
430 return 'Field(%r, %r)' % (self.name, self.type)
433 class Return(TypeContainer):
435 def __init__(self, rtype, transfer=None):
436 TypeContainer.__init__(self, None, rtype, transfer)
437 self.direction = PARAM_DIRECTION_OUT
441 return 'Return(%r)' % (self.type, )
446 def __init__(self, name, parent, is_abstract):
447 Node.__init__(self, name)
450 self.glib_type_struct = None
451 self.is_abstract = is_abstract
453 self.virtual_methods = []
454 self.static_methods = []
456 self.constructors = []
461 def remove_matching_children(self, pred):
462 self.methods = filter(pred, self.methods)
463 self.constructors = filter(pred, self.constructors)
464 self.properties = filter(pred, self.properties)
465 self.fields = filter(pred, self.fields)
468 return '%s(%r, %r, %r)' % (
469 self.__class__.__name__,
470 self.name, self.parent, self.methods)
473 class Interface(Node):
475 def __init__(self, name, parent):
476 Node.__init__(self, name)
479 self.virtual_methods = []
480 self.glib_type_struct = None
483 self.prerequisites = []
487 return '%s(%r, %r)' % (
488 self.__class__.__name__,
489 self.name, self.methods)
492 class Constant(Node):
494 def __init__(self, name, type_name, value):
495 Node.__init__(self, name)
496 self.type = Type(type_name)
500 return 'Constant(%r, %r, %r)' % (
501 self.name, self.type, self.value)
504 class Property(Node):
506 def __init__(self, name, type_name, readable, writable,
507 construct, construct_only, ctype=None):
508 Node.__init__(self, name)
509 self.type = Type(type_name, ctype)
510 self.readable = readable
511 self.writable = writable
512 self.construct = construct
513 self.construct_only = construct_only
517 return '%s(%r, %r)' % (
518 self.__class__.__name__,
519 self.name, self.type)
522 # FIXME: Inherit from Function
525 class Callback(Node):
527 def __init__(self, name, retval, parameters, ctype=None):
528 Node.__init__(self, name)
530 self.parameters = parameters
535 def get_parameter_index(self, name):
536 for i, parameter in enumerate(self.parameters):
537 if parameter.name == name:
540 def get_parameter(self, name):
541 for parameter in self.parameters:
542 if parameter.name == name:
546 return 'Callback(%r, %r, %r)' % (
547 self.name, self.retval, self.parameters)
552 def __init__(self, name, symbol):
553 Node.__init__(self, name)
555 self.constructors = []
561 return 'Union(%r, %r)' % (self.name, self.fields, )