2 # GObject-Introspection - a framework for introspecting GObject libraries
3 # Copyright (C) 2008 Johan Dahlin
4 # Copyright (C) 2008, 2009 Red Hat, Inc.
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2 of the License, or (at your option) any later version.
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the
18 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 # Boston, MA 02111-1307, USA.
23 This file descbribes abstract data type nodes independent on the
24 implementation language.
26 These can later on be extended (eg subclassed) with additional information
27 which is language/library/domain specific.
31 ## Basic types, modeled on GITypeTag but not equivalent
34 TYPE_NONE = 'none' # We differ from repository on these first two
36 TYPE_BOOLEAN = 'boolean'
40 TYPE_USHORT = 'ushort'
42 TYPE_UINT16 = 'uint16'
46 TYPE_UINT32 = 'uint32'
48 TYPE_UINT64 = 'uint64'
52 TYPE_SSIZET = 'gssize'
55 TYPE_DOUBLE = 'double'
56 TYPE_STRING = 'utf8' # requires zero-terminated
57 TYPE_FILENAME = 'filename'
59 BASIC_GIR_TYPES = [TYPE_BOOLEAN, TYPE_INT8, TYPE_UINT8, TYPE_INT16,
60 TYPE_UINT16, TYPE_INT32, TYPE_UINT32, TYPE_INT64,
61 TYPE_UINT64, TYPE_SHORT, TYPE_USHORT, TYPE_INT,
62 TYPE_UINT, TYPE_LONG, TYPE_ULONG, TYPE_SSIZET,
63 TYPE_SIZET, TYPE_FLOAT, TYPE_DOUBLE,
65 GIR_TYPES = [TYPE_NONE, TYPE_ANY]
66 GIR_TYPES.extend(BASIC_GIR_TYPES)
67 GIR_TYPES.extend([TYPE_STRING, TYPE_FILENAME])
69 # Higher-level data types
70 TYPE_SEQUENCE = 'sequence' # Sequence of something
74 TYPE_USTRING = 'ustring'
80 PARAM_DIRECTION_IN = 'in'
81 PARAM_DIRECTION_OUT = 'out'
82 PARAM_DIRECTION_INOUT = 'inout'
84 PARAM_SCOPE_CALL = 'call'
85 PARAM_SCOPE_ASYNC = 'async'
86 PARAM_SCOPE_NOTIFIED = 'notified'
88 PARAM_TRANSFER_NONE = 'none'
89 PARAM_TRANSFER_CONTAINER = 'container'
90 PARAM_TRANSFER_FULL = 'full'
93 for name in GIR_TYPES:
94 type_names[name] = name
97 type_names['char'] = TYPE_INT8
98 type_names['signed char'] = TYPE_INT8
99 type_names['unsigned char'] = TYPE_UINT8
100 type_names['short'] = TYPE_SHORT
101 type_names['signed short'] = TYPE_SHORT
102 type_names['unsigned short'] = TYPE_USHORT
103 type_names['int'] = TYPE_INT
104 type_names['signed int'] = TYPE_INT
105 type_names['unsigned short int'] = TYPE_USHORT
106 type_names['signed'] = TYPE_INT
107 type_names['unsigned int'] = TYPE_UINT
108 type_names['unsigned'] = TYPE_UINT
109 type_names['long'] = TYPE_LONG
110 type_names['signed long'] = TYPE_LONG
111 type_names['unsigned long'] = TYPE_ULONG
112 type_names['unsigned long int'] = TYPE_ULONG
113 type_names['float'] = TYPE_FLOAT
114 type_names['double'] = TYPE_DOUBLE
115 type_names['char*'] = TYPE_STRING
116 type_names['void*'] = TYPE_ANY
117 type_names['void'] = TYPE_NONE
119 # Random C unix type definitions; note some of these may be GNU Libc
120 # specific. If someone is actually bitten by this, feel free to do
121 # the required configure goop to determine their size and replace
124 # We don't want to encourage people to use these in their APIs because
125 # they compromise the platform-independence that GLib gives you.
126 # These are here mostly to avoid blowing when random platform-specific
127 # methods are added under #ifdefs inside GLib itself. We could just (skip)
128 # the relevant methods, but on the other hand, since these types are just
129 # integers it's easy enough to expand them.
130 type_names['size_t'] = TYPE_SIZET
131 type_names['time_t'] = TYPE_LONG
132 type_names['off_t'] = TYPE_SIZET
133 type_names['pid_t'] = TYPE_INT
134 type_names['uid_t'] = TYPE_UINT
135 type_names['gid_t'] = TYPE_UINT
136 type_names['dev_t'] = TYPE_INT
137 type_names['socklen_t'] = TYPE_INT32
140 type_names['id'] = TYPE_ANY
142 # Suppress some GLib names
143 type_names['uchar'] = TYPE_UINT8
144 type_names['ushort'] = TYPE_USHORT
145 type_names['size'] = TYPE_SIZET
146 type_names['ssize'] = TYPE_SSIZET
147 type_names['pointer'] = TYPE_ANY
148 type_names['constpointer'] = TYPE_ANY
151 # These types, when seen by reference, are converted into an Array()
153 # If you add/change these, be sure to update glibast.py too
154 default_array_types = {}
155 default_array_types['uint8*'] = TYPE_UINT8
156 default_array_types['utf8*'] = TYPE_STRING
158 # These types, when seen by reference, are interpreted as out parameters
159 default_out_types = (TYPE_SHORT, TYPE_USHORT, TYPE_INT, TYPE_UINT,
160 TYPE_LONG, TYPE_ULONG, TYPE_FLOAT, TYPE_DOUBLE,
161 TYPE_SIZET, TYPE_SSIZET)
164 def type_name_from_ctype(ctype):
165 return type_names.get(ctype, ctype)
170 def __init__(self, name=None):
173 self.introspectable = True
174 self.attributes = [] # (key, value)*
175 self.deprecated = None
176 self.deprecated_version = None
179 self.file_positions = set()
181 def __cmp__(self, other):
182 return cmp(self.name, other.name)
185 return '%s(%r)' % (self.__class__.__name__, self.name)
187 def remove_matching_children(self, pred):
190 def inherit_file_positions(self, node):
191 self.file_positions.update(node.file_positions)
193 def add_file_position(self, filename, line, column):
194 self.file_positions.add((filename, line, column))
196 def add_symbol_reference(self, symbol):
197 if symbol.source_filename:
198 self.add_file_position(symbol.source_filename, symbol.line, -1)
200 class Namespace(Node):
202 def __init__(self, name, version):
203 Node.__init__(self, name)
204 self.version = version
208 return '%s(%r, %r, %r)' % (self.__class__.__name__, self.name,
209 self.version, self.nodes)
211 def remove_matching(self, pred):
213 def recursive_pred(node):
214 node.remove_matching_children(pred)
217 self.nodes = filter(recursive_pred, self.nodes)
221 def __init__(self, name, version):
222 Node.__init__(self, 'include')
224 self.version = version
227 def from_string(self, string):
228 return Include(*string.split('-', 1))
230 def __cmp__(self, other):
231 if not isinstance(other, Include):
232 return cmp(self, other)
233 namecmp = cmp(self.name, other.name)
236 return cmp(self.version, other.version)
239 return hash((self.name, self.version))
242 return '%s-%s' % (self.name, self.version)
244 class Callable(Node):
246 def __init__(self, name, retval, parameters, throws):
247 Node.__init__(self, name)
249 self.parameters = parameters
250 self.throws = not not throws
254 return '%s(%r, %r, %r)' % (self.__class__.__name__,
255 self.name, self.retval,
258 class Function(Callable):
260 def __init__(self, name, retval, parameters, symbol, throws=None):
261 Callable.__init__(self, name, retval, parameters, throws)
263 self.is_method = False
266 def get_parameter_index(self, name):
267 for i, parameter in enumerate(self.parameters):
268 if parameter.name == name:
269 return i + int(self.is_method)
271 def get_parameter(self, name):
272 for parameter in self.parameters:
273 if parameter.name == name:
277 class VFunction(Callable):
279 def __init__(self, name, retval, parameters, throws):
280 Callable.__init__(self, name, retval, parameters, throws)
284 def from_callback(cls, cb):
285 obj = cls(cb.name, cb.retval, cb.parameters[1:],
292 def __init__(self, name, ctype=None):
293 Node.__init__(self, name)
295 self.resolved = False
296 self.is_const = False
297 self.canonical = None
298 self.derefed_canonical = None
304 Type.__init__(self, '<varargs>')
309 def __init__(self, name, ctype, element_type):
312 Type.__init__(self, name, ctype)
313 self.element_type = element_type
314 self.zeroterminated = True
315 self.length_param_index = -1
316 self.length_param_name = None
320 return 'Array(%r, %r)' % (self.name, self.element_type, )
325 def __init__(self, name, ctype, element_type):
326 Type.__init__(self, name, ctype)
327 self.element_type = element_type
330 return 'List(%r of %r)' % (self.name, self.element_type, )
335 def __init__(self, name, ctype, key_type, value_type):
336 Type.__init__(self, name, ctype)
337 self.key_type = key_type
338 self.value_type = value_type
341 return 'Map(%r <%r,%r>)' % (self.name, self.key_type, self.value_type)
346 def __init__(self, name, target, ctype=None):
347 Node.__init__(self, name)
352 return 'Alias(%r, %r)' % (self.name, self.target)
355 class TypeContainer(Node):
357 def __init__(self, name, typenode, transfer):
358 Node.__init__(self, name)
360 if transfer in [PARAM_TRANSFER_NONE, PARAM_TRANSFER_CONTAINER,
361 PARAM_TRANSFER_FULL]:
362 self.transfer = transfer
367 class Parameter(TypeContainer):
369 def __init__(self, name, typenode, direction=None,
370 transfer=None, allow_none=False, scope=None):
371 TypeContainer.__init__(self, name, typenode, transfer)
372 if direction in [PARAM_DIRECTION_IN, PARAM_DIRECTION_OUT,
373 PARAM_DIRECTION_INOUT, None]:
374 self.direction = direction
376 self.direction = PARAM_DIRECTION_IN
378 self.caller_allocates = False
379 self.allow_none = allow_none
381 self.closure_index = -1
382 self.destroy_index = -1
386 return 'Parameter(%r, %r)' % (self.name, self.type)
391 def __init__(self, name, symbol, members):
392 Node.__init__(self, name)
394 self.members = members
398 return 'Enum(%r, %r)' % (self.name, self.members)
401 class Bitfield(Node):
403 def __init__(self, name, symbol, members):
404 Node.__init__(self, name)
406 self.members = members
410 return 'Bitfield(%r, %r)' % (self.name, self.members)
415 def __init__(self, name, value, symbol):
416 Node.__init__(self, name)
421 return 'Member(%r, %r)' % (self.name, self.value)
426 def __init__(self, name, symbol, disguised=False):
427 Node.__init__(self, name)
429 self.constructors = []
431 self.disguised = disguised
435 def remove_matching_children(self, pred):
436 self.fields = filter(pred, self.fields)
437 self.constructors = filter(pred, self.constructors)
438 self.methods = filter(pred, self.methods)
446 def __init__(self, name, typenode, symbol, readable, writable, bits=None):
447 Node.__init__(self, name)
450 self.readable = readable
451 self.writable = writable
456 return 'Field(%r, %r, %r)' % (self.name, self.type, self.bits)
458 return 'Field(%r, %r)' % (self.name, self.type)
461 class Return(TypeContainer):
463 def __init__(self, rtype, transfer=None):
464 TypeContainer.__init__(self, None, rtype, transfer)
465 self.direction = PARAM_DIRECTION_OUT
469 return 'Return(%r)' % (self.type, )
474 def __init__(self, name, parent, is_abstract):
475 Node.__init__(self, name)
478 self.glib_type_struct = None
479 self.is_abstract = is_abstract
481 self.virtual_methods = []
482 self.static_methods = []
484 self.constructors = []
489 def remove_matching_children(self, pred):
490 self.methods = filter(pred, self.methods)
491 self.constructors = filter(pred, self.constructors)
492 self.properties = filter(pred, self.properties)
493 self.fields = filter(pred, self.fields)
496 return '%s(%r, %r, %r)' % (
497 self.__class__.__name__,
498 self.name, self.parent, self.methods)
501 class Interface(Node):
503 def __init__(self, name, parent):
504 Node.__init__(self, name)
507 self.virtual_methods = []
508 self.glib_type_struct = None
511 self.prerequisites = []
515 return '%s(%r, %r)' % (
516 self.__class__.__name__,
517 self.name, self.methods)
520 class Constant(Node):
522 def __init__(self, name, type_name, value):
523 Node.__init__(self, name)
524 self.type = Type(type_name)
528 return 'Constant(%r, %r, %r)' % (
529 self.name, self.type, self.value)
532 class Property(TypeContainer):
534 def __init__(self, name, type_name, readable, writable,
535 construct, construct_only, ctype=None, transfer=None):
536 self.type = Type(type_name, ctype)
537 TypeContainer.__init__(self, name, self.type, transfer)
538 self.readable = readable
539 self.writable = writable
540 self.construct = construct
541 self.construct_only = construct_only
545 return '%s(%r, %r)' % (
546 self.__class__.__name__,
547 self.name, self.type)
550 # FIXME: Inherit from Function
553 class Callback(Node):
555 def __init__(self, name, retval, parameters, ctype=None):
556 Node.__init__(self, name)
558 self.parameters = parameters
563 def get_parameter_index(self, name):
564 for i, parameter in enumerate(self.parameters):
565 if parameter.name == name:
568 def get_parameter(self, name):
569 for parameter in self.parameters:
570 if parameter.name == name:
574 return 'Callback(%r, %r, %r)' % (
575 self.name, self.retval, self.parameters)
580 def __init__(self, name, symbol):
581 Node.__init__(self, name)
583 self.constructors = []
589 return 'Union(%r, %r)' % (self.name, self.fields, )