diff options
author | Andreas Rottmann <a.rottmann@gmx.at> | 2009-01-03 13:44:42 +0000 |
---|---|---|
committer | Jürg Billeter <juergbi@src.gnome.org> | 2009-01-03 13:44:42 +0000 |
commit | bc88ef7bcda59b15988d27517a4f4f7e0672e33b (patch) | |
tree | 7e3af8b1d130ca9e4b5e78fb7314340d02b11eca /giscanner/transformer.py | |
parent | 00b0ae6bca603adc2c424c9a9384c60c4e4b1ccb (diff) | |
download | gobject-introspection-bc88ef7bcda59b15988d27517a4f4f7e0672e33b.tar.gz |
Bug 556489 – callback annotations
2008-01-03 Andreas Rottmann <a.rottmann@gmx.at>
Bug 556489 – callback annotations
* giscanner/transformer.py
* tools/generate.c (write_callable_info): Write out the new scope,
closure and destroy attributes.
* giscanner/transformer.py (Transformer._type_is_callback): New
method, checking if a given type is a callback.
(Transformer._augment_callback_params): New method; adds
information (closure, destroy) to callback parameters.
(Transformer._handle_closure, Transformer._handle_destroy): New methods,
auxiliary to _augment_callback_params.
(Transformer._create_function): Call _augment_callback_params().
(Transformer._create_parameter): Handle scope option.
(Transformer._create_typedef_callback): New method, creates a
callback, and registers it in the typedef namespace
(Transformer._create_typedef): Use _create_typedef_callback()
instead of the plain _create_callback().
* giscanner/ast.py (Parameter): Added callback-related fields.
* giscanner/girwriter.py: Write out new Parameter fields.
* girepository/girnode.h (GIrNodeParam): Added fields scope,
closure and destroy.
* girepository/gtypelib.h (ArgBlob): Ditto.
* girepository/girparser.c (start_parameter): Handle new fields.
* girepository/girmodule.c (g_ir_module_build_typelib): Adjust
arg_blob_size, bump major version due to this change.
* girepository/girnode.c (g_ir_node_get_full_size_internal)
(g_ir_node_build_typelib)
* girepository/gtypelib.c (g_typelib_check_sanity): ArgBlob size
adjustments.
(g_ir_node_build_typelib): Fill in new ArgBlob flags from param.
* girepository/girepository.h (GIScope): New enumeration, listing
the different possible scopes for callbacks.
* girepository/ginfo.c (g_arg_info_get_scope)
(g_arg_info_get_closure, g_arg_info_get_destroy): Accessors for
callback-related argument indices (callback scope, closure for a
callback, destroy notification for a callback).
* tests/scanner/: Added testcases for new features.
svn path=/trunk/; revision=998
Diffstat (limited to 'giscanner/transformer.py')
-rw-r--r-- | giscanner/transformer.py | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/giscanner/transformer.py b/giscanner/transformer.py index e7c7214a..0ed7ca00 100644 --- a/giscanner/transformer.py +++ b/giscanner/transformer.py @@ -269,6 +269,52 @@ class Transformer(object): if isinstance(return_.type, Array): self._pair_array(params, return_) + def _type_is_callback(self, type): + if (isinstance(type, Callback) or + isinstance(self._typedefs_ns.get(type.name), Callback)): + return True + return False + + def _handle_closure(self, param, closure_idx, closure_param): + if (closure_param.type.name == 'any' and + closure_param.name == 'user_data'): + param.closure_name = closure_param.name + param.closure_index = closure_idx + return True + return False + + def _handle_destroy(self, param, destroy_idx, destroy_param): + if ((self._namespace.name == 'GLib' and + destroy_param.type.name == 'DestroyNotify') or + destroy_param.type.name == 'GLib.DestroyNotify'): + param.destroy_name = destroy_param.name + param.destroy_index = destroy_idx + return True + return False + + def _augment_callback_params(self, params): + for i, param in enumerate(params): + if self._type_is_callback(param.type): + # j is the index where we look for closure/destroy to + # group with the callback param + j = i + 1 + if j == len(params): + continue # no more args -> nothing to group look + # at the param directly following for either a closure + # or a destroy; only one of these will fire + had_closure = self._handle_closure(param, j, params[j]) + had_destroy = self._handle_destroy(param, j, params[j]) + j += 1 + # are we out of params, or did we find neither? + if j == len(params) or (not had_closure and not had_destroy): + continue + # we found either a closure or a destroy; check the + # parameter following for the other + if not had_closure: + self._handle_closure(param, j, params[j]) + if not had_destroy: + self._handle_destroy(param, j, params[j]) + # We take the annotations from the parser as strings; here we # want to split them into components, so: # (transfer full) -> {'transfer' : [ 'full' ]} @@ -286,6 +332,7 @@ class Transformer(object): symbol.base_type, directives)) return_ = self._create_return(symbol.base_type.base_type, directives.get('return', {})) + self._augment_callback_params(parameters) self._pair_annotations(parameters, return_) name = self._strip_namespace_func(symbol.ident) func = Function(name, return_, parameters, symbol.ident) @@ -357,7 +404,7 @@ class Transformer(object): ctype = symbol.base_type.type if (ctype == CTYPE_POINTER and symbol.base_type.base_type.type == CTYPE_FUNCTION): - node = self._create_callback(symbol) + node = self._create_typedef_callback(symbol) elif (ctype == CTYPE_POINTER and symbol.base_type.base_type.type == CTYPE_STRUCT): node = self._create_typedef_struct(symbol, disguised=True) @@ -586,6 +633,8 @@ class Transformer(object): pass elif option in ('transfer', 'transfer-inferred'): pass + elif option == 'scope': + param.scope = data[0] else: print 'Unhandled parameter annotation option: %r' % ( option, ) @@ -642,6 +691,11 @@ class Transformer(object): self._create_union(symbol) return union + def _create_typedef_callback(self, symbol): + callback = self._create_callback(symbol) + self._typedefs_ns[callback.name] = callback + return callback + def _create_struct(self, symbol): directives = symbol.directives() struct = self._typedefs_ns.get(symbol.ident, None) |