File gobject-introspection-bgo729662-ownership-transfer.patch of Package gobject-introspection
diff --git a/girepository/gicallableinfo.c b/girepository/gicallableinfo.c
index 28c5950..bc60104 100644
--- a/girepository/gicallableinfo.c
+++ b/girepository/gicallableinfo.c
@@ -274,6 +274,32 @@ g_callable_info_get_caller_owns (GICallableInfo *info)
}
/**
+ * g_callable_info_get_instance_ownership_transfer:
+ * @info: a #GICallableInfo
+ *
+ * Obtains the ownership transfer for the instance argument.
+ * #GITransfer contains a list of possible transfer values.
+ *
+ * Returns: the transfer
+ */
+GITransfer
+g_callable_info_get_instance_ownership_transfer (GICallableInfo *info)
+{
+ GIRealInfo *rinfo = (GIRealInfo*) info;
+ SignatureBlob *blob;
+
+ g_return_val_if_fail (info != NULL, -1);
+ g_return_val_if_fail (GI_IS_CALLABLE_INFO (info), -1);
+
+ blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)];
+
+ if (blob->instance_transfer_ownership)
+ return GI_TRANSFER_EVERYTHING;
+ else
+ return GI_TRANSFER_NOTHING;
+}
+
+/**
* g_callable_info_get_n_args:
* @info: a #GICallableInfo
*
diff --git a/girepository/gicallableinfo.h b/girepository/gicallableinfo.h
index a7d7079..bc7068e 100644
--- a/girepository/gicallableinfo.h
+++ b/girepository/gicallableinfo.h
@@ -67,6 +67,8 @@ gboolean g_callable_info_invoke (GICallableInfo *info,
gboolean is_method,
gboolean throws,
GError **error);
+GITransfer g_callable_info_get_instance_ownership_transfer (GICallableInfo *info);
+
G_END_DECLS
diff --git a/girepository/girepository.symbols b/girepository/girepository.symbols
index 5f01adf..48fb0d9 100644
--- a/girepository/girepository.symbols
+++ b/girepository/girepository.symbols
@@ -26,6 +26,7 @@ g_info_new
g_callable_info_can_throw_gerror
g_callable_info_get_arg
g_callable_info_get_caller_owns
+g_callable_info_get_instance_ownership_transfer
g_callable_info_get_n_args
g_callable_info_get_return_attribute
g_callable_info_get_return_type
diff --git a/girepository/girnode.c b/girepository/girnode.c
index afb71e5..795c53c 100644
--- a/girepository/girnode.c
+++ b/girepository/girnode.c
@@ -1659,6 +1659,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob2->caller_owns_return_value = function->result->transfer;
blob2->caller_owns_return_container = function->result->shallow_transfer;
blob2->skip_return = function->result->skip;
+ blob2->instance_transfer_ownership = function->instance_transfer_full;
blob2->reserved = 0;
blob2->n_arguments = n;
@@ -1757,6 +1758,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob2->may_return_null = signal->result->allow_none;
blob2->caller_owns_return_value = signal->result->transfer;
blob2->caller_owns_return_container = signal->result->shallow_transfer;
+ blob2->instance_transfer_ownership = signal->instance_transfer_full;
blob2->reserved = 0;
blob2->n_arguments = n;
@@ -1815,6 +1817,7 @@ _g_ir_node_build_typelib (GIrNode *node,
blob2->may_return_null = vfunc->result->allow_none;
blob2->caller_owns_return_value = vfunc->result->transfer;
blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
+ blob2->instance_transfer_ownership = vfunc->instance_transfer_full;
blob2->reserved = 0;
blob2->n_arguments = n;
diff --git a/girepository/girnode.h b/girepository/girnode.h
index 07b084c..9c5c412 100644
--- a/girepository/girnode.h
+++ b/girepository/girnode.h
@@ -100,6 +100,7 @@ struct _GIrNodeFunction
gboolean is_constructor;
gboolean wraps_vfunc;
gboolean throws;
+ gboolean instance_transfer_full;
gchar *symbol;
@@ -188,6 +189,7 @@ struct _GIrNodeSignal
gboolean detailed;
gboolean action;
gboolean no_hooks;
+ gboolean instance_transfer_full;
gboolean has_class_closure;
gboolean true_stops_emit;
@@ -208,6 +210,7 @@ struct _GIrNodeVFunc
gboolean must_not_be_implemented;
gboolean is_class_closure;
gboolean throws;
+ gboolean instance_transfer_full;
char *invoker;
diff --git a/girepository/girparser.c b/girepository/girparser.c
index f96cfb1..3cb6e1d 100644
--- a/girepository/girparser.c
+++ b/girepository/girparser.c
@@ -1046,6 +1046,71 @@ parse_param_transfer (GIrNodeParam *param, const gchar *transfer, const gchar *n
}
static gboolean
+start_instance_parameter (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ ParseContext *ctx,
+ GError **error)
+{
+ const gchar *transfer;
+ gboolean transfer_full;
+
+ if (!(strcmp (element_name, "instance-parameter") == 0 &&
+ ctx->state == STATE_FUNCTION_PARAMETERS))
+ return FALSE;
+
+ transfer = find_attribute ("transfer-ownership", attribute_names, attribute_values);
+
+ state_switch (ctx, STATE_PASSTHROUGH);
+
+ if (strcmp (transfer, "full") == 0)
+ transfer_full = TRUE;
+ else if (strcmp (transfer, "none") == 0)
+ transfer_full = FALSE;
+ else
+ {
+ g_set_error (error, G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ "invalid value for 'transfer-ownership' for instance parameter: %s", transfer);
+ return FALSE;
+ }
+
+ switch (CURRENT_NODE (ctx)->type)
+ {
+ case G_IR_NODE_FUNCTION:
+ case G_IR_NODE_CALLBACK:
+ {
+ GIrNodeFunction *func;
+
+ func = (GIrNodeFunction *)CURRENT_NODE (ctx);
+ func->instance_transfer_full = transfer_full;
+ }
+ break;
+ case G_IR_NODE_SIGNAL:
+ {
+ GIrNodeSignal *signal;
+
+ signal = (GIrNodeSignal *)CURRENT_NODE (ctx);
+ signal->instance_transfer_full = transfer_full;
+ }
+ break;
+ case G_IR_NODE_VFUNC:
+ {
+ GIrNodeVFunc *vfunc;
+
+ vfunc = (GIrNodeVFunc *)CURRENT_NODE (ctx);
+ vfunc->instance_transfer_full = transfer_full;
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return TRUE;
+}
+
+static gboolean
start_parameter (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
@@ -2831,11 +2896,10 @@ start_element_handler (GMarkupParseContext *context,
attribute_names, attribute_values,
ctx, error))
goto out;
- else if (strcmp (element_name, "instance-parameter") == 0)
- {
- state_switch (ctx, STATE_PASSTHROUGH);
- goto out;
- }
+ else if (start_instance_parameter (context, element_name,
+ attribute_names, attribute_values,
+ ctx, error))
+ goto out;
else if (strcmp (element_name, "c:include") == 0)
{
state_switch (ctx, STATE_C_INCLUDE);
diff --git a/girepository/gitypelib-internal.h b/girepository/gitypelib-internal.h
index ac71008..6495f95 100644
--- a/girepository/gitypelib-internal.h
+++ b/girepository/gitypelib-internal.h
@@ -452,6 +452,8 @@ typedef struct {
* If the flag is set, the caller is resonsible for freeing the
* container, but not its contents.
* @skip_return: Indicates that the return value is only useful in C and should be skipped.
+ * @instance_transfer_ownership: When calling, the function assumes ownership of
+ * the instance parameter.
* @n_arguments: The number of arguments that this function expects, also the length
* of the array of ArgBlobs.
* @arguments: An array of ArgBlob for the arguments of the function.
@@ -463,7 +465,8 @@ typedef struct {
guint16 caller_owns_return_value : 1;
guint16 caller_owns_return_container : 1;
guint16 skip_return : 1;
- guint16 reserved :12;
+ guint16 instance_transfer_ownership : 1;
+ guint16 reserved :11;
guint16 n_arguments;
diff --git a/tests/repository/gitypelibtest.c b/tests/repository/gitypelibtest.c
index 565c95c..7b9cb35 100644
--- a/tests/repository/gitypelibtest.c
+++ b/tests/repository/gitypelibtest.c
@@ -276,6 +276,34 @@ test_signal_array_len (GIRepository * repo)
g_base_info_unref (testobj_info);
}
+static void
+test_instance_transfer_ownership (GIRepository * repo)
+{
+ GIObjectInfo *testobj_info;
+ GIFunctionInfo *func_info;
+ GITransfer transfer;
+
+ g_assert (g_irepository_require (repo, "Regress", NULL, 0, NULL));
+ testobj_info = g_irepository_find_by_name (repo, "Regress", "TestObj");
+ g_assert (testobj_info != NULL);
+
+ func_info = g_object_info_find_method (testobj_info, "instance_method");
+ g_assert (func_info != NULL);
+ transfer = g_callable_info_get_instance_ownership_transfer ((GICallableInfo*) func_info);
+ g_assert_cmpint (GI_TRANSFER_NOTHING, ==, transfer);
+
+ g_base_info_unref (func_info);
+
+ func_info = g_object_info_find_method (testobj_info, "instance_method_full");
+ g_assert (func_info != NULL);
+ transfer = g_callable_info_get_instance_ownership_transfer ((GICallableInfo*) func_info);
+ g_assert_cmpint (GI_TRANSFER_EVERYTHING, ==, transfer);
+
+ g_base_info_unref (func_info);
+
+ g_base_info_unref (testobj_info);
+}
+
int
main (int argc, char **argv)
{
@@ -292,6 +320,7 @@ main (int argc, char **argv)
test_hash_with_cairo_typelib (repo);
test_char_types (repo);
test_signal_array_len (repo);
+ test_instance_transfer_ownership (repo);
exit (0);
}
diff --git a/tests/scanner/Regress-1.0-expected.gir b/tests/scanner/Regress-1.0-expected.gir
index 0dadc59..0648487 100644
--- a/tests/scanner/Regress-1.0-expected.gir
+++ b/tests/scanner/Regress-1.0-expected.gir
@@ -2929,6 +2929,17 @@ case.</doc>
</parameter>
</parameters>
</method>
+ <method name="instance_method_full"
+ c:identifier="regress_test_obj_instance_method_full">
+ <return-value transfer-ownership="none">
+ <type name="none" c:type="void"/>
+ </return-value>
+ <parameters>
+ <instance-parameter name="obj" transfer-ownership="full">
+ <type name="TestObj" c:type="RegressTestObj*"/>
+ </instance-parameter>
+ </parameters>
+ </method>
<method name="set_bare" c:identifier="regress_test_obj_set_bare">
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
diff --git a/tests/scanner/Regress-1.0-sections-expected.txt b/tests/scanner/Regress-1.0-sections-expected.txt
index 96df7c5..f6af199 100644
--- a/tests/scanner/Regress-1.0-sections-expected.txt
+++ b/tests/scanner/Regress-1.0-sections-expected.txt
@@ -332,6 +332,7 @@ regress_test_obj_emit_sig_with_uint64
regress_forced_method
regress_test_obj_instance_method
regress_test_obj_instance_method_callback
+regress_test_obj_instance_method_full
regress_test_obj_set_bare
regress_test_obj_skip_inout_param
regress_test_obj_skip_out_param
diff --git a/tests/scanner/regress.c b/tests/scanner/regress.c
index d32c52b..9116591 100644
--- a/tests/scanner/regress.c
+++ b/tests/scanner/regress.c
@@ -2681,6 +2681,17 @@ regress_test_obj_instance_method (RegressTestObj *obj)
return -1;
}
+/**
+ * regress_test_obj_instance_method_full:
+ * @obj: (transfer full):
+ *
+ */
+void
+regress_test_obj_instance_method_full (RegressTestObj *obj)
+{
+ g_object_unref (obj);
+}
+
double
regress_test_obj_static_method (int x)
{
diff --git a/tests/scanner/regress.h b/tests/scanner/regress.h
index 274d0e4..ce0663e 100644
--- a/tests/scanner/regress.h
+++ b/tests/scanner/regress.h
@@ -516,6 +516,7 @@ void regress_test_obj_emit_sig_with_foreign_struct (RegressTestObj *obj);
void regress_test_obj_emit_sig_with_int64 (RegressTestObj *obj);
void regress_test_obj_emit_sig_with_uint64 (RegressTestObj *obj);
int regress_test_obj_instance_method (RegressTestObj *obj);
+void regress_test_obj_instance_method_full (RegressTestObj *obj);
double regress_test_obj_static_method (int x);
void regress_forced_method (RegressTestObj *obj);