From f74823dbcb647dee950c066119876db9f0edc32f Mon Sep 17 00:00:00 2001 From: Johan Dahlin Date: Tue, 24 Nov 2009 22:18:27 -0200 Subject: Better scope in GAsyncReadyCallback/GDestroyNotify GAsyncReadyCallback should have use the async scope per default and GDestroyNotify should be notified if the previous parameters are a callback and user data. Fixes https://bugzilla.gnome.org/show_bug.cgi?id=602862 --- giscanner/annotationparser.py | 19 ++++++++++++++- tests/scanner/Makefile.am | 3 ++- tests/scanner/annotation-1.0-expected.gir | 1 + tests/scanner/annotation-1.0-expected.tgir | 2 +- tests/scanner/foo-1.0-expected.gir | 39 ++++++++++++++++++++++++++++++ tests/scanner/foo-1.0-expected.tgir | 33 +++++++++++++++++++++++++ tests/scanner/foo.h | 10 ++++++++ tests/scanner/utility-1.0-expected.gir | 1 + tests/scanner/utility-1.0-expected.tgir | 2 +- 9 files changed, 106 insertions(+), 4 deletions(-) diff --git a/giscanner/annotationparser.py b/giscanner/annotationparser.py index 1cedfb9c..f03c6240 100644 --- a/giscanner/annotationparser.py +++ b/giscanner/annotationparser.py @@ -73,6 +73,9 @@ OPT_ARRAY_FIXED_SIZE = 'fixed-size' OPT_ARRAY_LENGTH = 'length' OPT_ARRAY_ZERO_TERMINATED = 'zero-terminated' +OPT_SCOPE_ASYNC = 'async' +OPT_SCOPE_CALL = 'call' +OPT_SCOPE_NOTIFIED = 'notified' class InvalidAnnotationError(Exception): pass @@ -410,6 +413,16 @@ class AnnotationApplier(object): def _parse_callable(self, callable, block): self._parse_node_common(callable, block) + for i, param in enumerate(callable.parameters): + if param.type.name != 'GLib.DestroyNotify': + continue + if i < 2: + break + callback_param = callable.parameters[i-2] + if callback_param.closure_index != -1: + callback_param.scope = OPT_SCOPE_NOTIFIED + callback_param.transfer = PARAM_TRANSFER_NONE + self._parse_params(callable, callable.parameters, block) self._parse_return(callable, callable.retval, block) if block: @@ -490,11 +503,15 @@ class AnnotationApplier(object): def _parse_param(self, parent, param, tag): options = getattr(tag, 'options', {}) - if isinstance(parent, Function): + if isinstance(parent, Function) and not param.scope: scope = options.get(OPT_SCOPE) if scope: param.scope = scope.one() param.transfer = PARAM_TRANSFER_NONE + elif param.type.name == 'Gio.AsyncReadyCallback': + param.scope = OPT_SCOPE_ASYNC + param.transfer = PARAM_TRANSFER_NONE + destroy = options.get(OPT_DESTROY) if destroy: param.destroy_index = parent.get_parameter_index(destroy.one()) diff --git a/tests/scanner/Makefile.am b/tests/scanner/Makefile.am index a14cf8da..001a5822 100644 --- a/tests/scanner/Makefile.am +++ b/tests/scanner/Makefile.am @@ -12,7 +12,7 @@ testlibdir = $(prefix)/unused install-testlibLTLIBRARIES: # prevent it from being installed AM_CPPFLAGS = -I$(top_srcdir)/girepository -AM_CFLAGS = $(GOBJECT_CFLAGS) $(GTHREAD_CFLAGS) +AM_CFLAGS = $(GIO_CFLAGS) $(GOBJECT_CFLAGS) $(GTHREAD_CFLAGS) AM_LDFLAGS = -avoid-version LIBS = $(GOBJECT_LIBS) $(GTHREAD_LIBS) @@ -68,6 +68,7 @@ foo-1.0.gir: libfoo.la foo.c foo.h utility-1.0.gir $(SCANNER_BIN) $(SCANNER_LIBS $(CHECK_DEBUG) $(SCANNER) \ --include=GObject-2.0 \ --include=utility-1.0 \ + --include=Gio-2.0 \ --c-include="foo.h" \ --libtool="$(LIBTOOL)" \ --library=libfoo.la \ diff --git a/tests/scanner/annotation-1.0-expected.gir b/tests/scanner/annotation-1.0-expected.gir index df707fdc..33d5e7c6 100644 --- a/tests/scanner/annotation-1.0-expected.gir +++ b/tests/scanner/annotation-1.0-expected.gir @@ -455,6 +455,7 @@ type."> diff --git a/tests/scanner/annotation-1.0-expected.tgir b/tests/scanner/annotation-1.0-expected.tgir index bf0e35b3..835a547a 100644 --- a/tests/scanner/annotation-1.0-expected.tgir +++ b/tests/scanner/annotation-1.0-expected.tgir @@ -339,7 +339,7 @@ - + diff --git a/tests/scanner/foo-1.0-expected.gir b/tests/scanner/foo-1.0-expected.gir index fa3d73cd..d14218c0 100644 --- a/tests/scanner/foo-1.0-expected.gir +++ b/tests/scanner/foo-1.0-expected.gir @@ -8,6 +8,7 @@ and/or use gtk-doc annotations. --> xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> + @@ -702,6 +703,44 @@ uses a C sugar return type."> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/scanner/foo-1.0-expected.tgir b/tests/scanner/foo-1.0-expected.tgir index bcba5a2e..096efa58 100644 --- a/tests/scanner/foo-1.0-expected.tgir +++ b/tests/scanner/foo-1.0-expected.tgir @@ -4,6 +4,7 @@ xmlns:c="http://www.gtk.org/introspection/c/1.0" xmlns:glib="http://www.gtk.org/introspection/glib/1.0"> + @@ -568,6 +569,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/scanner/foo.h b/tests/scanner/foo.h index b8f88a78..61c2ca45 100644 --- a/tests/scanner/foo.h +++ b/tests/scanner/foo.h @@ -2,6 +2,7 @@ #define __FOO_OBJECT_H__ #include +#include /* GAsyncReadyCallback */ #include "utility.h" #define FOO_SUCCESS_INT 0x1138 @@ -344,6 +345,14 @@ void foo_test_varargs_callback2 (FooVarargsCallback callback); void foo_test_varargs_callback3 (FooVarargsCallback callback, FooVarargsCallback callback2); +/* Make sure callbacks get the right scope by default */ +void foo_async_ready_callback(GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +void foo_destroy_notify_callback(FooCallback callback, + gpointer data, + GDestroyNotify destroy); + typedef enum { FOO_ERROR_GOOD, FOO_ERROR_BAD, @@ -382,4 +391,5 @@ typedef enum { } FooSkippable; void foo_skip_me (FooSkippable fs); + #endif /* __FOO_OBJECT_H__ */ diff --git a/tests/scanner/utility-1.0-expected.gir b/tests/scanner/utility-1.0-expected.gir index 1b2fe84f..a597d5d7 100644 --- a/tests/scanner/utility-1.0-expected.gir +++ b/tests/scanner/utility-1.0-expected.gir @@ -74,6 +74,7 @@ and/or use gtk-doc annotations. --> diff --git a/tests/scanner/utility-1.0-expected.tgir b/tests/scanner/utility-1.0-expected.tgir index ec4597a7..a58a132d 100644 --- a/tests/scanner/utility-1.0-expected.tgir +++ b/tests/scanner/utility-1.0-expected.tgir @@ -54,7 +54,7 @@ - + -- cgit v1.2.1