]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Add support for delegate parameters in signals
authorRico Tzschichholz <ricotz@ubuntu.com>
Tue, 27 Nov 2018 22:53:56 +0000 (23:53 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 28 Nov 2018 07:56:24 +0000 (08:56 +0100)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/205

codegen/valaccodeattribute.vala
codegen/valagsignalmodule.vala
tests/Makefile.am
tests/objects/signals-delegate-parameter.vala [new file with mode: 0644]

index 0b89230e89c2719aa563373f3935f2931f8f9987..1c3665f80142e7c490ab4a6a3094aac8e3026342 100644 (file)
@@ -1063,6 +1063,16 @@ public class Vala.CCodeAttribute : AttributeCache {
                                }
                                return ret;
                        }
+               } else if (node is DelegateType) {
+                       unowned DelegateType delegate_type = (DelegateType) node;
+                       var ret = "POINTER";
+                       if (delegate_type.delegate_symbol.has_target) {
+                               ret = "%s,POINTER".printf (ret);
+                               if (delegate_type.is_disposable ()) {
+                                       ret = "%s,POINTER".printf (ret);
+                               }
+                       }
+                       return ret;
                } else if (node is VoidType) {
                        return "VOID";
                } else {
index a8aa450e6b12acf9e2188846f0955c3cfa1c51be..562fc9cf6392677db4b2cd24071b131120a62d47 100644 (file)
@@ -71,6 +71,8 @@ public class Vala.GSignalModule : GObjectModule {
                        return "gint";
                } else if (t is ArrayType) {
                        return "gpointer";
+               } else if (t is DelegateType) {
+                       return "gpointer";
                } else if (t is ErrorType) {
                        return "gpointer";
                }
@@ -199,6 +201,16 @@ public class Vala.GSignalModule : GObjectModule {
                                        callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf (n_params), length_ctype));
                                        n_params++;
                                }
+                       } else if (p.variable_type is DelegateType) {
+                               unowned DelegateType delegate_type = (DelegateType) p.variable_type;
+                               if (delegate_type.delegate_symbol.has_target) {
+                                       callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf (n_params), get_ccode_name (delegate_target_type)));
+                                       n_params++;
+                                       if (delegate_type.is_disposable ()) {
+                                               callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf (n_params), get_ccode_name (delegate_target_destroy_type)));
+                                               n_params++;
+                                       }
+                               }
                        }
                }
                callback_decl.add_parameter (new CCodeParameter ("data2", "gpointer"));
@@ -253,6 +265,8 @@ public class Vala.GSignalModule : GObjectModule {
                                } else {
                                        get_value_function = "g_value_get_pointer";
                                }
+                       } else if (p.variable_type is DelegateType) {
+                               get_value_function = "g_value_get_pointer";
                        } else if (p.variable_type is PointerType || p.variable_type is GenericType) {
                                get_value_function = "g_value_get_pointer";
                        } else if (p.variable_type is ErrorType) {
@@ -276,6 +290,20 @@ public class Vala.GSignalModule : GObjectModule {
                                        fc.add_argument (inner_fc);
                                        i++;
                                }
+                       } else if (p.variable_type is DelegateType) {
+                               unowned DelegateType delegate_type = (DelegateType) p.variable_type;
+                               if (delegate_type.delegate_symbol.has_target) {
+                                       inner_fc = new CCodeFunctionCall (new CCodeIdentifier (get_value_function));
+                                       inner_fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("param_values"), new CCodeIdentifier (i.to_string ())));
+                                       fc.add_argument (inner_fc);
+                                       i++;
+                                       if (delegate_type.is_disposable ()) {
+                                               inner_fc = new CCodeFunctionCall (new CCodeIdentifier (get_value_function));
+                                               inner_fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("param_values"), new CCodeIdentifier (i.to_string ())));
+                                               fc.add_argument (inner_fc);
+                                               i++;
+                                       }
+                               }
                        }
                }
                fc.add_argument (new CCodeIdentifier ("data2"));
