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