From 7acef299c26b44a7245ff9b4f35bd2f2b9d420a8 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 5 Feb 2024 18:40:03 +0000 Subject: [PATCH] =?UTF-8?q?girepository:=20Fix=20declaration=20of=20?= =?UTF-8?q?=E2=80=98find=20using=20interfaces=E2=80=99=20methods?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the declaration and documentation of `gi_object_info_find_method_using_interfaces()` and `gi_object_info_find_vfunc_using_interfaces()`. The documentation was wrong when I wrote it: the value returned is the object or interface which declares the method or vfunc, not the one which implements it. The returned declarer info may be a `GIObjectInfo` or a `GIInterfaceInfo`. Since those two types have no subtype relation between them, the return type has to be changed to `GIBaseInfo`. Using `GIObjectInfo` would have been fine in girepository-1.0 because all `*Info` types were aliases of each other — but since the move to `GTypeInstance` this is no longer true. A unit test will be in the following commit. Signed-off-by: Philip Withnall Fixes: #3246 --- docs/reference/girepository/migrating-gi.md | 1 + girepository/giobjectinfo.c | 54 ++++++++++++--------- girepository/giobjectinfo.h | 4 +- 3 files changed, 33 insertions(+), 26 deletions(-) diff --git a/docs/reference/girepository/migrating-gi.md b/docs/reference/girepository/migrating-gi.md index cca213fd7..6fd5e9662 100644 --- a/docs/reference/girepository/migrating-gi.md +++ b/docs/reference/girepository/migrating-gi.md @@ -53,6 +53,7 @@ your code if integer type warnings are enabled. | `g_callable_info_invoke` arguments | `is_method` and `throws` dropped in [method@GIRepository.CallableInfo.invoke] | | `g_constant_info_get_type` | [method@GIRepository.ConstantInfo.get_type_info] | | `g_field_info_get_type` | [method@GIRepository.FieldInfo.get_type_info] | +| `g_object_info_find_method_using_interfaces` and `g_object_info_find_vfunc_using_interfaces` | The `implementor` out argument has been renamed to `declarer` and is now of type [type@GIRepository.BaseInfo] | | `g_object_info_get_type_init` | [method@GIRepository.ObjectInfo.get_type_init_function_name] | | `g_object_info_get_ref_function` | [method@GIRepository.ObjectInfo.get_ref_function_name] | | `g_object_info_get_unref_function` | [method@GIRepository.ObjectInfo.get_unref_function_name] | diff --git a/girepository/giobjectinfo.c b/girepository/giobjectinfo.c index b55390ed9..0e7cc5545 100644 --- a/girepository/giobjectinfo.c +++ b/girepository/giobjectinfo.c @@ -496,9 +496,10 @@ gi_object_info_find_method (GIObjectInfo *info, * gi_object_info_find_method_using_interfaces: * @info: a #GIObjectInfo * @name: name of method to obtain - * @implementor: (out) (transfer full) (optional) (nullable): The implementor of - * the interface, or `NULL` to ignore. If no method is found, this will return - * `NULL`. + * @declarer: (out) (transfer full) (optional) (nullable): The + * [class@GIRepository.ObjectInfo] or [class@GIRepository.InterfaceInfo] which + * declares the method, or `NULL` to ignore. If no method is found, this will + * return `NULL`. * * Obtain a method of the object given a @name, searching both the * object @info and any interfaces it implements. @@ -516,14 +517,14 @@ gi_object_info_find_method (GIObjectInfo *info, GIFunctionInfo * gi_object_info_find_method_using_interfaces (GIObjectInfo *info, const char *name, - GIObjectInfo **implementor) + GIBaseInfo **declarer) { GIFunctionInfo *result = NULL; - GIObjectInfo *implementor_result = NULL; + GIBaseInfo *declarer_result = NULL; result = gi_object_info_find_method (info, name); if (result) - implementor_result = (GIObjectInfo *) gi_base_info_ref ((GIBaseInfo*) info); + declarer_result = gi_base_info_ref (info); if (result == NULL) { @@ -541,17 +542,19 @@ gi_object_info_find_method_using_interfaces (GIObjectInfo *info, if (result != NULL) { - implementor_result = (GIObjectInfo *) iface_info; + declarer_result = GI_BASE_INFO (g_steal_pointer (&iface_info)); break; } gi_base_info_unref ((GIBaseInfo*) iface_info); } } - if (implementor) - *implementor = implementor_result; - else if (implementor_result != NULL) - gi_base_info_unref ((GIBaseInfo*) implementor_result); - return result; + + if (declarer) + *declarer = g_steal_pointer (&declarer_result); + + g_clear_pointer (&declarer_result, gi_base_info_unref); + + return g_steal_pointer (&result); } /** @@ -766,9 +769,10 @@ gi_object_info_find_vfunc (GIObjectInfo *info, * gi_object_info_find_vfunc_using_interfaces: * @info: a #GIObjectInfo * @name: name of vfunc to obtain - * @implementor: (out) (transfer full) (optional) (nullable): The implementor of - * the interface, or `NULL` to ignore. If no vfunc is found, this will return - * `NULL`. + * @declarer: (out) (transfer full) (optional) (nullable): The + * [class@GIRepository.ObjectInfo] or [class@GIRepository.InterfaceInfo] which + * declares the vfunc, or `NULL` to ignore. If no vfunc is found, this will + * return `NULL`. * * Locate a virtual function slot with name @name, searching both the object * @info and any interfaces it implements. @@ -791,14 +795,14 @@ gi_object_info_find_vfunc (GIObjectInfo *info, GIVFuncInfo * gi_object_info_find_vfunc_using_interfaces (GIObjectInfo *info, const char *name, - GIObjectInfo **implementor) + GIBaseInfo **declarer) { GIVFuncInfo *result = NULL; - GIObjectInfo *implementor_result = NULL; + GIBaseInfo *declarer_result = NULL; result = gi_object_info_find_vfunc (info, name); if (result) - implementor_result = (GIObjectInfo *) gi_base_info_ref ((GIBaseInfo*) info); + declarer_result = gi_base_info_ref (info); if (result == NULL) { @@ -816,17 +820,19 @@ gi_object_info_find_vfunc_using_interfaces (GIObjectInfo *info, if (result != NULL) { - implementor_result = (GIObjectInfo *) iface_info; + declarer_result = GI_BASE_INFO (g_steal_pointer (&iface_info)); break; } gi_base_info_unref ((GIBaseInfo*) iface_info); } } - if (implementor) - *implementor = implementor_result; - else if (implementor_result != NULL) - gi_base_info_unref ((GIBaseInfo*) implementor_result); - return result; + + if (declarer) + *declarer = g_steal_pointer (&declarer_result); + + g_clear_pointer (&declarer_result, gi_base_info_unref); + + return g_steal_pointer (&result); } /** diff --git a/girepository/giobjectinfo.h b/girepository/giobjectinfo.h index 8065612ce..cb652704d 100644 --- a/girepository/giobjectinfo.h +++ b/girepository/giobjectinfo.h @@ -156,7 +156,7 @@ GIFunctionInfo * gi_object_info_find_method (GIObjectInfo *info, GI_AVAILABLE_IN_ALL GIFunctionInfo * gi_object_info_find_method_using_interfaces (GIObjectInfo *info, const char *name, - GIObjectInfo **implementor); + GIBaseInfo **declarer); GI_AVAILABLE_IN_ALL @@ -186,7 +186,7 @@ GIVFuncInfo * gi_object_info_find_vfunc (GIObjectInfo *info, GI_AVAILABLE_IN_ALL GIVFuncInfo * gi_object_info_find_vfunc_using_interfaces (GIObjectInfo *info, const char *name, - GIObjectInfo **implementor); + GIBaseInfo **declarer); GI_AVAILABLE_IN_ALL unsigned int gi_object_info_get_n_constants (GIObjectInfo *info);