@@ -392,6 +420,14 @@ public class Vala.GSignalModule : GObjectModule {
                        params_len++;
                        if (param.variable_type is ArrayType) {
                                params_len += ((ArrayType) param.variable_type).rank;
+                       } else if (param.variable_type is DelegateType) {
+                               unowned DelegateType delegate_type = (DelegateType) param.variable_type;
+                               if (delegate_type.delegate_symbol.has_target) {
+                                       params_len++;
+                                       if (delegate_type.is_disposable ()) {
+                                               params_len++;
+                                       }
+                               }
                        }
                }
 
@@ -409,6 +445,15 @@ public class Vala.GSignalModule : GObjectModule {
                                for (var i = 0; i < array_type.rank; i++) {
                                        csignew.add_argument (new CCodeConstant (length_type_id));
                                }
+                       } else if (param.variable_type is DelegateType) {
+                               unowned DelegateType delegate_type = (DelegateType) param.variable_type;
+                               csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
+                               if (delegate_type.delegate_symbol.has_target) {
+                                       csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
+                                       if (delegate_type.is_disposable ()) {
+                                               csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
+                                       }
+                               }
                        } else if (param.variable_type is PointerType || param.variable_type is GenericType || param.direction != ParameterDirection.IN) {
                                csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
                        } else if (param.variable_type is ErrorType) {
index 919f958423aea77780a5d065d087abce428eb818..2fbed86b62137ff4cfcd8f8f46bbd4dab851af7a 100644 (file)
@@ -268,6 +268,7 @@ TESTS = \
        objects/regex.vala \
        objects/signals.vala \
        objects/signals-delegate.vala \
+       objects/signals-delegate-parameter.vala \
        objects/singleton.vala \
        objects/test-025.vala \
        objects/test-026.vala \
diff --git a/tests/objects/signals-delegate-parameter.vala b/tests/objects/signals-delegate-parameter.vala
new file mode 100644 (file)
index 0000000..e3de21e
--- /dev/null
@@ -0,0 +1,69 @@
+delegate void FooFunc ();
+[CCode (has_target = false)]
+delegate void BarFunc ();
+
+class Foo : Object {
+       public signal void delegate_param_no_target (BarFunc f);
+       public signal void delegate_param_with_target (FooFunc f);
+       public signal void delegate_param_with_destroy (owned FooFunc f);
+}
+
+void no_target_cb (BarFunc f) {
+       f ();
+}
+
+void with_target_cb (FooFunc f) {
+       f ();
+}
+
+void with_destroy_cb (owned FooFunc f) {
+       f ();
+}
+
+bool success1 = false;
+
+class Bar : Object {
+       Foo foo;
+
+       bool success2 = false;
+       bool success3 = false;
+
+       public Bar () {
+               foo = new Foo ();
+       }
+
+       public void test_no_target () {
+               foo.delegate_param_no_target.connect (no_target_cb);
+               foo.delegate_param_no_target (() => {
+                       success1 = true;
+               });
+               assert (success1);
+       }
+
+       public void test_with_target () {
+               foo.delegate_param_with_target.connect (with_target_cb);
+               foo.delegate_param_with_target (() => {
+                       assert (this.ref_count == 1);
+                       success2 = true;
+               });
+               assert (this.ref_count == 1);
+               assert (success2);
+       }
+
+       public void test_with_destroy () {
+               foo.delegate_param_with_destroy.connect (with_destroy_cb);
+               foo.delegate_param_with_destroy (() => {
+                       assert (this.ref_count == 2);
+                       success3 = true;
+               });
+               assert (this.ref_count == 1);
+               assert (success3);
+       }
+}
+
+void main () {
+       var bar = new Bar ();
+       bar.test_no_target ();
+       bar.test_with_target ();
+       bar.test_with_destroy ();
+}