Add signal flags
[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 # Copyright (C) 2008, 2009 Red Hat, Inc.
5 #
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.
10 #
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.
15 #
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.
20 #
21
22 from .message import Position
23 from .odict import odict
24 from .utils import to_underscores
25
26 class Type(object):
27     """A Type can be either:
28 * A reference to a node (target_giname)
29 * A reference to a "fundamental" type like 'utf8'
30 * A "foreign" type - this can be any string."
31 If none are specified, then it's in an "unresolved" state.  An
32 unresolved type can have two data sources; a "ctype" which comes
33 from a C type string, or a gtype_name (from g_type_name()).
34 """ # '''
35
36     def __init__(self,
37                  ctype=None,
38                  gtype_name=None,
39                  target_fundamental=None,
40                  target_giname=None,
41                  target_foreign=None,
42                  _target_unknown=False,
43                  is_const=False,
44                  origin_symbol=None):
45         self.ctype = ctype
46         self.gtype_name = gtype_name
47         self.origin_symbol = origin_symbol
48         if _target_unknown:
49             assert isinstance(self, TypeUnknown)
50         elif target_fundamental:
51             assert target_giname is None
52             assert target_foreign is None
53         elif target_giname:
54             assert '.' in target_giname
55             assert target_fundamental is None
56             assert target_foreign is None
57         elif target_foreign:
58             assert ctype is not None
59             assert target_giname is None
60             assert target_fundamental is None
61         else:
62             assert (ctype is not None) or (gtype_name is not None)
63         self.target_fundamental = target_fundamental
64         self.target_giname = target_giname
65         self.target_foreign = target_foreign
66         self.is_const = is_const
67
68     @property
69     def resolved(self):
70         return (self.target_fundamental or
71                 self.target_giname or
72                 self.target_foreign)
73
74     @property
75     def unresolved_string(self):
76         if self.ctype:
77             return self.ctype
78         elif self.gtype_name:
79             return self.gtype_name
80         else:
81             assert False
82
83     @classmethod
84     def create_from_gtype_name(cls, gtype_name):
85         """Parse a GType name (as from g_type_name()), and return a
86 Type instance.  Note that this function performs namespace lookup,
87 in contrast to the other create_type() functions."""
88         # First, is it a fundamental?
89         fundamental = type_names.get(gtype_name)
90         if fundamental is not None:
91             return cls(target_fundamental=fundamental.target_fundamental)
92         if gtype_name == 'GHashTable':
93             return Map(TYPE_ANY, TYPE_ANY, gtype_name=gtype_name)
94         elif gtype_name in ('GArray', 'GPtrArray', 'GByteArray'):
95             return Array('GLib.' + gtype_name[1:], TYPE_ANY,
96                          gtype_name=gtype_name)
97         elif gtype_name == 'GStrv':
98             bare_utf8 = TYPE_STRING.clone()
99             bare_utf8.ctype = None
100             return Array(None, bare_utf8, ctype=None, gtype_name=gtype_name,
101                          is_const=False)
102
103         # Workaround for Gdk.Rectangle being boxed alias for
104         # cairo.RectangleInt.  G-I does not support boxing of aliases.
105         # See https://bugzilla.gnome.org/show_bug.cgi?id=655423
106         if gtype_name == 'GdkRectangle':
107             gtype_name = 'CairoRectangleInt'
108
109         return cls(gtype_name=gtype_name)
110
111     def get_giname(self):
112         assert self.target_giname is not None
113         return self.target_giname.split('.')[1]
114
115     def __cmp__(self, other):
116         if self.target_fundamental:
117             return cmp(self.target_fundamental, other.target_fundamental)
118         if self.target_giname:
119             return cmp(self.target_giname, other.target_giname)
120         if self.target_foreign:
121             return cmp(self.target_foreign, other.target_foreign)
122         return cmp(self.ctype, other.ctype)
123
124     def is_equiv(self, typeval):
125         """Return True if the specified types are compatible at
126         an introspection level, disregarding their C types.
127         A sequence may be given for typeval, in which case
128         this function returns True if the type is compatible with
129         any."""
130         if isinstance(typeval, (list, tuple)):
131             for val in typeval:
132                 if self.is_equiv(val):
133                     return True
134             return False
135         return self == typeval
136
137     def clone(self):
138         return Type(target_fundamental=self.target_fundamental,
139                     target_giname=self.target_giname,
140                     target_foreign=self.target_foreign,
141                     ctype=self.ctype,
142                     is_const=self.is_const)
143
144     def __str__(self):
145         if self.target_fundamental:
146             return self.target_fundamental
147         elif self.target_giname:
148             return self.target_giname
149         elif self.target_foreign:
150             return self.target_foreign
151
152     def __repr__(self):
153         if self.target_fundamental:
154             data = 'target_fundamental=%s, ' % (self.target_fundamental, )
155         elif self.target_giname:
156             data = 'target_giname=%s, ' % (self.target_giname, )
157         elif self.target_foreign:
158             data = 'target_foreign=%s, ' % (self.target_foreign, )
159         else:
160             data = ''
161         return '%s(%sctype=%s)' % (self.__class__.__name__, data, self.ctype)
162
163 class TypeUnknown(Type):
164     def __init__(self):
165         Type.__init__(self, _target_unknown=True)
166
167 ######
168 ## Fundamental types
169 ######
170 # Two special ones
171 TYPE_NONE = Type(target_fundamental='none', ctype='void')
172 TYPE_ANY = Type(target_fundamental='gpointer', ctype='gpointer')
173 # "Basic" types
174 TYPE_BOOLEAN = Type(target_fundamental='gboolean', ctype='gboolean')
175 TYPE_INT8 = Type(target_fundamental='gint8', ctype='gint8')
176 TYPE_UINT8 = Type(target_fundamental='guint8', ctype='guint8')
177 TYPE_INT16 = Type(target_fundamental='gint16', ctype='gint16')
178 TYPE_UINT16 = Type(target_fundamental='guint16', ctype='guint16')
179 TYPE_INT32 = Type(target_fundamental='gint32', ctype='gint32')
180 TYPE_UINT32 = Type(target_fundamental='guint32', ctype='guint32')
181 TYPE_INT64 = Type(target_fundamental='gint64', ctype='gint64')
182 TYPE_UINT64 = Type(target_fundamental='guint64', ctype='guint64')
183 TYPE_CHAR = Type(target_fundamental='gchar', ctype='gchar')
184 TYPE_SHORT = Type(target_fundamental='gshort', ctype='gshort')
185 TYPE_USHORT = Type(target_fundamental='gushort', ctype='gushort')
186 TYPE_INT = Type(target_fundamental='gint', ctype='gint')
187 TYPE_UINT = Type(target_fundamental='guint', ctype='guint')
188 TYPE_LONG = Type(target_fundamental='glong', ctype='glong')
189 TYPE_ULONG = Type(target_fundamental='gulong', ctype='gulong')
190 TYPE_SIZE = Type(target_fundamental='gsize', ctype='gsize')
191 TYPE_SSIZE = Type(target_fundamental='gssize', ctype='gssize')
192 TYPE_INTPTR = Type(target_fundamental='gintptr', ctype='gintptr')
193 TYPE_UINTPTR = Type(target_fundamental='guintptr', ctype='guintptr')
194 # C99 types
195 TYPE_LONG_LONG = Type(target_fundamental='long long', ctype='long long')
196 TYPE_LONG_ULONG = Type(target_fundamental='unsigned long long',
197                        ctype='unsigned long long')
198 TYPE_FLOAT = Type(target_fundamental='gfloat', ctype='gfloat')
199 TYPE_DOUBLE = Type(target_fundamental='gdouble', ctype='gdouble')
200 # ?
201 TYPE_LONG_DOUBLE = Type(target_fundamental='long double',
202                         ctype='long double')
203 TYPE_UNICHAR = Type(target_fundamental='gunichar', ctype='gunichar')
204
205 # C types with semantics overlaid
206 TYPE_GTYPE = Type(target_fundamental='GType', ctype='GType')
207 TYPE_STRING = Type(target_fundamental='utf8', ctype='gchar*')
208 TYPE_FILENAME = Type(target_fundamental='filename', ctype='gchar*')
209
210 TYPE_VALIST = Type(target_fundamental='va_list', ctype='va_list')
211
212 BASIC_GIR_TYPES = [TYPE_BOOLEAN, TYPE_INT8, TYPE_UINT8, TYPE_INT16,
213                    TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_INT64,
214                    TYPE_UINT64, TYPE_CHAR, TYPE_SHORT, TYPE_USHORT, TYPE_INT,
215                    TYPE_UINT, TYPE_LONG, TYPE_ULONG, TYPE_SIZE, TYPE_SSIZE,
216                    TYPE_LONG_LONG, TYPE_LONG_ULONG, TYPE_INTPTR, TYPE_UINTPTR,
217                    TYPE_FLOAT, TYPE_DOUBLE,
218                    TYPE_LONG_DOUBLE, TYPE_UNICHAR, TYPE_GTYPE]
219 GIR_TYPES = [TYPE_NONE, TYPE_ANY]
220 GIR_TYPES.extend(BASIC_GIR_TYPES)
221 GIR_TYPES.extend([TYPE_STRING, TYPE_FILENAME, TYPE_VALIST])
222
223 INTROSPECTABLE_BASIC = list(GIR_TYPES)
224 for v in [TYPE_NONE, TYPE_ANY,
225           TYPE_LONG_LONG, TYPE_LONG_ULONG,
226           TYPE_LONG_DOUBLE, TYPE_VALIST]:
227     INTROSPECTABLE_BASIC.remove(v)
228
229 type_names = {}
230 for typeval in GIR_TYPES:
231     type_names[typeval.target_fundamental] = typeval
232 basic_type_names = {}
233 for typeval in BASIC_GIR_TYPES:
234     basic_type_names[typeval.target_fundamental] = typeval
235
236 # C builtin
237 type_names['char'] = TYPE_CHAR
238 type_names['signed char'] = TYPE_INT8
239 type_names['unsigned char'] = TYPE_UINT8
240 type_names['short'] = TYPE_SHORT
241 type_names['signed short'] = TYPE_SHORT
242 type_names['unsigned short'] = TYPE_USHORT
243 type_names['int'] = TYPE_INT
244 type_names['signed int'] = TYPE_INT
245 type_names['unsigned short int'] = TYPE_USHORT
246 type_names['signed'] = TYPE_INT
247 type_names['unsigned int'] = TYPE_UINT
248 type_names['unsigned'] = TYPE_UINT
249 type_names['long'] = TYPE_LONG
250 type_names['signed long'] = TYPE_LONG
251 type_names['unsigned long'] = TYPE_ULONG
252 type_names['unsigned long int'] = TYPE_ULONG
253 type_names['float'] = TYPE_FLOAT
254 type_names['double'] = TYPE_DOUBLE
255 type_names['char*'] = TYPE_STRING
256 type_names['void*'] = TYPE_ANY
257 type_names['void'] = TYPE_NONE
258 # Also alias the signed one here
259 type_names['signed long long'] = TYPE_LONG_LONG
260
261 # A few additional GLib type aliases
262 type_names['guchar'] = TYPE_UINT8
263 type_names['gchararray'] = TYPE_STRING
264 type_names['gchar*'] = TYPE_STRING
265 type_names['goffset'] = TYPE_INT64
266 type_names['gunichar2'] = TYPE_UINT16
267 type_names['gsize'] = TYPE_SIZE
268 type_names['gssize'] = TYPE_SSIZE
269 type_names['gintptr'] = TYPE_INTPTR
270 type_names['guintptr'] = TYPE_UINTPTR
271 type_names['gconstpointer'] = TYPE_ANY
272
273 # We used to support these; continue to do so
274 type_names['any'] = TYPE_ANY
275 type_names['boolean'] = TYPE_BOOLEAN
276 type_names['uint'] = TYPE_UINT
277 type_names['ulong'] = TYPE_ULONG
278
279 # C stdio, used in GLib public headers; squash this for now here
280 # until we move scanning into GLib and can (skip)
281 type_names['FILE*'] = TYPE_ANY
282
283 # One off C unix type definitions; note some of these may be GNU Libc
284 # specific.  If someone is actually bitten by this, feel free to do
285 # the required configure goop to determine their size and replace
286 # here.
287 #
288 # We don't want to encourage people to use these in their APIs because
289 # they compromise the platform-independence that GLib gives you.
290 # These are here mostly to avoid blowing when random platform-specific
291 # methods are added under #ifdefs inside GLib itself.  We could just (skip)
292 # the relevant methods, but on the other hand, since these types are just
293 # integers it's easy enough to expand them.
294 type_names['size_t'] = type_names['gsize']
295 type_names['time_t'] = TYPE_LONG
296 type_names['off_t'] = type_names['gsize']
297 type_names['pid_t'] = TYPE_INT
298 type_names['uid_t'] = TYPE_UINT
299 type_names['gid_t'] = TYPE_UINT
300 type_names['dev_t'] = TYPE_INT
301 type_names['socklen_t'] = TYPE_INT32
302 type_names['size_t'] = TYPE_ULONG
303 type_names['ssize_t'] = TYPE_LONG
304
305 # Obj-C
306 type_names['id'] = TYPE_ANY
307
308 ##
309 ## Parameters
310 ##
311
312 PARAM_DIRECTION_IN = 'in'
313 PARAM_DIRECTION_OUT = 'out'
314 PARAM_DIRECTION_INOUT = 'inout'
315
316 PARAM_SCOPE_CALL = 'call'
317 PARAM_SCOPE_ASYNC = 'async'
318 PARAM_SCOPE_NOTIFIED = 'notified'
319
320 PARAM_TRANSFER_NONE = 'none'
321 PARAM_TRANSFER_CONTAINER = 'container'
322 PARAM_TRANSFER_FULL = 'full'
323
324 SIGNAL_FIRST = 'first'
325 SIGNAL_LAST = 'last'
326 SIGNAL_CLEANUP = 'cleanup'
327 SIGNAL_MUST_COLLECT = 'must-collect'
328
329
330 class Namespace(object):
331     def __init__(self, name, version,
332                  identifier_prefixes=None,
333                  symbol_prefixes=None):
334         self.name = name
335         self.version = version
336         if identifier_prefixes is not None:
337             self.identifier_prefixes = identifier_prefixes
338         else:
339             self.identifier_prefixes = [name]
340         if symbol_prefixes is not None:
341             self.symbol_prefixes = symbol_prefixes
342         else:
343             ps = self.identifier_prefixes
344             self.symbol_prefixes = [to_underscores(p).lower() for p in ps]
345         # cache upper-cased versions
346         self._ucase_symbol_prefixes = [p.upper() for p in self.symbol_prefixes]
347         self._names = odict() # Maps from GIName -> node
348         self._aliases = {} # Maps from GIName -> GIName
349         self._type_names = {} # Maps from GTName -> node
350         self._ctypes = {} # Maps from CType -> node
351         self._symbols = {} # Maps from function symbols -> Function
352
353     @property
354     def names(self):
355         return self._names
356
357     @property
358     def aliases(self):
359         return self._aliases
360
361     @property
362     def type_names(self):
363         return self._type_names
364
365     @property
366     def ctypes(self):
367         return self._ctypes
368
369     def type_from_name(self, name, ctype=None):
370         """Backwards compatibility method for older .gir files, which
371 only use the 'name' attribute.  If name refers to a fundamental type,
372 create a Type object referncing it.  If name is already a
373 fully-qualified GIName like 'Foo.Bar', returns a Type targeting it .
374 Otherwise a Type targeting name qualififed with the namespace name is
375 returned."""
376         if name in type_names:
377             return Type(target_fundamental=name, ctype=ctype)
378         if '.' in name:
379             target = name
380         else:
381             target = '%s.%s' % (self.name, name)
382         return Type(target_giname=target, ctype=ctype)
383
384     def append(self, node, replace=False):
385         previous = self._names.get(node.name)
386         if previous is not None:
387             if not replace:
388                 raise ValueError("Namespace conflict: %r" % (node, ))
389             self.remove(previous)
390         # A layering violation...but oh well.
391         if isinstance(node, Alias):
392             self._aliases[node.name] = node
393         elif isinstance(node, Registered) and node.gtype_name is not None:
394             self._type_names[node.gtype_name] = node
395         elif isinstance(node, Function):
396             self._symbols[node.symbol] = node
397         assert isinstance(node, Node)
398         assert node.namespace is None
399         node.namespace = self
400         self._names[node.name] = node
401         if hasattr(node, 'ctype'):
402             self._ctypes[node.ctype] = node
403         if hasattr(node, 'symbol'):
404             self._ctypes[node.symbol] = node
405
406     def remove(self, node):
407         if isinstance(node, Alias):
408             del self._aliases[node.name]
409         elif isinstance(node, Registered) and node.gtype_name is not None:
410             del self._type_names[node.gtype_name]
411         del self._names[node.name]
412         node.namespace = None
413         if hasattr(node, 'ctype'):
414             del self._ctypes[node.ctype]
415         if isinstance(node, Function):
416             del self._symbols[node.symbol]
417
418     def float(self, node):
419         """Like remove(), but doesn't unset the node's namespace
420 back-reference, and it's still possible to look up
421 functions via get_by_symbol()."""
422         if isinstance(node, Function):
423             symbol = node.symbol
424         self.remove(node)
425         self._symbols[symbol] = node
426         node.namespace = self
427
428     def __iter__(self):
429         return iter(self._names)
430
431     def iteritems(self):
432         return self._names.iteritems()
433
434     def itervalues(self):
435         return self._names.itervalues()
436
437     def get(self, name):
438         return self._names.get(name)
439
440     def get_by_ctype(self, ctype):
441         return self._ctypes.get(ctype)
442
443     def get_by_symbol(self, symbol):
444         return self._symbols.get(symbol)
445
446     def walk(self, callback):
447         for node in self.itervalues():
448             node.walk(callback, [])
449
450 class Include(object):
451
452     def __init__(self, name, version):
453         self.name = name
454         self.version = version
455
456     @classmethod
457     def from_string(cls, string):
458         return cls(*string.split('-', 1))
459
460     def __cmp__(self, other):
461         namecmp = cmp(self.name, other.name)
462         if namecmp != 0:
463             return namecmp
464         return cmp(self.version, other.version)
465
466     def __hash__(self):
467         return hash(str(self))
468
469     def __str__(self):
470         return '%s-%s' % (self.name, self.version)
471
472 class Annotated(object):
473     """An object which has a few generic metadata
474 properties."""
475     def __init__(self):
476         self.version = None
477         self.skip = False
478         self.introspectable = True
479         self.attributes = [] # (key, value)*
480         self.deprecated = None
481         self.deprecated_version = None
482         self.doc = None
483
484 class Node(Annotated):
485     """A node is a type of object which is uniquely identified by its
486 (namespace, name) pair.  When combined with a ., this is called a
487 GIName.  It's possible for nodes to contain or point to other nodes."""
488
489     c_name = property(lambda self: self.namespace.name + self.name)
490     gi_name = property(lambda self: '%s.%s' % (self.namespace.name, self.name))
491
492     def __init__(self, name=None):
493         Annotated.__init__(self)
494         self.namespace = None # Should be set later by Namespace.append()
495         self.name = name
496         self.foreign = False
497         self.file_positions = set()
498
499     def create_type(self):
500         """Create a Type object referencing this node."""
501         assert self.namespace is not None
502         return Type(target_giname=('%s.%s' % (self.namespace.name, self.name)))
503
504     def __cmp__(self, other):
505         nscmp = cmp(self.namespace, other.namespace)
506         if nscmp != 0:
507             return nscmp
508         return cmp(self.name, other.name)
509
510     def __repr__(self):
511         return '%s(%r)' % (self.__class__.__name__, self.name)
512
513     def inherit_file_positions(self, node):
514         self.file_positions.update(node.file_positions)
515
516     def add_file_position(self, position):
517         self.file_positions.add(position)
518
519     def add_symbol_reference(self, symbol):
520         if symbol.source_filename:
521             self.add_file_position(Position(symbol.source_filename, symbol.line))
522
523     def walk(self, callback, chain):
524         res = callback(self, chain)
525         assert res in (True, False), "Walk function must return boolean, not %r" % (res, )
526         if not res:
527             return False
528         chain.append(self)
529         self._walk(callback, chain)
530         chain.pop()
531
532     def _walk(self, callback, chain):
533         pass
534
535
536 class Registered:
537     """A node that (possibly) has gtype_name and get_type."""
538     def __init__(self, gtype_name, get_type):
539         assert (gtype_name is None and get_type is None) or \
540                (gtype_name is not None and get_type is not None)
541         self.gtype_name = gtype_name
542         self.get_type = get_type
543
544
545 class Callable(Node):
546
547     def __init__(self, name, retval, parameters, throws):
548         Node.__init__(self, name)
549         self.retval = retval
550         self.parameters = parameters
551         self.throws = not not throws
552         self.instance_parameter = None # Parameter
553
554     def get_parameter_index(self, name):
555         for i, parameter in enumerate(self.parameters):
556             if parameter.argname == name:
557                 return i
558         raise ValueError("Unknown argument %s" % (name, ))
559
560     def get_parameter(self, name):
561         for parameter in self.parameters:
562             if parameter.argname == name:
563                 return parameter
564         raise ValueError("Unknown argument %s" % (name, ))
565
566
567 class Function(Callable):
568
569     def __init__(self, name, retval, parameters, throws, symbol):
570         Callable.__init__(self, name, retval, parameters, throws)
571         self.symbol = symbol
572         self.is_method = False
573         self.is_constructor = False
574         self.shadowed_by = None # C symbol string
575         self.shadows = None # C symbol string
576
577
578 class ErrorQuarkFunction(Function):
579
580     def __init__(self, name, retval, parameters, throws, symbol, error_domain):
581         Function.__init__(self, name, retval, parameters, throws, symbol)
582         self.error_domain = error_domain
583
584
585 class VFunction(Callable):
586
587     def __init__(self, name, retval, parameters, throws):
588         Callable.__init__(self, name, retval, parameters, throws)
589         self.invoker = None
590
591     @classmethod
592     def from_callback(cls, cb):
593         obj = cls(cb.name, cb.retval, cb.parameters[1:],
594                   cb.throws)
595         return obj
596
597
598
599 class Varargs(Type):
600
601     def __init__(self):
602         Type.__init__(self, '<varargs>', target_fundamental='<varargs>')
603
604
605 class Array(Type):
606     C = '<c>'
607     GLIB_ARRAY = 'GLib.Array'
608     GLIB_BYTEARRAY = 'GLib.ByteArray'
609     GLIB_PTRARRAY = 'GLib.PtrArray'
610
611     def __init__(self, array_type, element_type, **kwargs):
612         Type.__init__(self, target_fundamental='<array>',
613                       **kwargs)
614         if (array_type is None or array_type == self.C):
615             self.array_type = self.C
616         else:
617             assert array_type in (self.GLIB_ARRAY,
618                                   self.GLIB_BYTEARRAY,
619                                   self.GLIB_PTRARRAY), array_type
620             self.array_type = array_type
621         assert isinstance(element_type, Type)
622         self.element_type = element_type
623         self.zeroterminated = True
624         self.length_param_name = None
625         self.size = None
626
627     def clone(self):
628         arr = Array(self.array_type, self.element_type)
629         arr.zeroterminated = self.zeroterminated
630         arr.length_param_name = self.length_param_name
631         arr.size = self.size
632         return arr
633
634 class List(Type):
635
636     def __init__(self, name, element_type, **kwargs):
637         Type.__init__(self, target_fundamental='<list>',
638                       **kwargs)
639         self.name = name
640         assert isinstance(element_type, Type)
641         self.element_type = element_type
642
643     def clone(self):
644         l = List(self.name, self.element_type)
645         l.zeroterminated = self.zeroterminated
646         l.length_param_name = self.length_param_name
647         l.size = self.size
648         return l
649
650 class Map(Type):
651
652     def __init__(self, key_type, value_type, **kwargs):
653         Type.__init__(self, target_fundamental='<map>', **kwargs)
654         assert isinstance(key_type, Type)
655         self.key_type = key_type
656         assert isinstance(value_type, Type)
657         self.value_type = value_type
658
659     def clone(self):
660         return Map(self.key_type, self.value_type)
661
662 class Alias(Node):
663
664     def __init__(self, name, target, ctype=None):
665         Node.__init__(self, name)
666         self.target = target
667         self.ctype = ctype
668
669
670 class TypeContainer(Annotated):
671     """A fundamental base class for Return and Parameter."""
672
673     def __init__(self, typenode, transfer):
674         Annotated.__init__(self)
675         self.type = typenode
676         if transfer is not None:
677             self.transfer = transfer
678         elif typenode.is_const:
679             self.transfer = PARAM_TRANSFER_NONE
680         else:
681             self.transfer = None
682
683
684 class Parameter(TypeContainer):
685     """An argument to a function."""
686
687     def __init__(self, argname, typenode, direction=None,
688                  transfer=None, allow_none=False, scope=None,
689                  caller_allocates=False):
690         TypeContainer.__init__(self, typenode, transfer)
691         self.argname = argname
692         self.direction = direction
693         self.allow_none = allow_none
694         self.scope = scope
695         self.caller_allocates = caller_allocates
696         self.closure_name = None
697         self.destroy_name = None
698
699
700 class Return(TypeContainer):
701     """A return value from a function."""
702
703     def __init__(self, rtype, transfer=None):
704         TypeContainer.__init__(self, rtype, transfer)
705         self.direction = PARAM_DIRECTION_OUT
706
707
708 class Enum(Node, Registered):
709
710     def __init__(self, name, ctype,
711                  gtype_name=None,
712                  get_type=None,
713                  c_symbol_prefix=None,
714                  members=None):
715         Node.__init__(self, name)
716         Registered.__init__(self, gtype_name, get_type)
717         self.c_symbol_prefix = c_symbol_prefix
718         self.ctype = ctype
719         self.members = members
720         # Associated error domain name
721         self.error_domain = None
722
723
724 class Bitfield(Node, Registered):
725
726     def __init__(self, name, ctype,
727                  gtype_name=None,
728                  c_symbol_prefix=None,
729                  get_type=None,
730                  members=None):
731         Node.__init__(self, name)
732         Registered.__init__(self, gtype_name, get_type)
733         self.ctype = ctype
734         self.c_symbol_prefix = c_symbol_prefix
735         self.members = members
736
737
738 class Member(Annotated):
739
740     def __init__(self, name, value, symbol, nick):
741         Annotated.__init__(self)
742         self.name = name
743         self.value = value
744         self.symbol = symbol
745         self.nick = nick
746
747     def __cmp__(self, other):
748         return cmp(self.name, other.name)
749
750
751
752 class Compound(Node, Registered):
753     def __init__(self, name,
754                  ctype=None,
755                  gtype_name=None,
756                  get_type=None,
757                  c_symbol_prefix=None,
758                  disguised=False):
759         Node.__init__(self, name)
760         Registered.__init__(self, gtype_name, get_type)
761         self.ctype = ctype
762         self.methods = []
763         self.static_methods = []
764         self.fields = []
765         self.constructors = []
766         self.disguised = disguised
767         self.gtype_name = gtype_name
768         self.get_type = get_type
769         self.c_symbol_prefix = c_symbol_prefix
770
771     def add_gtype(self, gtype_name, get_type):
772         self.gtype_name = gtype_name
773         self.get_type = get_type
774
775     def _walk(self, callback, chain):
776         for ctor in self.constructors:
777             ctor.walk(callback, chain)
778         for func in self.methods:
779             func.walk(callback, chain)
780         for func in self.static_methods:
781             func.walk(callback, chain)
782         for field in self.fields:
783             if field.anonymous_node is not None:
784                 field.anonymous_node.walk(callback, chain)
785
786 class Field(Annotated):
787
788     def __init__(self, name, typenode, readable, writable, bits=None,
789                  anonymous_node=None):
790         Annotated.__init__(self)
791         assert (typenode or anonymous_node)
792         self.name = name
793         self.type = typenode
794         self.readable = readable
795         self.writable = writable
796         self.bits = bits
797         self.anonymous_node = anonymous_node
798         self.private = False
799
800     def __cmp__(self, other):
801         return cmp(self.name, other.name)
802
803
804 class Record(Compound):
805
806     def __init__(self, name,
807                  ctype=None,
808                  gtype_name=None,
809                  get_type=None,
810                  c_symbol_prefix=None,
811                  disguised=False):
812         Compound.__init__(self, name,
813                           ctype=ctype,
814                           gtype_name=gtype_name,
815                           get_type=get_type,
816                           c_symbol_prefix=c_symbol_prefix,
817                           disguised=disguised)
818         # If non-None, this record defines the FooClass C structure
819         # for some Foo GObject (or similar for GInterface)
820         self.is_gtype_struct_for = None
821
822
823 class Union(Compound):
824
825     def __init__(self, name,
826                  ctype=None,
827                  gtype_name=None,
828                  get_type=None,
829                  c_symbol_prefix=None,
830                  disguised=False):
831         Compound.__init__(self, name,
832                           ctype=ctype,
833                           gtype_name=gtype_name,
834                           get_type=get_type,
835                           c_symbol_prefix=c_symbol_prefix,
836                           disguised=disguised)
837
838
839 class Boxed(Node, Registered):
840     """A boxed type with no known associated structure/union."""
841     def __init__(self, name,
842                  gtype_name=None,
843                  get_type=None,
844                  c_symbol_prefix=None):
845         assert gtype_name is not None
846         assert get_type is not None
847         Node.__init__(self, name)
848         Registered.__init__(self, gtype_name, get_type)
849         if get_type is not None:
850             assert c_symbol_prefix is not None
851         self.c_symbol_prefix = c_symbol_prefix
852         self.constructors = []
853         self.methods = []
854         self.static_methods = []
855
856     def _walk(self, callback, chain):
857         for ctor in self.constructors:
858             ctor.walk(callback, chain)
859         for meth in self.methods:
860             meth.walk(callback, chain)
861         for meth in self.static_methods:
862             meth.walk(callback, chain)
863
864
865 class Signal(Callable):
866
867     def __init__(self, name, retval, parameters, when="first",
868                  no_recurse=False, detailed=False, action=False,
869                  no_hooks=False):
870         Callable.__init__(self, name, retval, parameters, False)
871         self.when = when
872         self.no_recurse = no_recurse
873         self.detailed = detailed
874         self.action = action
875         self.no_hooks = no_hooks
876
877
878 class Class(Node, Registered):
879
880     def __init__(self, name, parent,
881                  ctype=None,
882                  gtype_name=None,
883                  get_type=None,
884                  c_symbol_prefix=None,
885                  is_abstract=False):
886         Node.__init__(self, name)
887         Registered.__init__(self, gtype_name, get_type)
888         self.ctype = ctype
889         self.c_symbol_prefix = c_symbol_prefix
890         self.parent = parent
891         self.fundamental = False
892         self.unref_func = None
893         self.ref_func = None
894         self.set_value_func = None
895         self.get_value_func = None
896         # When we're in the scanner, we keep around a list
897         # of parents so that we can transparently fall back
898         # if there are 'hidden' parents
899         self.parent_chain = []
900         self.glib_type_struct = None
901         self.is_abstract = is_abstract
902         self.methods = []
903         self.virtual_methods = []
904         self.static_methods = []
905         self.interfaces = []
906         self.constructors = []
907         self.properties = []
908         self.fields = []
909         self.signals = []
910
911     def _walk(self, callback, chain):
912         for meth in self.methods:
913             meth.walk(callback, chain)
914         for meth in self.virtual_methods:
915             meth.walk(callback, chain)
916         for meth in self.static_methods:
917             meth.walk(callback, chain)
918         for ctor in self.constructors:
919             ctor.walk(callback, chain)
920         for field in self.fields:
921             if field.anonymous_node:
922                 field.anonymous_node.walk(callback, chain)
923         for sig in self.signals:
924             sig.walk(callback, chain)
925
926
927 class Interface(Node, Registered):
928
929     def __init__(self, name, parent,
930                  ctype=None,
931                  gtype_name=None,
932                  get_type=None,
933                  c_symbol_prefix=None):
934         Node.__init__(self, name)
935         Registered.__init__(self, gtype_name, get_type)
936         self.ctype = ctype
937         self.c_symbol_prefix = c_symbol_prefix
938         self.parent = parent
939         self.parent_chain = []
940         self.methods = []
941         self.signals = []
942         self.static_methods = []
943         self.virtual_methods = []
944         self.glib_type_struct = None
945         self.properties = []
946         self.fields = []
947         self.prerequisites = []
948
949     def _walk(self, callback, chain):
950         for meth in self.methods:
951             meth.walk(callback, chain)
952         for meth in self.static_methods:
953             meth.walk(callback, chain)
954         for meth in self.virtual_methods:
955             meth.walk(callback, chain)
956         for field in self.fields:
957             if field.anonymous_node:
958                 field.anonymous_node.walk(callback, chain)
959         for sig in self.signals:
960             sig.walk(callback, chain)
961
962
963 class Constant(Node):
964
965     def __init__(self, name, value_type, value):
966         Node.__init__(self, name)
967         self.value_type = value_type
968         self.value = value
969
970
971 class Property(Node):
972
973     def __init__(self, name, typeobj, readable, writable,
974                  construct, construct_only, transfer=None):
975         Node.__init__(self, name)
976         self.type = typeobj
977         self.readable = readable
978         self.writable = writable
979         self.construct = construct
980         self.construct_only = construct_only
981         if transfer is None:
982             self.transfer = PARAM_TRANSFER_NONE
983         else:
984             self.transfer = transfer
985
986
987 class Callback(Callable):
988
989     def __init__(self, name, retval, parameters, throws, ctype=None):
990         Callable.__init__(self, name, retval, parameters, throws)
991         self.ctype = ctype