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['unsigned short int'] = TYPE_USHORT
107 type_names['signed'] = TYPE_INT
108 type_names['unsigned int'] = TYPE_UINT
109 type_names['unsigned'] = TYPE_UINT
110 type_names['long'] = TYPE_LONG
111 type_names['signed long'] = TYPE_LONG
112 type_names['unsigned long'] = TYPE_ULONG
113 type_names['unsigned long int'] = TYPE_ULONG
114 type_names['float'] = TYPE_FLOAT
115 type_names['double'] = TYPE_DOUBLE
116 type_names['char*'] = TYPE_STRING
117 type_names['void*'] = TYPE_ANY
118 type_names['void'] = TYPE_NONE
120 # Unix types that we special case here (and that have their own introspection
121 # type tag) because of wide use in GLib.
122 type_names['size_t'] = TYPE_SIZET
123 type_names['ssize_t'] = TYPE_SSIZET
125 # One off C unix type definitions; note some of these may be GNU Libc
126 # specific. If someone is actually bitten by this, feel free to do
127 # the required configure goop to determine their size and replace
130 # We don't want to encourage people to use these in their APIs because
131 # they compromise the platform-independence that GLib gives you.
132 # These are here mostly to avoid blowing when random platform-specific
133 # methods are added under #ifdefs inside GLib itself. We could just (skip)
134 # the relevant methods, but on the other hand, since these types are just
135 # integers it's easy enough to expand them.
136 type_names['off_t'] = TYPE_SIZET
137 type_names['pid_t'] = TYPE_INT
138 type_names['uid_t'] = TYPE_UINT
139 type_names['gid_t'] = TYPE_UINT
140 type_names['dev_t'] = TYPE_INT
141 type_names['socklen_t'] = TYPE_INT32
144 type_names['id'] = TYPE_ANY
146 # Suppress some GLib names
147 type_names['uchar'] = TYPE_UINT8
148 type_names['ushort'] = TYPE_USHORT
149 type_names['size'] = TYPE_SIZET
150 type_names['ssize'] = TYPE_SSIZET
151 type_names['pointer'] = TYPE_ANY
152 type_names['constpointer'] = TYPE_ANY
155 # These types, when seen by reference, are converted into an Array()
157 # If you add/change these, be sure to update glibast.py too
158 default_array_types = {}
159 default_array_types['uint8*'] = TYPE_UINT8
160 default_array_types['utf8*'] = TYPE_STRING
162 # These types, when seen by reference, are interpreted as out parameters
163 default_out_types = (TYPE_SHORT, TYPE_USHORT, TYPE_INT, TYPE_UINT,
164 TYPE_LONG, TYPE_ULONG, TYPE_FLOAT, TYPE_DOUBLE,
165 TYPE_SIZET, TYPE_SSIZET)
168 def type_name_from_ctype(ctype):
169 return type_names.get(ctype, ctype)
174 def __init__(self, name=None):
176 self.attributes = [] # (key, value)*
178 self.deprecated = None
179 self.deprecated_version = None
183 def __cmp__(self, other):
184 return cmp(self.name, other.name)
187 return '%s(%r)' % (self.__class__.__name__, self.name)
189 def remove_matching_children(self, pred):
192 class Namespace(Node):
194 def __init__(self, name, version):
195 Node.__init__(self, name)
196 self.version = version
200 return '%s(%r, %r, %r)' % (self.__class__.__name__, self.name,
201 self.version, self.nodes)
203 def remove_matching(self, pred):
205 def recursive_pred(node):
206 node.remove_matching_children(pred)
209 self.nodes = filter(recursive_pred, self.nodes)
213 def __init__(self, name, version):
214 Node.__init__(self, 'include')
216 self.version = version
219 def from_string(self, string):
220 return Include(*string.split('-', 1))
222 def __cmp__(self, other):
223 if not isinstance(other, Include):
224 return cmp(self, other)
225 namecmp = cmp(self.name, other.name)
228 return cmp(self.version, other.version)
231 return hash((self.name, self.version))
234 return '%s-%s' % (self.name, self.version)
236 class Callable(Node):
238 def __init__(self, name, retval, parameters, throws):
239 Node.__init__(self, name)
241 self.parameters = parameters
242 self.throws = not not throws
246 return '%s(%r, %r, %r)' % (self.__class__.__name__,
247 self.name, self.retval,
250 class Function(Callable):
252 def __init__(self, name, retval, parameters, symbol, throws=None):
253 Callable.__init__(self, name, retval, parameters, throws)
255 self.is_method = False
258 def get_parameter_index(self, name):
259 for i, parameter in enumerate(self.parameters):
260 if parameter.name == name:
261 return i + int(self.is_method)
263 def get_parameter(self, name):
264 for parameter in self.parameters:
265 if parameter.name == name:
269 class VFunction(Callable):
271 def __init__(self, name, retval, parameters, throws):
272 Callable.__init__(self, name, retval, parameters, throws)
276 def from_callback(cls, cb):
277 obj = cls(cb.name, cb.retval, cb.parameters[1:],
284 def __init__(self, name, ctype=None):
285 Node.__init__(self, name)
287 self.resolved = False
288 self.is_const = False
289 self.canonical = None
290 self.derefed_canonical = None
296 Type.__init__(self, '<varargs>')
301 def __init__(self, name, ctype, element_type):
304 Type.__init__(self, name, ctype)
305 self.element_type = element_type
306 self.zeroterminated = True
307 self.length_param_index = -1
308 self.length_param_name = None
312 return 'Array(%r, %r)' % (self.name, self.element_type, )
317 def __init__(self, name, ctype, element_type):
318 Type.__init__(self, name, ctype)
319 self.element_type = element_type
322 return 'List(%r of %r)' % (self.name, self.element_type, )
327 def __init__(self, name, ctype, key_type, value_type):
328 Type.__init__(self, name, ctype)
329 self.key_type = key_type
330 self.value_type = value_type
333 return 'Map(%r <%r,%r>)' % (self.name, self.key_type, self.value_type)
338 def __init__(self, name, target, ctype=None):
339 Node.__init__(self, name)
344 return 'Alias(%r, %r)' % (self.name, self.target)
347 class TypeContainer(Node):
349 def __init__(self, name, typenode, transfer):
350 Node.__init__(self, name)
352 if transfer in [PARAM_TRANSFER_NONE, PARAM_TRANSFER_CONTAINER,
353 PARAM_TRANSFER_FULL]:
354 self.transfer = transfer
359 class Parameter(TypeContainer):
361 def __init__(self, name, typenode, direction=None,
362 transfer=None, allow_none=False, scope=None):
363 TypeContainer.__init__(self, name, typenode, transfer)
364 if direction in [PARAM_DIRECTION_IN, PARAM_DIRECTION_OUT,
365 PARAM_DIRECTION_INOUT, None]:
366 self.direction = direction
368 self.direction = PARAM_DIRECTION_IN
370 self.caller_allocates = False
371 self.allow_none = allow_none
373 self.closure_index = -1
374 self.destroy_index = -1
378 return 'Parameter(%r, %r)' % (self.name, self.type)
383 def __init__(self, name, symbol, members):
384 Node.__init__(self, name)
386 self.members = members
390 return 'Enum(%r, %r)' % (self.name, self.members)
393 class Bitfield(Node):
395 def __init__(self, name, symbol, members):
396 Node.__init__(self, name)
398 self.members = members
402 return 'Bitfield(%r, %r)' % (self.name, self.members)
407 def __init__(self, name, value, symbol):
408 Node.__init__(self, name)
413 return 'Member(%r, %r)' % (self.name, self.value)
418 def __init__(self, name, symbol, disguised=False):
419 Node.__init__(self, name)
421 self.constructors = []
423 self.disguised = disguised
427 def remove_matching_children(self, pred):
428 self.fields = filter(pred, self.fields)
429 self.constructors = filter(pred, self.constructors)
430 self.methods = filter(pred, self.methods)
438 def __init__(self, name, typenode, symbol, readable, writable, bits=None):
439 Node.__init__(self, name)
442 self.readable = readable
443 self.writable = writable
448 return 'Field(%r, %r, %r)' % (self.name, self.type, self.bits)
450 return 'Field(%r, %r)' % (self.name, self.type)
453 class Return(TypeContainer):
455 def __init__(self, rtype, transfer=None):
456 TypeContainer.__init__(self, None, rtype, transfer)
457 self.direction = PARAM_DIRECTION_OUT
461 return 'Return(%r)' % (self.type, )
466 def __init__(self, name, parent, is_abstract):
467 Node.__init__(self, name)
470 self.glib_type_struct = None
471 self.is_abstract = is_abstract
473 self.virtual_methods = []
474 self.static_methods = []
476 self.constructors = []
481 def remove_matching_children(self, pred):
482 self.methods = filter(pred, self.methods)
483 self.constructors = filter(pred, self.constructors)
484 self.properties = filter(pred, self.properties)
485 self.fields = filter(pred, self.fields)
488 return '%s(%r, %r, %r)' % (
489 self.__class__.__name__,
490 self.name, self.parent, self.methods)
493 class Interface(Node):
495 def __init__(self, name, parent):
496 Node.__init__(self, name)
499 self.virtual_methods = []
500 self.glib_type_struct = None
503 self.prerequisites = []
507 return '%s(%r, %r)' % (
508 self.__class__.__name__,
509 self.name, self.methods)
512 class Constant(Node):
514 def __init__(self, name, type_name, value):
515 Node.__init__(self, name)
516 self.type = Type(type_name)
520 return 'Constant(%r, %r, %r)' % (
521 self.name, self.type, self.value)
524 class Property(TypeContainer):
526 def __init__(self, name, type_name, readable, writable,
527 construct, construct_only, ctype=None, transfer=None):
528 self.type = Type(type_name, ctype)
529 TypeContainer.__init__(self, name, self.type, transfer)
530 self.readable = readable
531 self.writable = writable
532 self.construct = construct
533 self.construct_only = construct_only
537 return '%s(%r, %r)' % (
538 self.__class__.__name__,
539 self.name, self.type)
542 # FIXME: Inherit from Function
545 class Callback(Node):
547 def __init__(self, name, retval, parameters, ctype=None):
548 Node.__init__(self, name)
550 self.parameters = parameters
555 def get_parameter_index(self, name):
556 for i, parameter in enumerate(self.parameters):
557 if parameter.name == name:
560 def get_parameter(self, name):
561 for parameter in self.parameters:
562 if parameter.name == name:
566 return 'Callback(%r, %r, %r)' % (
567 self.name, self.retval, self.parameters)
572 def __init__(self, name, symbol):
573 Node.__init__(self, name)
575 self.constructors = []
581 return 'Union(%r, %r)' % (self.name, self.fields, )