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.
22 from __future__ import absolute_import
23 from __future__ import division
24 from __future__ import print_function
25 from __future__ import unicode_literals
29 from itertools import chain
33 from .collections import OrderedDict
34 from .message import Position
35 from .utils import to_underscores
41 * A reference to a node (target_giname)
42 * A reference to a "fundamental" type like 'utf8'
43 * A "foreign" type - this can be any string."
44 If none are specified, then it's in an "unresolved" state. An
45 unresolved type can have two data sources; a "ctype" which comes
46 from a C type string, or a gtype_name (from g_type_name()).
52 target_fundamental=None,
55 _target_unknown=False,
60 self.gtype_name = gtype_name
61 self.origin_symbol = origin_symbol
63 assert isinstance(self, TypeUnknown)
64 elif target_fundamental:
65 assert target_giname is None
66 assert target_foreign is None
68 assert '.' in target_giname
69 assert target_fundamental is None
70 assert target_foreign is None
72 assert ctype is not None
73 assert target_giname is None
74 assert target_fundamental is None
76 assert (ctype is not None) or (gtype_name is not None)
77 self.target_fundamental = target_fundamental
78 self.target_giname = target_giname
79 self.target_foreign = target_foreign
80 self.is_const = is_const
81 self.complete_ctype = complete_ctype
85 return (self.target_fundamental or
90 def unresolved_string(self):
94 return self.gtype_name
95 elif self.target_giname:
96 return self.target_giname
101 def create_from_gtype_name(cls, gtype_name):
102 """Parse a GType name (as from g_type_name()), and return a
103 Type instance. Note that this function performs namespace lookup,
104 in contrast to the other create_type() functions."""
105 # First, is it a fundamental?
106 fundamental = type_names.get(gtype_name)
107 if fundamental is not None:
108 return cls(target_fundamental=fundamental.target_fundamental,
109 ctype=fundamental.ctype)
110 if gtype_name == 'GHashTable':
111 return Map(TYPE_ANY, TYPE_ANY, gtype_name=gtype_name)
112 elif gtype_name in ('GArray', 'GPtrArray', 'GByteArray'):
113 return Array('GLib.' + gtype_name[1:], TYPE_ANY,
114 gtype_name=gtype_name)
115 elif gtype_name == 'GStrv':
116 bare_utf8 = TYPE_STRING.clone()
117 bare_utf8.ctype = None
118 return Array(None, bare_utf8, ctype=None, gtype_name=gtype_name,
121 return cls(gtype_name=gtype_name)
123 def get_giname(self):
124 assert self.target_giname is not None
125 return self.target_giname.split('.')[1]
127 def _compare(self, other, op):
128 if self.target_fundamental:
129 return op(self.target_fundamental, other.target_fundamental)
130 elif self.target_giname:
131 return op(self.target_giname, other.target_giname)
132 elif self.target_foreign:
133 return op(self.target_foreign, other.target_foreign)
135 return op(self.ctype, other.ctype)
137 def __lt__(self, other):
138 return self._compare(other, operator.lt)
140 def __gt__(self, other):
141 return self._compare(other, operator.gt)
143 def __ge__(self, other):
144 return self._compare(other, operator.ge)
146 def __le__(self, other):
147 return self._compare(other, operator.le)
149 def __eq__(self, other):
150 return self._compare(other, operator.eq)
152 def __ne__(self, other):
153 return self._compare(other, operator.ne)
156 return hash((self.target_fundamental, self.target_giname,
157 self.target_foreign, self.ctype))
159 def is_equiv(self, typeval):
160 """Return True if the specified types are compatible at
161 an introspection level, disregarding their C types.
162 A sequence may be given for typeval, in which case
163 this function returns True if the type is compatible with
165 if isinstance(typeval, (list, tuple)):
167 if self.is_equiv(val):
170 return self == typeval
173 return Type(target_fundamental=self.target_fundamental,
174 target_giname=self.target_giname,
175 target_foreign=self.target_foreign,
177 is_const=self.is_const)
180 if self.target_fundamental:
181 return self.target_fundamental
182 elif self.target_giname:
183 return self.target_giname
184 elif self.target_foreign:
185 return self.target_foreign
188 if self.target_fundamental:
189 data = 'target_fundamental=%s, ' % (self.target_fundamental, )
190 elif self.target_giname:
191 data = 'target_giname=%s, ' % (self.target_giname, )
192 elif self.target_foreign:
193 data = 'target_foreign=%s, ' % (self.target_foreign, )
196 return '%s(%sctype=%s)' % (self.__class__.__name__, data, self.ctype)
199 class TypeUnknown(Type):
201 Type.__init__(self, _target_unknown=True)
203 # Fundamental types, two special ones
204 TYPE_NONE = Type(target_fundamental='none', ctype='void')
205 TYPE_ANY = Type(target_fundamental='gpointer', ctype='gpointer')
206 # Fundamental types, "Basic" types
207 TYPE_BOOLEAN = Type(target_fundamental='gboolean', ctype='gboolean')
208 TYPE_INT8 = Type(target_fundamental='gint8', ctype='gint8')
209 TYPE_UINT8 = Type(target_fundamental='guint8', ctype='guint8')
210 TYPE_INT16 = Type(target_fundamental='gint16', ctype='gint16')
211 TYPE_UINT16 = Type(target_fundamental='guint16', ctype='guint16')
212 TYPE_INT32 = Type(target_fundamental='gint32', ctype='gint32')
213 TYPE_UINT32 = Type(target_fundamental='guint32', ctype='guint32')
214 TYPE_INT64 = Type(target_fundamental='gint64', ctype='gint64')
215 TYPE_UINT64 = Type(target_fundamental='guint64', ctype='guint64')
216 TYPE_CHAR = Type(target_fundamental='gchar', ctype='gchar')
217 TYPE_SHORT = Type(target_fundamental='gshort', ctype='gshort')
218 TYPE_USHORT = Type(target_fundamental='gushort', ctype='gushort')
219 TYPE_INT = Type(target_fundamental='gint', ctype='gint')
220 TYPE_UINT = Type(target_fundamental='guint', ctype='guint')
221 TYPE_LONG = Type(target_fundamental='glong', ctype='glong')
222 TYPE_ULONG = Type(target_fundamental='gulong', ctype='gulong')
223 TYPE_SIZE = Type(target_fundamental='gsize', ctype='gsize')
224 TYPE_SSIZE = Type(target_fundamental='gssize', ctype='gssize')
225 TYPE_INTPTR = Type(target_fundamental='gintptr', ctype='gintptr')
226 TYPE_UINTPTR = Type(target_fundamental='guintptr', ctype='guintptr')
228 TYPE_LONG_LONG = Type(target_fundamental='long long', ctype='long long')
229 TYPE_LONG_ULONG = Type(target_fundamental='unsigned long long',
230 ctype='unsigned long long')
231 TYPE_FLOAT = Type(target_fundamental='gfloat', ctype='gfloat')
232 TYPE_DOUBLE = Type(target_fundamental='gdouble', ctype='gdouble')
234 TYPE_LONG_DOUBLE = Type(target_fundamental='long double',
236 TYPE_UNICHAR = Type(target_fundamental='gunichar', ctype='gunichar')
238 # C types with semantics overlaid
239 TYPE_GTYPE = Type(target_fundamental='GType', ctype='GType')
240 TYPE_STRING = Type(target_fundamental='utf8', ctype='gchar*')
241 TYPE_FILENAME = Type(target_fundamental='filename', ctype='gchar*')
243 TYPE_VALIST = Type(target_fundamental='va_list', ctype='va_list')
245 BASIC_TYPES = [TYPE_BOOLEAN, TYPE_INT8, TYPE_UINT8, TYPE_INT16,
246 TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_INT64,
247 TYPE_UINT64, TYPE_CHAR, TYPE_SHORT, TYPE_USHORT, TYPE_INT,
248 TYPE_UINT, TYPE_LONG, TYPE_ULONG, TYPE_SIZE, TYPE_SSIZE,
249 TYPE_LONG_LONG, TYPE_LONG_ULONG,
250 TYPE_FLOAT, TYPE_DOUBLE,
251 TYPE_LONG_DOUBLE, TYPE_UNICHAR, TYPE_GTYPE]
253 BASIC_GIR_TYPES = [TYPE_INTPTR, TYPE_UINTPTR]
254 BASIC_GIR_TYPES.extend(BASIC_TYPES)
256 GIR_TYPES = [TYPE_NONE, TYPE_ANY]
257 GIR_TYPES.extend(BASIC_GIR_TYPES)
258 GIR_TYPES.extend([TYPE_STRING, TYPE_FILENAME, TYPE_VALIST])
260 # These are the only basic types that are guaranteed to
261 # be as big as a pointer (and thus are allowed in GPtrArray)
262 POINTER_TYPES = [TYPE_ANY, TYPE_INTPTR, TYPE_UINTPTR]
264 INTROSPECTABLE_BASIC = list(GIR_TYPES)
265 for v in [TYPE_NONE, TYPE_ANY,
266 TYPE_LONG_LONG, TYPE_LONG_ULONG,
267 TYPE_LONG_DOUBLE, TYPE_VALIST]:
268 INTROSPECTABLE_BASIC.remove(v)
271 for typeval in GIR_TYPES:
272 type_names[typeval.target_fundamental] = typeval
273 basic_type_names = {}
274 for typeval in BASIC_GIR_TYPES:
275 basic_type_names[typeval.target_fundamental] = typeval
278 type_names['char'] = TYPE_CHAR
279 type_names['signed char'] = TYPE_INT8
280 type_names['unsigned char'] = TYPE_UINT8
281 type_names['short'] = TYPE_SHORT
282 type_names['signed short'] = TYPE_SHORT
283 type_names['unsigned short'] = TYPE_USHORT
284 type_names['int'] = TYPE_INT
285 type_names['signed int'] = TYPE_INT
286 type_names['unsigned short int'] = TYPE_USHORT
287 type_names['signed'] = TYPE_INT
288 type_names['unsigned int'] = TYPE_UINT
289 type_names['unsigned'] = TYPE_UINT
290 type_names['long'] = TYPE_LONG
291 type_names['signed long'] = TYPE_LONG
292 type_names['unsigned long'] = TYPE_ULONG
293 type_names['unsigned long int'] = TYPE_ULONG
294 type_names['float'] = TYPE_FLOAT
295 type_names['double'] = TYPE_DOUBLE
296 type_names['char*'] = TYPE_STRING
297 type_names['void*'] = TYPE_ANY
298 type_names['void'] = TYPE_NONE
299 # Also alias the signed one here
300 type_names['signed long long'] = TYPE_LONG_LONG
301 # C99 stdint exact width types
302 type_names['int8_t'] = TYPE_INT8
303 type_names['uint8_t'] = TYPE_UINT8
304 type_names['int16_t'] = TYPE_INT16
305 type_names['uint16_t'] = TYPE_UINT16
306 type_names['int32_t'] = TYPE_INT32
307 type_names['uint32_t'] = TYPE_UINT32
308 type_names['int64_t'] = TYPE_INT64
309 type_names['uint64_t'] = TYPE_UINT64
311 type_names['bool'] = TYPE_BOOLEAN
313 # A few additional GLib type aliases
314 type_names['guchar'] = TYPE_UINT8
315 type_names['gchararray'] = TYPE_STRING
316 type_names['gchar*'] = TYPE_STRING
317 type_names['goffset'] = TYPE_INT64
318 type_names['gunichar2'] = TYPE_UINT16
319 type_names['gsize'] = TYPE_SIZE
320 type_names['gssize'] = TYPE_SSIZE
321 type_names['gintptr'] = TYPE_INTPTR
322 type_names['guintptr'] = TYPE_UINTPTR
323 type_names['gconstpointer'] = TYPE_ANY
325 # We used to support these; continue to do so
326 type_names['any'] = TYPE_ANY
327 type_names['boolean'] = TYPE_BOOLEAN
328 type_names['uint'] = TYPE_UINT
329 type_names['ulong'] = TYPE_ULONG
331 # C stdio, used in GLib public headers; squash this for now here
332 # until we move scanning into GLib and can (skip)
333 type_names['FILE*'] = TYPE_ANY
335 # One off C unix type definitions; note some of these may be GNU Libc
336 # specific. If someone is actually bitten by this, feel free to do
337 # the required configure goop to determine their size and replace
340 # We don't want to encourage people to use these in their APIs because
341 # they compromise the platform-independence that GLib gives you.
342 # These are here mostly to avoid blowing when random platform-specific
343 # methods are added under #ifdefs inside GLib itself. We could just (skip)
344 # the relevant methods, but on the other hand, since these types are just
345 # integers it's easy enough to expand them.
346 type_names['size_t'] = type_names['gsize']
347 type_names['ssize_t'] = type_names['gssize']
348 type_names['time_t'] = TYPE_LONG
349 type_names['off_t'] = type_names['gsize']
350 type_names['pid_t'] = TYPE_INT
351 type_names['uid_t'] = TYPE_UINT
352 type_names['gid_t'] = TYPE_UINT
353 type_names['dev_t'] = TYPE_INT
354 type_names['socklen_t'] = TYPE_INT32
357 type_names['id'] = TYPE_ANY
360 PARAM_DIRECTION_IN = 'in'
361 PARAM_DIRECTION_OUT = 'out'
362 PARAM_DIRECTION_INOUT = 'inout'
364 PARAM_SCOPE_CALL = 'call'
365 PARAM_SCOPE_ASYNC = 'async'
366 PARAM_SCOPE_NOTIFIED = 'notified'
368 PARAM_TRANSFER_NONE = 'none'
369 PARAM_TRANSFER_CONTAINER = 'container'
370 PARAM_TRANSFER_FULL = 'full'
372 SIGNAL_FIRST = 'first'
374 SIGNAL_CLEANUP = 'cleanup'
375 SIGNAL_MUST_COLLECT = 'must-collect'
378 class Namespace(object):
379 def __init__(self, name, version, identifier_prefixes=None, symbol_prefixes=None):
381 self.version = version
382 if identifier_prefixes is not None:
383 self.identifier_prefixes = identifier_prefixes
385 self.identifier_prefixes = [name]
386 if symbol_prefixes is not None:
387 self.symbol_prefixes = symbol_prefixes
389 ps = self.identifier_prefixes
390 self.symbol_prefixes = [to_underscores(p).lower() for p in ps]
391 # cache upper-cased versions
392 self._ucase_symbol_prefixes = [p.upper() for p in self.symbol_prefixes]
393 self.names = OrderedDict() # Maps from GIName -> node
394 self.aliases = {} # Maps from GIName -> GIName
395 self.type_names = {} # Maps from GTName -> node
396 self.ctypes = {} # Maps from CType -> node
397 self.symbols = {} # Maps from function symbols -> Function
398 # Immediate includes only, not their transitive closure:
399 self.includes = set() # Include
400 self.shared_libraries = [] # str
401 self.c_includes = [] # str
402 self.exported_packages = [] # str
404 def type_from_name(self, name, ctype=None):
405 """Backwards compatibility method for older .gir files, which
406 only use the 'name' attribute. If name refers to a fundamental type,
407 create a Type object referncing it. If name is already a
408 fully-qualified GIName like 'Foo.Bar', returns a Type targeting it .
409 Otherwise a Type targeting name qualififed with the namespace name is
411 if name in type_names:
412 return Type(target_fundamental=name, ctype=ctype)
416 target = '%s.%s' % (self.name, name)
417 return Type(target_giname=target, ctype=ctype)
419 def track(self, node):
420 """Doesn't directly append the function to our own namespace,
421 but adds it to things like ctypes, symbols, and type_names.
423 assert isinstance(node, Node)
424 if node.namespace is self:
426 assert node.namespace is None
427 node.namespace = self
428 if isinstance(node, Alias):
429 self.aliases[node.name] = node
430 elif isinstance(node, Registered) and node.gtype_name is not None:
431 self.type_names[node.gtype_name] = node
432 elif isinstance(node, Function):
433 self.symbols[node.symbol] = node
434 if isinstance(node, (Compound, Class, Interface, Boxed)):
435 for fn in chain(node.methods, node.static_methods, node.constructors):
436 if not isinstance(fn, Function):
439 self.symbols[fn.symbol] = fn
440 if isinstance(node, (Compound, Class, Interface)):
441 for f in node.fields:
443 if isinstance(node, (Class, Interface)):
444 for m in chain(node.signals, node.properties):
446 if isinstance(node, (Enum, Bitfield)):
447 for fn in node.static_methods:
448 if not isinstance(fn, Function):
451 self.symbols[fn.symbol] = fn
452 for member in node.members:
453 member.namespace = self
454 self.symbols[member.symbol] = member
455 if hasattr(node, 'ctype'):
456 self.ctypes[node.ctype] = node
458 def append(self, node, replace=False):
459 previous = self.names.get(node.name)
460 if previous is not None:
462 raise ValueError("Namespace conflict: %r" % (node, ))
463 self.remove(previous)
466 self.names[node.name] = node
468 def remove(self, node):
469 if isinstance(node, Alias):
470 del self.aliases[node.name]
471 elif isinstance(node, Registered) and node.gtype_name is not None:
472 del self.type_names[node.gtype_name]
473 if hasattr(node, 'ctype'):
474 del self.ctypes[node.ctype]
475 if isinstance(node, Function):
476 del self.symbols[node.symbol]
477 node.namespace = None
478 self.names.pop(node.name, None)
480 def float(self, node):
481 """Like remove(), but doesn't unset the node's namespace
482 back-reference, and it's still possible to look up
483 functions via get_by_symbol()."""
484 if isinstance(node, Function):
487 self.symbols[symbol] = node
488 node.namespace = self
491 return iter(self.names)
494 return self.names.items()
497 return self.names.values()
500 return self.names.get(name)
502 def get_by_ctype(self, ctype):
503 return self.ctypes.get(ctype)
505 def get_by_symbol(self, symbol):
506 return self.symbols.get(symbol)
508 def walk(self, callback):
509 for node in self.values():
510 node.walk(callback, [])
513 class Include(object):
515 def __init__(self, name, version):
517 self.version = version
520 def from_string(cls, string):
521 return cls(*string.split('-', 1))
523 def _compare(self, other, op):
524 return op((self.name, self.version), (other.name, other.version))
526 def __lt__(self, other):
527 return self._compare(other, operator.lt)
529 def __gt__(self, other):
530 return self._compare(other, operator.gt)
532 def __ge__(self, other):
533 return self._compare(other, operator.ge)
535 def __le__(self, other):
536 return self._compare(other, operator.le)
538 def __eq__(self, other):
539 return self._compare(other, operator.eq)
541 def __ne__(self, other):
542 return self._compare(other, operator.ne)
545 return hash(str(self))
548 return '%s-%s' % (self.name, self.version)
551 class Annotated(object):
552 """An object which has a few generic metadata
556 self.version_doc = None
558 self.introspectable = True
559 self.attributes = OrderedDict()
560 self.stability = None
561 self.stability_doc = None
562 self.deprecated = None
563 self.deprecated_doc = None
567 class Node(Annotated):
568 """A node is a type of object which is uniquely identified by its
569 (namespace, name) pair. When combined with a ., this is called a
570 GIName. It's possible for nodes to contain or point to other nodes."""
572 c_name = property(lambda self: self.namespace.name + self.name if self.namespace else
574 gi_name = property(lambda self: '%s.%s' % (self.namespace.name, self.name))
576 def __init__(self, name=None):
577 Annotated.__init__(self)
578 self.namespace = None # Should be set later by Namespace.append()
581 self.file_positions = set()
584 def _get_parent(self):
585 if self._parent is not None:
588 return self.namespace
590 def _set_parent(self, value):
592 parent = property(_get_parent, _set_parent)
594 def create_type(self):
595 """Create a Type object referencing this node."""
596 assert self.namespace is not None
597 return Type(target_giname=('%s.%s' % (self.namespace.name, self.name)))
599 def _compare(self, other, op):
600 return op((self.namespace, self.name), (other.namespace, other.name))
602 def __lt__(self, other):
603 return self._compare(other, operator.lt)
605 def __gt__(self, other):
606 return self._compare(other, operator.gt)
608 def __ge__(self, other):
609 return self._compare(other, operator.ge)
611 def __le__(self, other):
612 return self._compare(other, operator.le)
614 def __eq__(self, other):
615 return self._compare(other, operator.eq)
617 def __ne__(self, other):
618 return self._compare(other, operator.ne)
621 return hash((self.namespace, self.name))
624 return "%s('%s')" % (self.__class__.__name__, self.name)
626 def inherit_file_positions(self, node):
627 self.file_positions.update(node.file_positions)
629 def add_file_position(self, position):
630 self.file_positions.add(position)
632 def add_symbol_reference(self, symbol):
633 if symbol.source_filename:
634 self.add_file_position(Position(symbol.source_filename, symbol.line))
636 def walk(self, callback, chain):
637 res = callback(self, chain)
638 assert res in (True, False), "Walk function must return boolean, not %r" % (res, )
642 self._walk(callback, chain)
645 def _walk(self, callback, chain):
650 """A node that (possibly) has gtype_name and get_type."""
651 def __init__(self, gtype_name, get_type):
652 assert (gtype_name is None and get_type is None) or \
653 (gtype_name is not None and get_type is not None)
654 self.gtype_name = gtype_name
655 self.get_type = get_type
658 class Callable(Node):
660 def __init__(self, name, retval, parameters, throws):
661 Node.__init__(self, name)
663 self.parameters = parameters
664 self.throws = not not throws
665 self.instance_parameter = None # Parameter
666 self.parent = None # A Class or Interface
668 def _get_retval(self):
671 def _set_retval(self, value):
673 if self._retval is not None:
674 self._retval.parent = self
675 retval = property(_get_retval, _set_retval)
677 def _get_instance_parameter(self):
678 return self._instance_parameter
680 def _set_instance_parameter(self, value):
681 self._instance_parameter = value
682 if value is not None:
684 instance_parameter = property(_get_instance_parameter,
685 _set_instance_parameter)
687 def _get_parameters(self):
688 return self._parameters
690 def _set_parameters(self, value):
691 self._parameters = value
692 for param in self._parameters:
694 parameters = property(_get_parameters, _set_parameters)
696 # Returns all parameters, including the instance parameter
698 def all_parameters(self):
699 if self.instance_parameter is not None:
700 return [self.instance_parameter] + self.parameters
702 return self.parameters
704 def get_parameter_index(self, name):
705 for i, parameter in enumerate(self.parameters):
706 if parameter.argname == name:
708 raise ValueError("Unknown argument %s" % (name, ))
710 def get_parameter(self, name):
711 for parameter in self.all_parameters:
712 if parameter.argname == name:
714 raise ValueError("Unknown argument %s" % (name, ))
717 class Function(Callable):
719 def __init__(self, name, retval, parameters, throws, symbol):
720 Callable.__init__(self, name, retval, parameters, throws)
722 self.is_method = False
723 self.is_constructor = False
724 self.shadowed_by = None # C symbol string
725 self.shadows = None # C symbol string
726 self.moved_to = None # namespaced function name string
727 self.internal_skipped = False # if True, this func will not be written to GIR
730 clone = copy.copy(self)
731 # copy the parameters array so a change to self.parameters does not
732 # influence clone.parameters.
733 clone.parameters = self.parameters[:]
734 for param in clone.parameters:
738 def is_type_meta_function(self):
740 if not (self.name.endswith('_get_type') or self.name.endswith('_get_gtype')):
743 # Doesn't have any parameters
748 rettype = self.retval.type
749 if (not rettype.is_equiv(TYPE_GTYPE) and rettype.target_giname != 'Gtk.Type'):
750 message.warn("function '%s' returns '%r', not a GType" % (self.name, rettype))
756 class ErrorQuarkFunction(Function):
758 def __init__(self, name, retval, parameters, throws, symbol, error_domain):
759 Function.__init__(self, name, retval, parameters, throws, symbol)
760 self.error_domain = error_domain
763 class VFunction(Callable):
765 def __init__(self, name, retval, parameters, throws):
766 Callable.__init__(self, name, retval, parameters, throws)
770 def from_callback(cls, name, cb):
771 obj = cls(name, cb.retval, cb.parameters[1:],
779 Type.__init__(self, '<varargs>', target_fundamental='<varargs>')
784 GLIB_ARRAY = 'GLib.Array'
785 GLIB_BYTEARRAY = 'GLib.ByteArray'
786 GLIB_PTRARRAY = 'GLib.PtrArray'
788 def __init__(self, array_type, element_type, **kwargs):
789 Type.__init__(self, target_fundamental='<array>',
791 if (array_type is None or array_type == self.C):
792 self.array_type = self.C
794 assert array_type in (self.GLIB_ARRAY,
796 self.GLIB_PTRARRAY), array_type
797 self.array_type = array_type
798 assert isinstance(element_type, Type)
799 self.element_type = element_type
800 self.zeroterminated = True
801 self.length_param_name = None
805 arr = Array(self.array_type, self.element_type)
806 arr.zeroterminated = self.zeroterminated
807 arr.length_param_name = self.length_param_name
814 def __init__(self, name, element_type, **kwargs):
815 Type.__init__(self, target_fundamental='<list>',
818 assert isinstance(element_type, Type)
819 self.element_type = element_type
822 return List(self.name, self.element_type)
827 def __init__(self, key_type, value_type, **kwargs):
828 Type.__init__(self, target_fundamental='<map>', **kwargs)
829 assert isinstance(key_type, Type)
830 self.key_type = key_type
831 assert isinstance(value_type, Type)
832 self.value_type = value_type
835 return Map(self.key_type, self.value_type)
840 def __init__(self, name, target, ctype=None):
841 Node.__init__(self, name)
846 class TypeContainer(Annotated):
847 """A fundamental base class for Return and Parameter."""
849 def __init__(self, typenode, nullable, not_nullable, transfer, direction):
850 Annotated.__init__(self)
852 self.nullable = nullable
853 self.not_nullable = not_nullable
854 self.direction = direction
855 if transfer is not None:
856 self.transfer = transfer
857 elif typenode.is_const:
858 self.transfer = PARAM_TRANSFER_NONE
863 class Parameter(TypeContainer):
864 """An argument to a function."""
866 def __init__(self, argname, typenode, direction=None,
867 transfer=None, nullable=False, optional=False,
868 allow_none=False, scope=None,
869 caller_allocates=False, not_nullable=False):
870 TypeContainer.__init__(self, typenode, nullable, not_nullable,
872 self.argname = argname
873 self.optional = optional
874 self.parent = None # A Callable
877 if self.direction == PARAM_DIRECTION_OUT:
883 self.caller_allocates = caller_allocates
884 self.closure_name = None
885 self.destroy_name = None
892 class Return(TypeContainer):
893 """A return value from a function."""
895 def __init__(self, rtype, nullable=False, not_nullable=False,
897 TypeContainer.__init__(self, rtype, nullable, not_nullable, transfer,
898 direction=PARAM_DIRECTION_OUT)
899 self.parent = None # A Callable
902 class Enum(Node, Registered):
904 def __init__(self, name, ctype,
907 c_symbol_prefix=None,
909 Node.__init__(self, name)
910 Registered.__init__(self, gtype_name, get_type)
911 self.c_symbol_prefix = c_symbol_prefix
913 self.members = members
914 for member in members:
916 # Associated error domain name
917 self.error_domain = None
918 self.static_methods = []
920 def _walk(self, callback, chain):
921 for meth in self.static_methods:
922 meth.walk(callback, chain)
925 class Bitfield(Node, Registered):
927 def __init__(self, name, ctype,
929 c_symbol_prefix=None,
932 Node.__init__(self, name)
933 Registered.__init__(self, gtype_name, get_type)
935 self.c_symbol_prefix = c_symbol_prefix
936 self.members = members
937 for member in members:
939 self.static_methods = []
941 def _walk(self, callback, chain):
942 for meth in self.static_methods:
943 meth.walk(callback, chain)
946 class Member(Annotated):
948 def __init__(self, name, value, symbol, nick):
949 Annotated.__init__(self)
956 def _compare(self, other, op):
957 return op(self.name, other.name)
959 def __lt__(self, other):
960 return self._compare(other, operator.lt)
962 def __gt__(self, other):
963 return self._compare(other, operator.gt)
965 def __ge__(self, other):
966 return self._compare(other, operator.ge)
968 def __le__(self, other):
969 return self._compare(other, operator.le)
971 def __eq__(self, other):
972 return self._compare(other, operator.eq)
974 def __ne__(self, other):
975 return self._compare(other, operator.ne)
978 return hash(self.name)
981 return "%s('%s')" % (self.__class__.__name__, self.name)
984 class Compound(Node, Registered):
985 def __init__(self, name,
989 c_symbol_prefix=None,
992 Node.__init__(self, name)
993 Registered.__init__(self, gtype_name, get_type)
996 self.static_methods = []
998 self.constructors = []
999 self.disguised = disguised
1000 self.gtype_name = gtype_name
1001 self.get_type = get_type
1002 self.c_symbol_prefix = c_symbol_prefix
1003 self.tag_name = tag_name
1005 def add_gtype(self, gtype_name, get_type):
1006 self.gtype_name = gtype_name
1007 self.get_type = get_type
1008 self.namespace.type_names[gtype_name] = self
1010 def _walk(self, callback, chain):
1011 for ctor in self.constructors:
1012 ctor.walk(callback, chain)
1013 for func in self.methods:
1014 func.walk(callback, chain)
1015 for func in self.static_methods:
1016 func.walk(callback, chain)
1017 for field in self.fields:
1018 if field.anonymous_node is not None:
1019 field.anonymous_node.walk(callback, chain)
1021 def get_field(self, name):
1022 for field in self.fields:
1023 if field.name == name:
1025 raise ValueError("Unknown field %s" % (name, ))
1027 def get_field_index(self, name):
1028 for i, field in enumerate(self.fields):
1029 if field.name == name:
1031 raise ValueError("Unknown field %s" % (name, ))
1034 class Field(Annotated):
1036 def __init__(self, name, typenode, readable, writable, bits=None,
1037 anonymous_node=None):
1038 Annotated.__init__(self)
1039 assert (typenode or anonymous_node)
1041 self.type = typenode
1042 self.readable = readable
1043 self.writable = writable
1045 self.anonymous_node = anonymous_node
1046 self.private = False
1047 self.namespace = None
1048 self.parent = None # a compound
1050 def _compare(self, other, op):
1051 return op(self.name, other.name)
1053 def __lt__(self, other):
1054 return self._compare(other, operator.lt)
1056 def __gt__(self, other):
1057 return self._compare(other, operator.gt)
1059 def __ge__(self, other):
1060 return self._compare(other, operator.ge)
1062 def __le__(self, other):
1063 return self._compare(other, operator.le)
1065 def __eq__(self, other):
1066 return self._compare(other, operator.eq)
1068 def __ne__(self, other):
1069 return self._compare(other, operator.ne)
1072 return hash(self.name)
1075 return "%s('%s')" % (self.__class__.__name__, self.name)
1078 class Record(Compound):
1080 def __init__(self, name,
1084 c_symbol_prefix=None,
1087 Compound.__init__(self, name,
1089 gtype_name=gtype_name,
1091 c_symbol_prefix=c_symbol_prefix,
1092 disguised=disguised,
1094 # If non-None, this record defines the FooClass C structure
1095 # for some Foo GObject (or similar for GInterface)
1096 self.is_gtype_struct_for = None
1099 class Union(Compound):
1101 def __init__(self, name,
1105 c_symbol_prefix=None,
1108 Compound.__init__(self, name,
1110 gtype_name=gtype_name,
1112 c_symbol_prefix=c_symbol_prefix,
1113 disguised=disguised,
1117 class Boxed(Node, Registered):
1118 """A boxed type with no known associated structure/union."""
1119 def __init__(self, name,
1122 c_symbol_prefix=None):
1123 assert gtype_name is not None
1124 assert get_type is not None
1125 Node.__init__(self, name)
1126 Registered.__init__(self, gtype_name, get_type)
1127 if get_type is not None:
1128 assert c_symbol_prefix is not None
1129 self.c_symbol_prefix = c_symbol_prefix
1130 self.constructors = []
1132 self.static_methods = []
1134 def _walk(self, callback, chain):
1135 for ctor in self.constructors:
1136 ctor.walk(callback, chain)
1137 for meth in self.methods:
1138 meth.walk(callback, chain)
1139 for meth in self.static_methods:
1140 meth.walk(callback, chain)
1143 class Signal(Callable):
1145 def __init__(self, name, retval, parameters, when=None,
1146 no_recurse=False, detailed=False, action=False,
1148 Callable.__init__(self, name, retval, parameters, False)
1150 self.no_recurse = no_recurse
1151 self.detailed = detailed
1152 self.action = action
1153 self.no_hooks = no_hooks
1156 class Class(Node, Registered):
1158 def __init__(self, name, parent_type,
1162 c_symbol_prefix=None,
1164 Node.__init__(self, name)
1165 Registered.__init__(self, gtype_name, get_type)
1167 self.c_symbol_prefix = c_symbol_prefix
1168 self.parent_type = parent_type
1169 self.fundamental = False
1170 self.unref_func = None
1171 self.ref_func = None
1172 self.set_value_func = None
1173 self.get_value_func = None
1174 # When we're in the scanner, we keep around a list
1175 # of parents so that we can transparently fall back
1176 # if there are 'hidden' parents
1177 self.parent_chain = []
1178 self.glib_type_struct = None
1179 self.is_abstract = is_abstract
1181 self.virtual_methods = []
1182 self.static_methods = []
1183 self.interfaces = []
1184 self.constructors = []
1185 self.properties = []
1189 def _walk(self, callback, chain):
1190 for meth in self.methods:
1191 meth.walk(callback, chain)
1192 for meth in self.virtual_methods:
1193 meth.walk(callback, chain)
1194 for meth in self.static_methods:
1195 meth.walk(callback, chain)
1196 for ctor in self.constructors:
1197 ctor.walk(callback, chain)
1198 for field in self.fields:
1199 if field.anonymous_node:
1200 field.anonymous_node.walk(callback, chain)
1201 for sig in self.signals:
1202 sig.walk(callback, chain)
1203 for prop in self.properties:
1204 prop.walk(callback, chain)
1207 class Interface(Node, Registered):
1209 def __init__(self, name, parent_type,
1213 c_symbol_prefix=None):
1214 Node.__init__(self, name)
1215 Registered.__init__(self, gtype_name, get_type)
1217 self.c_symbol_prefix = c_symbol_prefix
1218 self.parent_type = parent_type
1219 self.parent_chain = []
1222 self.static_methods = []
1223 self.virtual_methods = []
1224 self.glib_type_struct = None
1225 self.properties = []
1227 self.prerequisites = []
1228 # Not used yet, exists just to avoid an exception in
1229 # Namespace.append()
1230 self.constructors = []
1232 def _walk(self, callback, chain):
1233 for meth in self.methods:
1234 meth.walk(callback, chain)
1235 for meth in self.static_methods:
1236 meth.walk(callback, chain)
1237 for meth in self.virtual_methods:
1238 meth.walk(callback, chain)
1239 for field in self.fields:
1240 if field.anonymous_node:
1241 field.anonymous_node.walk(callback, chain)
1242 for sig in self.signals:
1243 sig.walk(callback, chain)
1246 class Constant(Node):
1248 def __init__(self, name, value_type, value, ctype):
1249 Node.__init__(self, name)
1250 self.value_type = value_type
1255 class Property(Node):
1257 def __init__(self, name, typeobj, readable, writable,
1258 construct, construct_only, transfer=None):
1259 Node.__init__(self, name)
1261 self.readable = readable
1262 self.writable = writable
1263 self.construct = construct
1264 self.construct_only = construct_only
1265 if transfer is None:
1266 self.transfer = PARAM_TRANSFER_NONE
1268 self.transfer = transfer
1269 self.parent = None # A Class or Interface
1272 class Callback(Callable):
1274 def __init__(self, name, retval, parameters, throws, ctype=None):
1275 Callable.__init__(self, name, retval, parameters, throws)