Imported Upstream version 1.49.1
[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 __future__ import absolute_import
23 from __future__ import division
24 from __future__ import print_function
25 from __future__ import unicode_literals
26
27 import copy
28 import operator
29 from itertools import chain
30
31 from . import message
32
33 from .collections import OrderedDict
34 from .message import Position
35 from .utils import to_underscores
36
37
38 class Type(object):
39     """
40     A Type can be either:
41     * A reference to a node (target_giname)
42     * A reference to a "fundamental" type like 'utf8'
43     * A "foreign" type - this can be any string."
44     If none are specified, then it's in an "unresolved" state.  An
45     unresolved type can have two data sources; a "ctype" which comes
46     from a C type string, or a gtype_name (from g_type_name()).
47     """
48
49     def __init__(self,
50                  ctype=None,
51                  gtype_name=None,
52                  target_fundamental=None,
53                  target_giname=None,
54                  target_foreign=None,
55                  _target_unknown=False,
56                  is_const=False,
57                  origin_symbol=None,
58                  complete_ctype=None):
59         self.ctype = ctype
60         self.gtype_name = gtype_name
61         self.origin_symbol = origin_symbol
62         if _target_unknown:
63             assert isinstance(self, TypeUnknown)
64         elif target_fundamental:
65             assert target_giname is None
66             assert target_foreign is None
67         elif target_giname:
68             assert '.' in target_giname
69             assert target_fundamental is None
70             assert target_foreign is None
71         elif target_foreign:
72             assert ctype is not None
73             assert target_giname is None
74             assert target_fundamental is None
75         else:
76             assert (ctype is not None) or (gtype_name is not None)
77         self.target_fundamental = target_fundamental
78         self.target_giname = target_giname
79         self.target_foreign = target_foreign
80         self.is_const = is_const
81         self.complete_ctype = complete_ctype
82
83     @property
84     def resolved(self):
85         return (self.target_fundamental or
86                 self.target_giname or
87                 self.target_foreign)
88
89     @property
90     def unresolved_string(self):
91         if self.ctype:
92             return self.ctype
93         elif self.gtype_name:
94             return self.gtype_name
95         elif self.target_giname:
96             return self.target_giname
97         else:
98             assert False
99
100     @classmethod
101     def create_from_gtype_name(cls, gtype_name):
102         """Parse a GType name (as from g_type_name()), and return a
103 Type instance.  Note that this function performs namespace lookup,
104 in contrast to the other create_type() functions."""
105         # First, is it a fundamental?
106         fundamental = type_names.get(gtype_name)
107         if fundamental is not None:
108             return cls(target_fundamental=fundamental.target_fundamental,
109                        ctype=fundamental.ctype)
110         if gtype_name == 'GHashTable':
111             return Map(TYPE_ANY, TYPE_ANY, gtype_name=gtype_name)
112         elif gtype_name in ('GArray', 'GPtrArray', 'GByteArray'):
113             return Array('GLib.' + gtype_name[1:], TYPE_ANY,
114                          gtype_name=gtype_name)
115         elif gtype_name == 'GStrv':
116             bare_utf8 = TYPE_STRING.clone()
117             bare_utf8.ctype = None
118             return Array(None, bare_utf8, ctype=None, gtype_name=gtype_name,
119                          is_const=False)
120
121         return cls(gtype_name=gtype_name)
122
123     def get_giname(self):
124         assert self.target_giname is not None
125         return self.target_giname.split('.')[1]
126
127     def _compare(self, other, op):
128         if self.target_fundamental:
129             return op(self.target_fundamental, other.target_fundamental)
130         elif self.target_giname:
131             return op(self.target_giname, other.target_giname)
132         elif self.target_foreign:
133             return op(self.target_foreign, other.target_foreign)
134         else:
135             return op(self.ctype, other.ctype)
136
137     def __lt__(self, other):
138         return self._compare(other, operator.lt)
139
140     def __gt__(self, other):
141         return self._compare(other, operator.gt)
142
143     def __ge__(self, other):
144         return self._compare(other, operator.ge)
145
146     def __le__(self, other):
147         return self._compare(other, operator.le)
148
149     def __eq__(self, other):
150         return self._compare(other, operator.eq)
151
152     def __ne__(self, other):
153         return self._compare(other, operator.ne)
154
155     def __hash__(self):
156         return hash((self.target_fundamental, self.target_giname,
157                      self.target_foreign, self.ctype))
158
159     def is_equiv(self, typeval):
160         """Return True if the specified types are compatible at
161         an introspection level, disregarding their C types.
162         A sequence may be given for typeval, in which case
163         this function returns True if the type is compatible with
164         any."""
165         if isinstance(typeval, (list, tuple)):
166             for val in typeval:
167                 if self.is_equiv(val):
168                     return True
169             return False
170         return self == typeval
171
172     def clone(self):
173         return Type(target_fundamental=self.target_fundamental,
174                     target_giname=self.target_giname,
175                     target_foreign=self.target_foreign,
176                     ctype=self.ctype,
177                     is_const=self.is_const)
178
179     def __str__(self):
180         if self.target_fundamental:
181             return self.target_fundamental
182         elif self.target_giname:
183             return self.target_giname
184         elif self.target_foreign:
185             return self.target_foreign
186
187     def __repr__(self):
188         if self.target_fundamental:
189             data = 'target_fundamental=%s, ' % (self.target_fundamental, )
190         elif self.target_giname:
191             data = 'target_giname=%s, ' % (self.target_giname, )
192         elif self.target_foreign:
193             data = 'target_foreign=%s, ' % (self.target_foreign, )
194         else:
195             data = ''
196         return '%s(%sctype=%s)' % (self.__class__.__name__, data, self.ctype)
197
198
199 class TypeUnknown(Type):
200     def __init__(self):
201         Type.__init__(self, _target_unknown=True)
202
203 # Fundamental types, two special ones
204 TYPE_NONE = Type(target_fundamental='none', ctype='void')
205 TYPE_ANY = Type(target_fundamental='gpointer', ctype='gpointer')
206 # Fundamental types, "Basic" types
207 TYPE_BOOLEAN = Type(target_fundamental='gboolean', ctype='gboolean')
208 TYPE_INT8 = Type(target_fundamental='gint8', ctype='gint8')
209 TYPE_UINT8 = Type(target_fundamental='guint8', ctype='guint8')
210 TYPE_INT16 = Type(target_fundamental='gint16', ctype='gint16')
211 TYPE_UINT16 = Type(target_fundamental='guint16', ctype='guint16')
212 TYPE_INT32 = Type(target_fundamental='gint32', ctype='gint32')
213 TYPE_UINT32 = Type(target_fundamental='guint32', ctype='guint32')
214 TYPE_INT64 = Type(target_fundamental='gint64', ctype='gint64')
215 TYPE_UINT64 = Type(target_fundamental='guint64', ctype='guint64')
216 TYPE_CHAR = Type(target_fundamental='gchar', ctype='gchar')
217 TYPE_SHORT = Type(target_fundamental='gshort', ctype='gshort')
218 TYPE_USHORT = Type(target_fundamental='gushort', ctype='gushort')
219 TYPE_INT = Type(target_fundamental='gint', ctype='gint')
220 TYPE_UINT = Type(target_fundamental='guint', ctype='guint')
221 TYPE_LONG = Type(target_fundamental='glong', ctype='glong')
222 TYPE_ULONG = Type(target_fundamental='gulong', ctype='gulong')
223 TYPE_SIZE = Type(target_fundamental='gsize', ctype='gsize')
224 TYPE_SSIZE = Type(target_fundamental='gssize', ctype='gssize')
225 TYPE_INTPTR = Type(target_fundamental='gintptr', ctype='gintptr')
226 TYPE_UINTPTR = Type(target_fundamental='guintptr', ctype='guintptr')
227 # C99 types
228 TYPE_LONG_LONG = Type(target_fundamental='long long', ctype='long long')
229 TYPE_LONG_ULONG = Type(target_fundamental='unsigned long long',
230                        ctype='unsigned long long')
231 TYPE_FLOAT = Type(target_fundamental='gfloat', ctype='gfloat')
232 TYPE_DOUBLE = Type(target_fundamental='gdouble', ctype='gdouble')
233 # ?
234 TYPE_LONG_DOUBLE = Type(target_fundamental='long double',
235                         ctype='long double')
236 TYPE_UNICHAR = Type(target_fundamental='gunichar', ctype='gunichar')
237
238 # C types with semantics overlaid
239 TYPE_GTYPE = Type(target_fundamental='GType', ctype='GType')
240 TYPE_STRING = Type(target_fundamental='utf8', ctype='gchar*')
241 TYPE_FILENAME = Type(target_fundamental='filename', ctype='gchar*')
242
243 TYPE_VALIST = Type(target_fundamental='va_list', ctype='va_list')
244
245 BASIC_TYPES = [TYPE_BOOLEAN, TYPE_INT8, TYPE_UINT8, TYPE_INT16,
246                TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_INT64,
247                TYPE_UINT64, TYPE_CHAR, TYPE_SHORT, TYPE_USHORT, TYPE_INT,
248                TYPE_UINT, TYPE_LONG, TYPE_ULONG, TYPE_SIZE, TYPE_SSIZE,
249                TYPE_LONG_LONG, TYPE_LONG_ULONG,
250                TYPE_FLOAT, TYPE_DOUBLE,
251                TYPE_LONG_DOUBLE, TYPE_UNICHAR, TYPE_GTYPE]
252
253 BASIC_GIR_TYPES = [TYPE_INTPTR, TYPE_UINTPTR]
254 BASIC_GIR_TYPES.extend(BASIC_TYPES)
255
256 GIR_TYPES = [TYPE_NONE, TYPE_ANY]
257 GIR_TYPES.extend(BASIC_GIR_TYPES)
258 GIR_TYPES.extend([TYPE_STRING, TYPE_FILENAME, TYPE_VALIST])
259
260 # These are the only basic types that are guaranteed to
261 # be as big as a pointer (and thus are allowed in GPtrArray)
262 POINTER_TYPES = [TYPE_ANY, TYPE_INTPTR, TYPE_UINTPTR]
263
264 INTROSPECTABLE_BASIC = list(GIR_TYPES)
265 for v in [TYPE_NONE, TYPE_ANY,
266           TYPE_LONG_LONG, TYPE_LONG_ULONG,
267           TYPE_LONG_DOUBLE, TYPE_VALIST]:
268     INTROSPECTABLE_BASIC.remove(v)
269
270 type_names = {}
271 for typeval in GIR_TYPES:
272     type_names[typeval.target_fundamental] = typeval
273 basic_type_names = {}
274 for typeval in BASIC_GIR_TYPES:
275     basic_type_names[typeval.target_fundamental] = typeval
276
277 # C builtin
278 type_names['char'] = TYPE_CHAR
279 type_names['signed char'] = TYPE_INT8
280 type_names['unsigned char'] = TYPE_UINT8
281 type_names['short'] = TYPE_SHORT
282 type_names['signed short'] = TYPE_SHORT
283 type_names['unsigned short'] = TYPE_USHORT
284 type_names['int'] = TYPE_INT
285 type_names['signed int'] = TYPE_INT
286 type_names['unsigned short int'] = TYPE_USHORT
287 type_names['signed'] = TYPE_INT
288 type_names['unsigned int'] = TYPE_UINT
289 type_names['unsigned'] = TYPE_UINT
290 type_names['long'] = TYPE_LONG
291 type_names['signed long'] = TYPE_LONG
292 type_names['unsigned long'] = TYPE_ULONG
293 type_names['unsigned long int'] = TYPE_ULONG
294 type_names['float'] = TYPE_FLOAT
295 type_names['double'] = TYPE_DOUBLE
296 type_names['char*'] = TYPE_STRING
297 type_names['void*'] = TYPE_ANY
298 type_names['void'] = TYPE_NONE
299 # Also alias the signed one here
300 type_names['signed long long'] = TYPE_LONG_LONG
301 # C99 stdint exact width types
302 type_names['int8_t'] = TYPE_INT8
303 type_names['uint8_t'] = TYPE_UINT8
304 type_names['int16_t'] = TYPE_INT16
305 type_names['uint16_t'] = TYPE_UINT16
306 type_names['int32_t'] = TYPE_INT32
307 type_names['uint32_t'] = TYPE_UINT32
308 type_names['int64_t'] = TYPE_INT64
309 type_names['uint64_t'] = TYPE_UINT64
310 # C99 stdbool
311 type_names['bool'] = TYPE_BOOLEAN
312
313 # A few additional GLib type aliases
314 type_names['guchar'] = TYPE_UINT8
315 type_names['gchararray'] = TYPE_STRING
316 type_names['gchar*'] = TYPE_STRING
317 type_names['goffset'] = TYPE_INT64
318 type_names['gunichar2'] = TYPE_UINT16
319 type_names['gsize'] = TYPE_SIZE
320 type_names['gssize'] = TYPE_SSIZE
321 type_names['gintptr'] = TYPE_INTPTR
322 type_names['guintptr'] = TYPE_UINTPTR
323 type_names['gconstpointer'] = TYPE_ANY
324
325 # We used to support these; continue to do so
326 type_names['any'] = TYPE_ANY
327 type_names['boolean'] = TYPE_BOOLEAN
328 type_names['uint'] = TYPE_UINT
329 type_names['ulong'] = TYPE_ULONG
330
331 # C stdio, used in GLib public headers; squash this for now here
332 # until we move scanning into GLib and can (skip)
333 type_names['FILE*'] = TYPE_ANY
334
335 # One off C unix type definitions; note some of these may be GNU Libc
336 # specific.  If someone is actually bitten by this, feel free to do
337 # the required configure goop to determine their size and replace
338 # here.
339 #
340 # We don't want to encourage people to use these in their APIs because
341 # they compromise the platform-independence that GLib gives you.
342 # These are here mostly to avoid blowing when random platform-specific
343 # methods are added under #ifdefs inside GLib itself.  We could just (skip)
344 # the relevant methods, but on the other hand, since these types are just
345 # integers it's easy enough to expand them.
346 type_names['size_t'] = type_names['gsize']
347 type_names['ssize_t'] = type_names['gssize']
348 type_names['time_t'] = TYPE_LONG
349 type_names['off_t'] = type_names['gsize']
350 type_names['pid_t'] = TYPE_INT
351 type_names['uid_t'] = TYPE_UINT
352 type_names['gid_t'] = TYPE_UINT
353 type_names['dev_t'] = TYPE_INT
354 type_names['socklen_t'] = TYPE_INT32
355
356 # Obj-C
357 type_names['id'] = TYPE_ANY
358
359 # Parameters
360 PARAM_DIRECTION_IN = 'in'
361 PARAM_DIRECTION_OUT = 'out'
362 PARAM_DIRECTION_INOUT = 'inout'
363
364 PARAM_SCOPE_CALL = 'call'
365 PARAM_SCOPE_ASYNC = 'async'
366 PARAM_SCOPE_NOTIFIED = 'notified'
367
368 PARAM_TRANSFER_NONE = 'none'
369 PARAM_TRANSFER_CONTAINER = 'container'
370 PARAM_TRANSFER_FULL = 'full'
371
372 SIGNAL_FIRST = 'first'
373 SIGNAL_LAST = 'last'
374 SIGNAL_CLEANUP = 'cleanup'
375 SIGNAL_MUST_COLLECT = 'must-collect'
376
377
378 class Namespace(object):
379     def __init__(self, name, version, identifier_prefixes=None, symbol_prefixes=None):
380         self.name = name
381         self.version = version
382         if identifier_prefixes is not None:
383             self.identifier_prefixes = identifier_prefixes
384         else:
385             self.identifier_prefixes = [name]
386         if symbol_prefixes is not None:
387             self.symbol_prefixes = symbol_prefixes
388         else:
389             ps = self.identifier_prefixes
390             self.symbol_prefixes = [to_underscores(p).lower() for p in ps]
391         # cache upper-cased versions
392         self._ucase_symbol_prefixes = [p.upper() for p in self.symbol_prefixes]
393         self.names = OrderedDict()   # Maps from GIName -> node
394         self.aliases = {}            # Maps from GIName -> GIName
395         self.type_names = {}         # Maps from GTName -> node
396         self.ctypes = {}             # Maps from CType -> node
397         self.symbols = {}            # Maps from function symbols -> Function
398         # Immediate includes only, not their transitive closure:
399         self.includes = set()        # Include
400         self.shared_libraries = []   # str
401         self.c_includes = []         # str
402         self.exported_packages = []  # str
403
404     def type_from_name(self, name, ctype=None):
405         """Backwards compatibility method for older .gir files, which
406 only use the 'name' attribute.  If name refers to a fundamental type,
407 create a Type object referncing it.  If name is already a
408 fully-qualified GIName like 'Foo.Bar', returns a Type targeting it .
409 Otherwise a Type targeting name qualififed with the namespace name is
410 returned."""
411         if name in type_names:
412             return Type(target_fundamental=name, ctype=ctype)
413         if '.' in name:
414             target = name
415         else:
416             target = '%s.%s' % (self.name, name)
417         return Type(target_giname=target, ctype=ctype)
418
419     def track(self, node):
420         """Doesn't directly append the function to our own namespace,
421 but adds it to things like ctypes, symbols, and type_names.
422 """
423         assert isinstance(node, Node)
424         if node.namespace is self:
425             return
426         assert node.namespace is None
427         node.namespace = self
428         if isinstance(node, Alias):
429             self.aliases[node.name] = node
430         elif isinstance(node, Registered) and node.gtype_name is not None:
431             self.type_names[node.gtype_name] = node
432         elif isinstance(node, Function):
433             self.symbols[node.symbol] = node
434         if isinstance(node, (Compound, Class, Interface, Boxed)):
435             for fn in chain(node.methods, node.static_methods, node.constructors):
436                 if not isinstance(fn, Function):
437                     continue
438                 fn.namespace = self
439                 self.symbols[fn.symbol] = fn
440         if isinstance(node, (Compound, Class, Interface)):
441             for f in node.fields:
442                 f.namespace = self
443         if isinstance(node, (Class, Interface)):
444             for m in chain(node.signals, node.properties):
445                 m.namespace = self
446         if isinstance(node, (Enum, Bitfield)):
447             for fn in node.static_methods:
448                 if not isinstance(fn, Function):
449                     continue
450                 fn.namespace = self
451                 self.symbols[fn.symbol] = fn
452             for member in node.members:
453                 member.namespace = self
454                 self.symbols[member.symbol] = member
455         if hasattr(node, 'ctype'):
456             self.ctypes[node.ctype] = node
457
458     def append(self, node, replace=False):
459         previous = self.names.get(node.name)
460         if previous is not None:
461             if not replace:
462                 raise ValueError("Namespace conflict: %r" % (node, ))
463             self.remove(previous)
464
465         self.track(node)
466         self.names[node.name] = node
467
468     def remove(self, node):
469         if isinstance(node, Alias):
470             del self.aliases[node.name]
471         elif isinstance(node, Registered) and node.gtype_name is not None:
472             del self.type_names[node.gtype_name]
473         if hasattr(node, 'ctype'):
474             del self.ctypes[node.ctype]
475         if isinstance(node, Function):
476             del self.symbols[node.symbol]
477         node.namespace = None
478         self.names.pop(node.name, None)
479
480     def float(self, node):
481         """Like remove(), but doesn't unset the node's namespace
482 back-reference, and it's still possible to look up
483 functions via get_by_symbol()."""
484         if isinstance(node, Function):
485             symbol = node.symbol
486         self.remove(node)
487         self.symbols[symbol] = node
488         node.namespace = self
489
490     def __iter__(self):
491         return iter(self.names)
492
493     def items(self):
494         return self.names.items()
495
496     def values(self):
497         return self.names.values()
498
499     def get(self, name):
500         return self.names.get(name)
501
502     def get_by_ctype(self, ctype):
503         return self.ctypes.get(ctype)
504
505     def get_by_symbol(self, symbol):
506         return self.symbols.get(symbol)
507
508     def walk(self, callback):
509         for node in self.values():
510             node.walk(callback, [])
511
512
513 class Include(object):
514
515     def __init__(self, name, version):
516         self.name = name
517         self.version = version
518
519     @classmethod
520     def from_string(cls, string):
521         return cls(*string.split('-', 1))
522
523     def _compare(self, other, op):
524         return op((self.name, self.version), (other.name, other.version))
525
526     def __lt__(self, other):
527         return self._compare(other, operator.lt)
528
529     def __gt__(self, other):
530         return self._compare(other, operator.gt)
531
532     def __ge__(self, other):
533         return self._compare(other, operator.ge)
534
535     def __le__(self, other):
536         return self._compare(other, operator.le)
537
538     def __eq__(self, other):
539         return self._compare(other, operator.eq)
540
541     def __ne__(self, other):
542         return self._compare(other, operator.ne)
543
544     def __hash__(self):
545         return hash(str(self))
546
547     def __str__(self):
548         return '%s-%s' % (self.name, self.version)
549
550
551 class Annotated(object):
552     """An object which has a few generic metadata
553 properties."""
554     def __init__(self):
555         self.version = None
556         self.version_doc = None
557         self.skip = False
558         self.introspectable = True
559         self.attributes = OrderedDict()
560         self.stability = None
561         self.stability_doc = None
562         self.deprecated = None
563         self.deprecated_doc = None
564         self.doc = None
565
566
567 class Node(Annotated):
568     """A node is a type of object which is uniquely identified by its
569 (namespace, name) pair.  When combined with a ., this is called a
570 GIName.  It's possible for nodes to contain or point to other nodes."""
571
572     c_name = property(lambda self: self.namespace.name + self.name if self.namespace else
573                       self.name)
574     gi_name = property(lambda self: '%s.%s' % (self.namespace.name, self.name))
575
576     def __init__(self, name=None):
577         Annotated.__init__(self)
578         self.namespace = None   # Should be set later by Namespace.append()
579         self.name = name
580         self.foreign = False
581         self.file_positions = set()
582         self._parent = None
583
584     def _get_parent(self):
585         if self._parent is not None:
586             return self._parent
587         else:
588             return self.namespace
589
590     def _set_parent(self, value):
591         self._parent = value
592     parent = property(_get_parent, _set_parent)
593
594     def create_type(self):
595         """Create a Type object referencing this node."""
596         assert self.namespace is not None
597         return Type(target_giname=('%s.%s' % (self.namespace.name, self.name)))
598
599     def _compare(self, other, op):
600         return op((self.namespace, self.name), (other.namespace, other.name))
601
602     def __lt__(self, other):
603         return self._compare(other, operator.lt)
604
605     def __gt__(self, other):
606         return self._compare(other, operator.gt)
607
608     def __ge__(self, other):
609         return self._compare(other, operator.ge)
610
611     def __le__(self, other):
612         return self._compare(other, operator.le)
613
614     def __eq__(self, other):
615         return self._compare(other, operator.eq)
616
617     def __ne__(self, other):
618         return self._compare(other, operator.ne)
619
620     def __hash__(self):
621         return hash((self.namespace, self.name))
622
623     def __repr__(self):
624         return "%s('%s')" % (self.__class__.__name__, self.name)
625
626     def inherit_file_positions(self, node):
627         self.file_positions.update(node.file_positions)
628
629     def add_file_position(self, position):
630         self.file_positions.add(position)
631
632     def add_symbol_reference(self, symbol):
633         if symbol.source_filename:
634             self.add_file_position(Position(symbol.source_filename, symbol.line))
635
636     def walk(self, callback, chain):
637         res = callback(self, chain)
638         assert res in (True, False), "Walk function must return boolean, not %r" % (res, )
639         if not res:
640             return False
641         chain.append(self)
642         self._walk(callback, chain)
643         chain.pop()
644
645     def _walk(self, callback, chain):
646         pass
647
648
649 class Registered:
650     """A node that (possibly) has gtype_name and get_type."""
651     def __init__(self, gtype_name, get_type):
652         assert (gtype_name is None and get_type is None) or \
653                (gtype_name is not None and get_type is not None)
654         self.gtype_name = gtype_name
655         self.get_type = get_type
656
657
658 class Callable(Node):
659
660     def __init__(self, name, retval, parameters, throws):
661         Node.__init__(self, name)
662         self.retval = retval
663         self.parameters = parameters
664         self.throws = not not throws
665         self.instance_parameter = None  # Parameter
666         self.parent = None  # A Class or Interface
667
668     def _get_retval(self):
669         return self._retval
670
671     def _set_retval(self, value):
672         self._retval = value
673         if self._retval is not None:
674             self._retval.parent = self
675     retval = property(_get_retval, _set_retval)
676
677     def _get_instance_parameter(self):
678         return self._instance_parameter
679
680     def _set_instance_parameter(self, value):
681         self._instance_parameter = value
682         if value is not None:
683             value.parent = self
684     instance_parameter = property(_get_instance_parameter,
685                                   _set_instance_parameter)
686
687     def _get_parameters(self):
688         return self._parameters
689
690     def _set_parameters(self, value):
691         self._parameters = value
692         for param in self._parameters:
693             param.parent = self
694     parameters = property(_get_parameters, _set_parameters)
695
696     # Returns all parameters, including the instance parameter
697     @property
698     def all_parameters(self):
699         if self.instance_parameter is not None:
700             return [self.instance_parameter] + self.parameters
701         else:
702             return self.parameters
703
704     def get_parameter_index(self, name):
705         for i, parameter in enumerate(self.parameters):
706             if parameter.argname == name:
707                 return i
708         raise ValueError("Unknown argument %s" % (name, ))
709
710     def get_parameter(self, name):
711         for parameter in self.all_parameters:
712             if parameter.argname == name:
713                 return parameter
714         raise ValueError("Unknown argument %s" % (name, ))
715
716
717 class Function(Callable):
718
719     def __init__(self, name, retval, parameters, throws, symbol):
720         Callable.__init__(self, name, retval, parameters, throws)
721         self.symbol = symbol
722         self.is_method = False
723         self.is_constructor = False
724         self.shadowed_by = None         # C symbol string
725         self.shadows = None             # C symbol string
726         self.moved_to = None            # namespaced function name string
727         self.internal_skipped = False   # if True, this func will not be written to GIR
728
729     def clone(self):
730         clone = copy.copy(self)
731         # copy the parameters array so a change to self.parameters does not
732         # influence clone.parameters.
733         clone.parameters = self.parameters[:]
734         for param in clone.parameters:
735             param.parent = clone
736         return clone
737
738     def is_type_meta_function(self):
739         # Named correctly
740         if not (self.name.endswith('_get_type') or self.name.endswith('_get_gtype')):
741             return False
742
743         # Doesn't have any parameters
744         if self.parameters:
745             return False
746
747         # Returns GType
748         rettype = self.retval.type
749         if (not rettype.is_equiv(TYPE_GTYPE) and rettype.target_giname != 'Gtk.Type'):
750             message.warn("function '%s' returns '%r', not a GType" % (self.name, rettype))
751             return False
752
753         return True
754
755
756 class ErrorQuarkFunction(Function):
757
758     def __init__(self, name, retval, parameters, throws, symbol, error_domain):
759         Function.__init__(self, name, retval, parameters, throws, symbol)
760         self.error_domain = error_domain
761
762
763 class VFunction(Callable):
764
765     def __init__(self, name, retval, parameters, throws):
766         Callable.__init__(self, name, retval, parameters, throws)
767         self.invoker = None
768
769     @classmethod
770     def from_callback(cls, name, cb):
771         obj = cls(name, cb.retval, cb.parameters[1:],
772                   cb.throws)
773         return obj
774
775
776 class Varargs(Type):
777
778     def __init__(self):
779         Type.__init__(self, '<varargs>', target_fundamental='<varargs>')
780
781
782 class Array(Type):
783     C = '<c>'
784     GLIB_ARRAY = 'GLib.Array'
785     GLIB_BYTEARRAY = 'GLib.ByteArray'
786     GLIB_PTRARRAY = 'GLib.PtrArray'
787
788     def __init__(self, array_type, element_type, **kwargs):
789         Type.__init__(self, target_fundamental='<array>',
790                       **kwargs)
791         if (array_type is None or array_type == self.C):
792             self.array_type = self.C
793         else:
794             assert array_type in (self.GLIB_ARRAY,
795                                   self.GLIB_BYTEARRAY,
796                                   self.GLIB_PTRARRAY), array_type
797             self.array_type = array_type
798         assert isinstance(element_type, Type)
799         self.element_type = element_type
800         self.zeroterminated = True
801         self.length_param_name = None
802         self.size = None
803
804     def clone(self):
805         arr = Array(self.array_type, self.element_type)
806         arr.zeroterminated = self.zeroterminated
807         arr.length_param_name = self.length_param_name
808         arr.size = self.size
809         return arr
810
811
812 class List(Type):
813
814     def __init__(self, name, element_type, **kwargs):
815         Type.__init__(self, target_fundamental='<list>',
816                       **kwargs)
817         self.name = name
818         assert isinstance(element_type, Type)
819         self.element_type = element_type
820
821     def clone(self):
822         return List(self.name, self.element_type)
823
824
825 class Map(Type):
826
827     def __init__(self, key_type, value_type, **kwargs):
828         Type.__init__(self, target_fundamental='<map>', **kwargs)
829         assert isinstance(key_type, Type)
830         self.key_type = key_type
831         assert isinstance(value_type, Type)
832         self.value_type = value_type
833
834     def clone(self):
835         return Map(self.key_type, self.value_type)
836
837
838 class Alias(Node):
839
840     def __init__(self, name, target, ctype=None):
841         Node.__init__(self, name)
842         self.target = target
843         self.ctype = ctype
844
845
846 class TypeContainer(Annotated):
847     """A fundamental base class for Return and Parameter."""
848
849     def __init__(self, typenode, nullable, not_nullable, transfer, direction):
850         Annotated.__init__(self)
851         self.type = typenode
852         self.nullable = nullable
853         self.not_nullable = not_nullable
854         self.direction = direction
855         if transfer is not None:
856             self.transfer = transfer
857         elif typenode.is_const:
858             self.transfer = PARAM_TRANSFER_NONE
859         else:
860             self.transfer = None
861
862
863 class Parameter(TypeContainer):
864     """An argument to a function."""
865
866     def __init__(self, argname, typenode, direction=None,
867                  transfer=None, nullable=False, optional=False,
868                  allow_none=False, scope=None,
869                  caller_allocates=False, not_nullable=False):
870         TypeContainer.__init__(self, typenode, nullable, not_nullable,
871                                transfer, direction)
872         self.argname = argname
873         self.optional = optional
874         self.parent = None  # A Callable
875
876         if allow_none:
877             if self.direction == PARAM_DIRECTION_OUT:
878                 self.optional = True
879             else:
880                 self.nullable = True
881
882         self.scope = scope
883         self.caller_allocates = caller_allocates
884         self.closure_name = None
885         self.destroy_name = None
886
887     @property
888     def name(self):
889         return self.argname
890
891
892 class Return(TypeContainer):
893     """A return value from a function."""
894
895     def __init__(self, rtype, nullable=False, not_nullable=False,
896                  transfer=None):
897         TypeContainer.__init__(self, rtype, nullable, not_nullable, transfer,
898                                direction=PARAM_DIRECTION_OUT)
899         self.parent = None  # A Callable
900
901
902 class Enum(Node, Registered):
903
904     def __init__(self, name, ctype,
905                  gtype_name=None,
906                  get_type=None,
907                  c_symbol_prefix=None,
908                  members=None):
909         Node.__init__(self, name)
910         Registered.__init__(self, gtype_name, get_type)
911         self.c_symbol_prefix = c_symbol_prefix
912         self.ctype = ctype
913         self.members = members
914         for member in members:
915             member.parent = self
916         # Associated error domain name
917         self.error_domain = None
918         self.static_methods = []
919
920     def _walk(self, callback, chain):
921         for meth in self.static_methods:
922             meth.walk(callback, chain)
923
924
925 class Bitfield(Node, Registered):
926
927     def __init__(self, name, ctype,
928                  gtype_name=None,
929                  c_symbol_prefix=None,
930                  get_type=None,
931                  members=None):
932         Node.__init__(self, name)
933         Registered.__init__(self, gtype_name, get_type)
934         self.ctype = ctype
935         self.c_symbol_prefix = c_symbol_prefix
936         self.members = members
937         for member in members:
938             member.parent = self
939         self.static_methods = []
940
941     def _walk(self, callback, chain):
942         for meth in self.static_methods:
943             meth.walk(callback, chain)
944
945
946 class Member(Annotated):
947
948     def __init__(self, name, value, symbol, nick):
949         Annotated.__init__(self)
950         self.name = name
951         self.value = value
952         self.symbol = symbol
953         self.nick = nick
954         self.parent = None
955
956     def _compare(self, other, op):
957         return op(self.name, other.name)
958
959     def __lt__(self, other):
960         return self._compare(other, operator.lt)
961
962     def __gt__(self, other):
963         return self._compare(other, operator.gt)
964
965     def __ge__(self, other):
966         return self._compare(other, operator.ge)
967
968     def __le__(self, other):
969         return self._compare(other, operator.le)
970
971     def __eq__(self, other):
972         return self._compare(other, operator.eq)
973
974     def __ne__(self, other):
975         return self._compare(other, operator.ne)
976
977     def __hash__(self):
978         return hash(self.name)
979
980     def __repr__(self):
981         return "%s('%s')" % (self.__class__.__name__, self.name)
982
983
984 class Compound(Node, Registered):
985     def __init__(self, name,
986                  ctype=None,
987                  gtype_name=None,
988                  get_type=None,
989                  c_symbol_prefix=None,
990                  disguised=False,
991                  tag_name=None):
992         Node.__init__(self, name)
993         Registered.__init__(self, gtype_name, get_type)
994         self.ctype = ctype
995         self.methods = []
996         self.static_methods = []
997         self.fields = []
998         self.constructors = []
999         self.disguised = disguised
1000         self.gtype_name = gtype_name
1001         self.get_type = get_type
1002         self.c_symbol_prefix = c_symbol_prefix
1003         self.tag_name = tag_name
1004
1005     def add_gtype(self, gtype_name, get_type):
1006         self.gtype_name = gtype_name
1007         self.get_type = get_type
1008         self.namespace.type_names[gtype_name] = self
1009
1010     def _walk(self, callback, chain):
1011         for ctor in self.constructors:
1012             ctor.walk(callback, chain)
1013         for func in self.methods:
1014             func.walk(callback, chain)
1015         for func in self.static_methods:
1016             func.walk(callback, chain)
1017         for field in self.fields:
1018             if field.anonymous_node is not None:
1019                 field.anonymous_node.walk(callback, chain)
1020
1021     def get_field(self, name):
1022         for field in self.fields:
1023             if field.name == name:
1024                 return field
1025         raise ValueError("Unknown field %s" % (name, ))
1026
1027     def get_field_index(self, name):
1028         for i, field in enumerate(self.fields):
1029             if field.name == name:
1030                 return i
1031         raise ValueError("Unknown field %s" % (name, ))
1032
1033
1034 class Field(Annotated):
1035
1036     def __init__(self, name, typenode, readable, writable, bits=None,
1037                  anonymous_node=None):
1038         Annotated.__init__(self)
1039         assert (typenode or anonymous_node)
1040         self.name = name
1041         self.type = typenode
1042         self.readable = readable
1043         self.writable = writable
1044         self.bits = bits
1045         self.anonymous_node = anonymous_node
1046         self.private = False
1047         self.namespace = None
1048         self.parent = None  # a compound
1049
1050     def _compare(self, other, op):
1051         return op(self.name, other.name)
1052
1053     def __lt__(self, other):
1054         return self._compare(other, operator.lt)
1055
1056     def __gt__(self, other):
1057         return self._compare(other, operator.gt)
1058
1059     def __ge__(self, other):
1060         return self._compare(other, operator.ge)
1061
1062     def __le__(self, other):
1063         return self._compare(other, operator.le)
1064
1065     def __eq__(self, other):
1066         return self._compare(other, operator.eq)
1067
1068     def __ne__(self, other):
1069         return self._compare(other, operator.ne)
1070
1071     def __hash__(self):
1072         return hash(self.name)
1073
1074     def __repr__(self):
1075         return "%s('%s')" % (self.__class__.__name__, self.name)
1076
1077
1078 class Record(Compound):
1079
1080     def __init__(self, name,
1081                  ctype=None,
1082                  gtype_name=None,
1083                  get_type=None,
1084                  c_symbol_prefix=None,
1085                  disguised=False,
1086                  tag_name=None):
1087         Compound.__init__(self, name,
1088                           ctype=ctype,
1089                           gtype_name=gtype_name,
1090                           get_type=get_type,
1091                           c_symbol_prefix=c_symbol_prefix,
1092                           disguised=disguised,
1093                           tag_name=tag_name)
1094         # If non-None, this record defines the FooClass C structure
1095         # for some Foo GObject (or similar for GInterface)
1096         self.is_gtype_struct_for = None
1097
1098
1099 class Union(Compound):
1100
1101     def __init__(self, name,
1102                  ctype=None,
1103                  gtype_name=None,
1104                  get_type=None,
1105                  c_symbol_prefix=None,
1106                  disguised=False,
1107                  tag_name=None):
1108         Compound.__init__(self, name,
1109                           ctype=ctype,
1110                           gtype_name=gtype_name,
1111                           get_type=get_type,
1112                           c_symbol_prefix=c_symbol_prefix,
1113                           disguised=disguised,
1114                           tag_name=tag_name)
1115
1116
1117 class Boxed(Node, Registered):
1118     """A boxed type with no known associated structure/union."""
1119     def __init__(self, name,
1120                  gtype_name=None,
1121                  get_type=None,
1122                  c_symbol_prefix=None):
1123         assert gtype_name is not None
1124         assert get_type is not None
1125         Node.__init__(self, name)
1126         Registered.__init__(self, gtype_name, get_type)
1127         if get_type is not None:
1128             assert c_symbol_prefix is not None
1129         self.c_symbol_prefix = c_symbol_prefix
1130         self.constructors = []
1131         self.methods = []
1132         self.static_methods = []
1133
1134     def _walk(self, callback, chain):
1135         for ctor in self.constructors:
1136             ctor.walk(callback, chain)
1137         for meth in self.methods:
1138             meth.walk(callback, chain)
1139         for meth in self.static_methods:
1140             meth.walk(callback, chain)
1141
1142
1143 class Signal(Callable):
1144
1145     def __init__(self, name, retval, parameters, when=None,
1146                  no_recurse=False, detailed=False, action=False,
1147                  no_hooks=False):
1148         Callable.__init__(self, name, retval, parameters, False)
1149         self.when = when
1150         self.no_recurse = no_recurse
1151         self.detailed = detailed
1152         self.action = action
1153         self.no_hooks = no_hooks
1154
1155
1156 class Class(Node, Registered):
1157
1158     def __init__(self, name, parent_type,
1159                  ctype=None,
1160                  gtype_name=None,
1161                  get_type=None,
1162                  c_symbol_prefix=None,
1163                  is_abstract=False):
1164         Node.__init__(self, name)
1165         Registered.__init__(self, gtype_name, get_type)
1166         self.ctype = ctype
1167         self.c_symbol_prefix = c_symbol_prefix
1168         self.parent_type = parent_type
1169         self.fundamental = False
1170         self.unref_func = None
1171         self.ref_func = None
1172         self.set_value_func = None
1173         self.get_value_func = None
1174         # When we're in the scanner, we keep around a list
1175         # of parents so that we can transparently fall back
1176         # if there are 'hidden' parents
1177         self.parent_chain = []
1178         self.glib_type_struct = None
1179         self.is_abstract = is_abstract
1180         self.methods = []
1181         self.virtual_methods = []
1182         self.static_methods = []
1183         self.interfaces = []
1184         self.constructors = []
1185         self.properties = []
1186         self.fields = []
1187         self.signals = []
1188
1189     def _walk(self, callback, chain):
1190         for meth in self.methods:
1191             meth.walk(callback, chain)
1192         for meth in self.virtual_methods:
1193             meth.walk(callback, chain)
1194         for meth in self.static_methods:
1195             meth.walk(callback, chain)
1196         for ctor in self.constructors:
1197             ctor.walk(callback, chain)
1198         for field in self.fields:
1199             if field.anonymous_node:
1200                 field.anonymous_node.walk(callback, chain)
1201         for sig in self.signals:
1202             sig.walk(callback, chain)
1203         for prop in self.properties:
1204             prop.walk(callback, chain)
1205
1206
1207 class Interface(Node, Registered):
1208
1209     def __init__(self, name, parent_type,
1210                  ctype=None,
1211                  gtype_name=None,
1212                  get_type=None,
1213                  c_symbol_prefix=None):
1214         Node.__init__(self, name)
1215         Registered.__init__(self, gtype_name, get_type)
1216         self.ctype = ctype
1217         self.c_symbol_prefix = c_symbol_prefix
1218         self.parent_type = parent_type
1219         self.parent_chain = []
1220         self.methods = []
1221         self.signals = []
1222         self.static_methods = []
1223         self.virtual_methods = []
1224         self.glib_type_struct = None
1225         self.properties = []
1226         self.fields = []
1227         self.prerequisites = []
1228         # Not used yet, exists just to avoid an exception in
1229         # Namespace.append()
1230         self.constructors = []
1231
1232     def _walk(self, callback, chain):
1233         for meth in self.methods:
1234             meth.walk(callback, chain)
1235         for meth in self.static_methods:
1236             meth.walk(callback, chain)
1237         for meth in self.virtual_methods:
1238             meth.walk(callback, chain)
1239         for field in self.fields:
1240             if field.anonymous_node:
1241                 field.anonymous_node.walk(callback, chain)
1242         for sig in self.signals:
1243             sig.walk(callback, chain)
1244
1245
1246 class Constant(Node):
1247
1248     def __init__(self, name, value_type, value, ctype):
1249         Node.__init__(self, name)
1250         self.value_type = value_type
1251         self.value = value
1252         self.ctype = ctype
1253
1254
1255 class Property(Node):
1256
1257     def __init__(self, name, typeobj, readable, writable,
1258                  construct, construct_only, transfer=None):
1259         Node.__init__(self, name)
1260         self.type = typeobj
1261         self.readable = readable
1262         self.writable = writable
1263         self.construct = construct
1264         self.construct_only = construct_only
1265         if transfer is None:
1266             self.transfer = PARAM_TRANSFER_NONE
1267         else:
1268             self.transfer = transfer
1269         self.parent = None  # A Class or Interface
1270
1271
1272 class Callback(Callable):
1273
1274     def __init__(self, name, retval, parameters, throws, ctype=None):
1275         Callable.__init__(self, name, retval, parameters, throws)
1276         self.ctype = ctype