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);
openSUSE Build Service is sponsored by