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



commit 569a33955a12812920683d84f9b4bb3004f119bd
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                             |  2 +-
 tests/objects/signals-delegate-parameter.vala | 69 +++++++++++++++++++++++++++
 4 files changed, 125 insertions(+), 1 deletion(-)
---
diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala
index c19c9f901..8e31924bc 100644
--- a/codegen/valaccodeattribute.vala
+++ b/codegen/valaccodeattribute.vala
@@ -1037,6 +1037,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 b8a619b63..bce3ab7e9 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -76,6 +76,8 @@ public class Vala.GSignalModule : GObjectModule {
                        }
                } else if (t is ArrayType) {
                        return "gpointer";
+               } else if (t is DelegateType) {
+                       return "gpointer";
                } else if (t is ErrorType) {
                        return "gpointer";
                }
@@ -233,6 +235,16 @@ public class Vala.GSignalModule : GObjectModule {
                                        callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf 
(n_params), "gint"));
                                        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), "gpointer"));
+                                       n_params++;
+                                       if (delegate_type.is_disposable ()) {
+                                               callback_decl.add_parameter (new CCodeParameter 
("arg_%d".printf (n_params), "GDestroyNotify"));
+                                               n_params++;
+                                       }
+                               }
                        }
                }
                callback_decl.add_parameter (new CCodeParameter ("data2", "gpointer"));
@@ -288,6 +300,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) {
@@ -308,6 +322,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"));
@@ -424,6 +452,14 @@ public class Vala.GSignalModule : GObjectModule {
                        params_len++;
                        if (param.variable_type.is_array ()) {
                                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++;
+                                       }
+                               }
                        }
                }
 
@@ -438,6 +474,15 @@ public class Vala.GSignalModule : GObjectModule {
                                for (var i = 0; i < ((ArrayType) param.variable_type).rank; i++) {
                                        csignew.add_argument (new CCodeConstant ("G_TYPE_INT"));
                                }
+                       } 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 b31b5ed15..8ede3f3a0 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -343,7 +343,7 @@ TESTS = \
        objects/signals.vala \
        objects/signals-enum-marshal.vala \
        objects/signals-delegate.vala \
-       objects/signals-lambda-delegate.vala \
+       objects/signals-delegate-parameter.vala \
        objects/test-025.vala \
        objects/test-026.vala \
        objects/test-029.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]