]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Fix signals with generic return
authorRico Tzschichholz <ricotz@ubuntu.com>
Fri, 26 Nov 2021 14:34:40 +0000 (15:34 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Mon, 29 Nov 2021 12:31:37 +0000 (13:31 +0100)
In addition to 36999b5ffd63cc56a8648791b02bf07e7da88077

codegen/valagsignalmodule.vala
tests/Makefile.am
tests/objects/signals-generic-return.vala [new file with mode: 0644]
vala/valasignal.vala

index 126e78a44f744adf6a95c202aa79f75aa80330ca..17b681365d128976e0f60c29dcd49f489c959a3c 100644 (file)
@@ -242,7 +242,7 @@ public class Vala.GSignalModule : GObjectModule {
 
                CCodeFunctionCall fc;
 
-               if (return_type.type_symbol != null || return_type is ArrayType) {
+               if (return_type.type_symbol != null || return_type is ArrayType || return_type is GenericType) {
                        ccode.add_declaration (get_value_type_name_from_type_reference (return_type), new CCodeVariableDeclarator ("v_return"));
 
                        fc = new CCodeFunctionCall (new CCodeIdentifier ("g_return_if_fail"));
@@ -318,7 +318,7 @@ public class Vala.GSignalModule : GObjectModule {
                }
                fc.add_argument (new CCodeIdentifier ("data2"));
 
-               if (return_type.type_symbol != null || return_type is ArrayType) {
+               if (return_type.type_symbol != null || return_type is ArrayType || return_type is GenericType) {
                        ccode.add_assignment (new CCodeIdentifier ("v_return"), fc);
 
                        CCodeFunctionCall set_fc;
index 9b4feb1cd3fa04d72ac246a7231e2095f0baa3a4..a2522ce6cf8c02b591aad5e15bb1fedbe9fdb888 100644 (file)
@@ -532,6 +532,7 @@ TESTS = \
        objects/signals-dynamic-lambda-handler.test \
        objects/signals-error-marshal.vala \
        objects/signals-fundamental-return.vala \
+       objects/signals-generic-return.vala \
        objects/signals-gobject-return.vala \
        objects/signals-lambda-delegate.vala \
        objects/signals-prototype-access.vala \
diff --git a/tests/objects/signals-generic-return.vala b/tests/objects/signals-generic-return.vala
new file mode 100644 (file)
index 0000000..410cdc7
--- /dev/null
@@ -0,0 +1,39 @@
+class Foo<G,T> : Object {
+       public signal G on_foo ();
+       public signal T on_bar ();
+}
+
+int cb_foo () {
+       return 23;
+}
+
+string cb_bar () {
+       return "foo";
+}
+
+void main () {
+       {
+               var foo = new Foo<int,string> ();
+               foo.on_foo.connect (() => {
+                       return 42;
+               });
+               foo.on_bar.connect (() => {
+                       return "bar";
+               });
+
+               var bar = foo.on_foo ();
+               assert (bar == 42);
+               var bar2 = foo.on_bar ();
+               assert (bar2 == "bar");
+       }
+       {
+               var foo = new Foo<int,string> ();
+               foo.on_foo.connect (cb_foo);
+               foo.on_bar.connect (cb_bar);
+
+               var bar = foo.on_foo ();
+               assert (bar == 23);
+               var bar2 = foo.on_bar ();
+               assert (bar2 == "foo");
+       }
+}
index 8e805d682cf82ef16c542096a46deaa6c818f9d4..ffd5a760affea6aa490b57bf84d31da9e6d68755 100644 (file)
@@ -115,7 +115,7 @@ public class Vala.Signal : Symbol, Callable {
 
                generated_delegate.sender_type = sender_param_type;
 
-               bool is_generic = false;
+               bool is_generic = actual_return_type.is_generic ();
 
                foreach (Parameter param in parameters) {
                        var actual_param = param.copy ();
@@ -133,8 +133,11 @@ public class Vala.Signal : Symbol, Callable {
                                generated_delegate.add_type_parameter (new TypeParameter (type_param.name, type_param.source_reference));
                        }
 
-                       // parameter types must refer to the delegate type parameters
+                       // return type and parameter types must refer to the delegate type parameters
                        // instead of to the class type parameters
+                       foreach (var type_param in generated_delegate.get_type_parameters ()) {
+                               actual_return_type.replace_type_parameter (cl.get_type_parameters ().get (cl.get_type_parameter_index (type_param.name)), type_param);
+                       }
                        foreach (var param in generated_delegate.get_parameters ()) {
                                foreach (var type_param in generated_delegate.get_type_parameters ()) {
                                        param.variable_type.replace_type_parameter (cl.get_type_parameters ().get (cl.get_type_parameter_index (type_param.name)), type_param);