From d220bb74c25ce098fb3cb074bb03a0868032e89c Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 9 Apr 2012 15:41:39 -0300 Subject: gicallableinfo: Add two new convenience methods: is_method and can_throw_gerror https://bugzilla.gnome.org/show_bug.cgi?id=673805 --- girepository/gicallableinfo.c | 70 +++++++++++++++++++++++++++++++++++++++++++ girepository/gicallableinfo.h | 2 ++ girepository/girffi.c | 29 ++---------------- 3 files changed, 74 insertions(+), 27 deletions(-) diff --git a/girepository/gicallableinfo.c b/girepository/gicallableinfo.c index 95fa2fc2..28c5950e 100644 --- a/girepository/gicallableinfo.c +++ b/girepository/gicallableinfo.c @@ -81,6 +81,76 @@ signature_offset (GICallableInfo *info) return 0; } +/** + * g_callable_info_can_throw_gerror: + * @info: a #GICallableInfo + * + * Returns: %TRUE if this #GICallableInfo can throw a #GError + * + * Since: 1.34 + */ +gboolean +g_callable_info_can_throw_gerror (GICallableInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*)info; + switch (rinfo->type) { + case GI_INFO_TYPE_FUNCTION: + { + FunctionBlob *blob; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + return blob->throws; + } + case GI_INFO_TYPE_VFUNC: + { + VFuncBlob *blob; + blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset]; + return blob->throws; + } + case GI_INFO_TYPE_CALLBACK: + case GI_INFO_TYPE_SIGNAL: + return FALSE; + default: + g_assert_not_reached (); + } +} + +/** + * g_callable_info_is_method: + * @info: a #GICallableInfo + * + * Determines if the callable info is a method. For #GIVFuncInfos, + * #GICallbackInfos, and #GISignalInfos, + * this is always true. Otherwise, this looks at the %GI_FUNCTION_IS_METHOD + * flag on the #GIFunctionInfo. + * + * Concretely, this function returns whether g_callable_info_get_n_args() + * matches the number of arguments in the raw C method. For methods, there + * is one more C argument than is exposed by introspection: the "self" + * or "this" object. + * + * Since: 1.34 + */ +gboolean +g_callable_info_is_method (GICallableInfo *info) +{ + GIRealInfo *rinfo = (GIRealInfo*)info; + switch (rinfo->type) { + case GI_INFO_TYPE_FUNCTION: + { + FunctionBlob *blob; + blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset]; + return (!blob->constructor && !blob->is_static); + } + case GI_INFO_TYPE_VFUNC: + case GI_INFO_TYPE_SIGNAL: + return TRUE; + case GI_INFO_TYPE_CALLBACK: + return FALSE; + default: + g_assert_not_reached (); + } +} + /** * g_callable_info_get_return_type: * @info: a #GICallableInfo diff --git a/girepository/gicallableinfo.h b/girepository/gicallableinfo.h index 48c08c41..a7d7079a 100644 --- a/girepository/gicallableinfo.h +++ b/girepository/gicallableinfo.h @@ -37,6 +37,8 @@ G_BEGIN_DECLS (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_SIGNAL) || \ (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_VFUNC)) +gboolean g_callable_info_is_method (GICallableInfo *info); +gboolean g_callable_info_can_throw_gerror (GICallableInfo *info); GITypeInfo * g_callable_info_get_return_type (GICallableInfo *info); void g_callable_info_load_return_type (GICallableInfo *info, GITypeInfo *type); diff --git a/girepository/girffi.c b/girepository/girffi.c index 11400613..f6e47fb0 100644 --- a/girepository/girffi.c +++ b/girepository/girffi.c @@ -289,33 +289,8 @@ g_function_invoker_new_for_address (gpointer addr, invoker->native_address = addr; - info_type = g_base_info_get_type ((GIBaseInfo *) info); - - switch (info_type) - { - case GI_INFO_TYPE_FUNCTION: - { - GIFunctionInfoFlags flags; - flags = g_function_info_get_flags ((GIFunctionInfo *)info); - is_method = (flags & GI_FUNCTION_IS_METHOD) != 0; - throws = (flags & GI_FUNCTION_THROWS) != 0; - } - break; - case GI_INFO_TYPE_VFUNC: - { - GIVFuncInfoFlags flags; - flags = g_vfunc_info_get_flags ((GIVFuncInfo *)info); - throws = (flags & GI_VFUNC_THROWS) != 0; - } - is_method = TRUE; - break; - case GI_INFO_TYPE_CALLBACK: - is_method = TRUE; - throws = FALSE; - break; - default: - g_assert_not_reached (); - } + is_method = g_callable_info_is_method (info); + throws = g_callable_info_can_throw_gerror (info); tinfo = g_callable_info_get_return_type (info); rtype = g_type_info_get_ffi_type (tinfo); -- cgit v1.2.1