[vala/staging] codegen: Add support for delegate parameters in signals



commit e1139c1a9cfb50e989a6d50f671128b2e0c5df52
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Tue Nov 27 23:53:56 2018 +0100

    codegen: Add support for delegate parameters in signals
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/205

 codegen/valaccodeattribute.vala               | 10 ++++
 codegen/valagsignalmodule.vala                | 45 +++++++++++++++++
 tests/Makefile.am                             |  1 +
 tests/objects/signals-delegate-parameter.vala | 69 +++++++++++++++++++++++++++
 4 files changed, 125 insertions(+)
---
diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala
index 0b89230e8..1c3665f80 100644
--- a/codegen/valaccodeattribute.vala
+++ b/codegen/valaccodeattribute.vala
@@ -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 {
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index a8aa450e6..562fc9cf6 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -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) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 919f95842..2fbed86b6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
index 000000000..e3de21eb8
--- /dev/null
+++ b/tests/objects/signals-delegate-parameter.vala
@@ -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 ();
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]