mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-05 10:38:08 +01:00
Merge branch 'gi-static-vfuncs' into 'main'
Support static vfuncs in GIRepository See merge request GNOME/glib!4457
This commit is contained in:
commit
9b1e0a583a
@ -135,9 +135,12 @@ gi_callable_info_can_throw_gerror (GICallableInfo *info)
|
||||
*
|
||||
* Determines if the callable info is a method.
|
||||
*
|
||||
* For [class@GIRepository.VFuncInfo]s, [class@GIRepository.CallbackInfo]s, and
|
||||
* [class@GIRepository.SignalInfo]s, this is always true. Otherwise, this looks
|
||||
* at the `GI_FUNCTION_IS_METHOD` flag on the [class@GIRepository.FunctionInfo].
|
||||
* For [class@GIRepository.SignalInfo]s, this is always true, and for
|
||||
* [class@GIRepository.CallbackInfo]s always false.
|
||||
* For [class@GIRepository.FunctionInfo]s this looks at the
|
||||
* `GI_FUNCTION_IS_METHOD` flag on the [class@GIRepository.FunctionInfo].
|
||||
* For [class@GIRepository.VFuncInfo]s this is true when the virtual function
|
||||
* has an instance parameter.
|
||||
*
|
||||
* Concretely, this function returns whether
|
||||
* [method@GIRepository.CallableInfo.get_n_args] matches the number of arguments
|
||||
@ -159,6 +162,11 @@ gi_callable_info_is_method (GICallableInfo *info)
|
||||
return (!blob->constructor && !blob->is_static);
|
||||
}
|
||||
case GI_INFO_TYPE_VFUNC:
|
||||
{
|
||||
VFuncBlob *blob;
|
||||
blob = (VFuncBlob *) &rinfo->typelib->data[rinfo->offset];
|
||||
return !blob->is_static;
|
||||
}
|
||||
case GI_INFO_TYPE_SIGNAL:
|
||||
return TRUE;
|
||||
case GI_INFO_TYPE_CALLBACK:
|
||||
|
@ -243,6 +243,8 @@ struct _GIIrNodeVFunc
|
||||
uint8_t instance_transfer_full : 1;
|
||||
uint8_t is_async : 1;
|
||||
|
||||
uint8_t is_static : 1;
|
||||
|
||||
char *invoker; /* (owned) */
|
||||
char *finish_func; /* (owned) */
|
||||
char *sync_func; /* (owned) */
|
||||
|
@ -2029,6 +2029,7 @@ gi_ir_node_build_typelib (GIIrNode *node,
|
||||
blob->struct_offset = vfunc->offset;
|
||||
blob->reserved2 = 0;
|
||||
blob->signature = signature;
|
||||
blob->is_static = vfunc->is_static;
|
||||
|
||||
gi_ir_node_build_typelib ((GIIrNode *)vfunc->result->type,
|
||||
node, build, &signature, offset2, NULL);
|
||||
|
@ -2660,6 +2660,7 @@ start_vfunc (GMarkupParseContext *context,
|
||||
const char *offset;
|
||||
const char *invoker;
|
||||
const char *throws;
|
||||
const char *is_static;
|
||||
const char *finish_func;
|
||||
const char *async_func;
|
||||
const char *sync_func;
|
||||
@ -2682,6 +2683,7 @@ start_vfunc (GMarkupParseContext *context,
|
||||
offset = find_attribute ("offset", attribute_names, attribute_values);
|
||||
invoker = find_attribute ("invoker", attribute_names, attribute_values);
|
||||
throws = find_attribute ("throws", attribute_names, attribute_values);
|
||||
is_static = find_attribute ("glib:static", attribute_names, attribute_values);
|
||||
finish_func = find_attribute ("glib:finish-func", attribute_names, attribute_values);
|
||||
sync_func = find_attribute ("glib:sync-func", attribute_names, attribute_values);
|
||||
async_func = find_attribute ("glib:async-func", attribute_names, attribute_values);
|
||||
@ -2728,6 +2730,11 @@ start_vfunc (GMarkupParseContext *context,
|
||||
else
|
||||
vfunc->throws = FALSE;
|
||||
|
||||
if (is_static && strcmp (is_static, "1") == 0)
|
||||
vfunc->is_static = TRUE;
|
||||
else
|
||||
vfunc->is_static = FALSE;
|
||||
|
||||
if (offset == NULL)
|
||||
vfunc->offset = 0xFFFF;
|
||||
else if (g_ascii_string_to_unsigned (offset, 10, 0, G_MAXSIZE, &parsed_offset, error))
|
||||
|
@ -1117,6 +1117,7 @@ typedef struct {
|
||||
* @invoker: If a method invoker for this virtual exists, this is the offset
|
||||
* in the class structure of the method. If no method is known, this value
|
||||
* will be 0x3ff.
|
||||
* @is_static: True if the vfunc has no instance parameter.
|
||||
* @reserved: Reserved for future use.
|
||||
* @finish: The index of the finish function if is_async is TRUE, otherwise ASYNC_SENTINEL
|
||||
* @reserved2: Reserved for future use.
|
||||
@ -1142,7 +1143,8 @@ typedef struct {
|
||||
|
||||
uint16_t struct_offset;
|
||||
uint16_t invoker : 10; /* Number of bits matches @index in FunctionBlob */
|
||||
uint16_t reserved : 6;
|
||||
uint16_t is_static : 1;
|
||||
uint16_t reserved : 5;
|
||||
|
||||
uint16_t finish : 10;
|
||||
uint16_t reserved2 : 6;
|
||||
|
@ -124,6 +124,91 @@ test_callable_get_async_function_for_sync_function (RepositoryFixture *fx,
|
||||
gi_base_info_unref (info);
|
||||
}
|
||||
|
||||
static void
|
||||
test_callable_info_is_method (RepositoryFixture *fx,
|
||||
const void *unused)
|
||||
{
|
||||
GIBaseInfo *info;
|
||||
GIFunctionInfo *func_info;
|
||||
GIVFuncInfo *vfunc_info;
|
||||
GISignalInfo *sig_info;
|
||||
GIBaseInfo *cb_info;
|
||||
|
||||
info = gi_repository_find_by_name (fx->repository, "Gio", "ActionGroup");
|
||||
g_assert_nonnull (info);
|
||||
|
||||
func_info = gi_interface_info_find_method (GI_INTERFACE_INFO (info), "action_added");
|
||||
g_assert_nonnull (func_info);
|
||||
|
||||
g_assert_true (gi_callable_info_is_method (GI_CALLABLE_INFO (func_info)));
|
||||
|
||||
vfunc_info = gi_interface_info_find_vfunc (GI_INTERFACE_INFO (info), "action_added");
|
||||
g_assert_nonnull (vfunc_info);
|
||||
|
||||
g_assert_true (gi_callable_info_is_method (GI_CALLABLE_INFO (vfunc_info)));
|
||||
|
||||
sig_info = gi_interface_info_find_signal (GI_INTERFACE_INFO (info), "action-added");
|
||||
g_assert_nonnull (sig_info);
|
||||
|
||||
g_assert_true (gi_callable_info_is_method (GI_CALLABLE_INFO (sig_info)));
|
||||
|
||||
cb_info = gi_repository_find_by_name (fx->repository, "Gio", "AsyncReadyCallback");
|
||||
g_assert_nonnull (cb_info);
|
||||
|
||||
g_assert_false (gi_callable_info_is_method (GI_CALLABLE_INFO (cb_info)));
|
||||
|
||||
gi_base_info_unref (info);
|
||||
gi_base_info_unref ((GIBaseInfo *) func_info);
|
||||
gi_base_info_unref ((GIBaseInfo *) vfunc_info);
|
||||
gi_base_info_unref ((GIBaseInfo *) sig_info);
|
||||
gi_base_info_unref (cb_info);
|
||||
}
|
||||
|
||||
static void
|
||||
test_callable_info_static_method (RepositoryFixture *fx,
|
||||
const void *unused)
|
||||
{
|
||||
GIBaseInfo *info;
|
||||
GIFunctionInfo *func_info;
|
||||
|
||||
info = gi_repository_find_by_name (fx->repository, "Gio", "Application");
|
||||
g_assert_nonnull (info);
|
||||
|
||||
func_info = gi_object_info_find_method (GI_OBJECT_INFO (info), "get_default");
|
||||
g_assert_nonnull (func_info);
|
||||
|
||||
g_assert_false (gi_callable_info_is_method (GI_CALLABLE_INFO (func_info)));
|
||||
|
||||
gi_base_info_unref (info);
|
||||
gi_base_info_unref ((GIBaseInfo *) func_info);
|
||||
}
|
||||
|
||||
static void
|
||||
test_callable_info_static_vfunc (RepositoryFixture *fx,
|
||||
const void *unused)
|
||||
{
|
||||
GIBaseInfo *info;
|
||||
GIVFuncInfo *vfunc_info;
|
||||
|
||||
g_test_bug ("https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/361");
|
||||
|
||||
info = gi_repository_find_by_name (fx->repository, "Gio", "Icon");
|
||||
g_assert_nonnull (info);
|
||||
|
||||
vfunc_info = gi_interface_info_find_vfunc (GI_INTERFACE_INFO (info), "from_tokens");
|
||||
if (!vfunc_info)
|
||||
{
|
||||
g_test_skip ("g-ir-scanner is not new enough");
|
||||
return;
|
||||
}
|
||||
g_assert_nonnull (vfunc_info);
|
||||
|
||||
g_assert_false (gi_callable_info_is_method (GI_CALLABLE_INFO (vfunc_info)));
|
||||
|
||||
gi_base_info_unref (info);
|
||||
gi_base_info_unref ((GIBaseInfo *) vfunc_info);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@ -131,6 +216,9 @@ main (int argc, char **argv)
|
||||
|
||||
ADD_REPOSITORY_TEST ("/callable-info/sync-function", test_callable_get_sync_function_for_async_function, &typelib_load_spec_gio);
|
||||
ADD_REPOSITORY_TEST ("/callable-info/async-function", test_callable_get_async_function_for_sync_function, &typelib_load_spec_gio);
|
||||
ADD_REPOSITORY_TEST ("/callable-info/is-method", test_callable_info_is_method, &typelib_load_spec_gio);
|
||||
ADD_REPOSITORY_TEST ("/callable-info/static-method", test_callable_info_static_method, &typelib_load_spec_gio);
|
||||
ADD_REPOSITORY_TEST ("/callable-info/static-vfunc", test_callable_info_static_vfunc, &typelib_load_spec_gio);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user