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