]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Replace all type parameter occurances in parameters for signal delegate
authorRico Tzschichholz <ricotz@ubuntu.com>
Wed, 10 Mar 2021 11:12:06 +0000 (12:12 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Sat, 13 Mar 2021 20:43:33 +0000 (21:43 +0100)
Improves 36999b5ffd63cc56a8648791b02bf07e7da88077

tests/Makefile.am
tests/objects/bug626038-2.vala [new file with mode: 0644]
vala/valadatatype.vala
vala/valasignal.vala

index 021eb8c30d91b78030ae5a73b5af582ce39af39b..6b77ef90d0f4b2654332037c4a7fd471b95215ec 100644 (file)
@@ -531,6 +531,7 @@ TESTS = \
        objects/bug620706.vala \
        objects/bug624594.vala \
        objects/bug626038.vala \
+       objects/bug626038-2.vala \
        objects/bug628639.vala \
        objects/bug629593.vala \
        objects/bug631267.vala \
diff --git a/tests/objects/bug626038-2.vala b/tests/objects/bug626038-2.vala
new file mode 100644 (file)
index 0000000..2a24228
--- /dev/null
@@ -0,0 +1,32 @@
+class Bar<K,V> {
+       public K k;
+       public V v;
+       public Bar (K k, V v) {
+               this.k = k;
+               this.v = v;
+       }
+}
+
+class Foo<G> {
+       public signal void bar (Bar<int,G> item);
+
+       public void fire (Bar<int,G> item) {
+               bar (item);
+       }
+}
+
+bool fired;
+
+void on_bar (Bar<int,string> item) {
+       assert (item.k == 42);
+       assert (item.v == "bar");
+       fired = true;
+}
+
+void main () {
+       Foo<string> foo = new Foo<string> ();
+       foo.bar.connect (on_bar);
+       var bar = new Bar<int,string> (42, "bar");
+       foo.fire (bar);
+       assert (fired);
+}
index 9fa6f7395af80742f48665f4656041af405d2d80..209a408210900bce013877cedb25966396d73c5d 100644 (file)
@@ -497,6 +497,38 @@ public abstract class Vala.DataType : CodeNode {
                return result;
        }
 
+       public bool is_generic () {
+               if (this is GenericType) {
+                       return true;
+               }
+
+               if (!has_type_arguments ()) {
+                       return false;
+               }
+               foreach (var type_arg in type_argument_list) {
+                       if (type_arg.is_generic ()) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       public void replace_type_parameter (TypeParameter old_type_param, TypeParameter new_type_param) {
+               if (this is GenericType) {
+                       unowned GenericType generic_type = (GenericType) this;
+                       if (generic_type.type_parameter == old_type_param) {
+                               generic_type.type_parameter = new_type_param;
+                       }
+                       return;
+               }
+               if (!has_type_arguments ()) {
+                       return;
+               }
+               foreach (var type_arg in type_argument_list) {
+                       type_arg.replace_type_parameter (old_type_param, new_type_param);
+               }
+       }
+
        /**
         * Search for the type parameter in this formal type and match it in
         * value_type.
index df7d761990b92e04b51232315a8fd84669ac50e9..d0303d4779062155ee60fb8fd70b50f319fe55ab 100644 (file)
@@ -122,7 +122,7 @@ public class Vala.Signal : Symbol, Callable {
                        actual_param.variable_type = actual_param.variable_type.get_actual_type (sender_type, null, node_reference);
                        generated_delegate.add_parameter (actual_param);
 
-                       if (actual_param.variable_type is GenericType) {
+                       if (actual_param.variable_type.is_generic ()) {
                                is_generic = true;
                        }
                }
@@ -136,9 +136,8 @@ public class Vala.Signal : Symbol, Callable {
                        // parameter types must refer to the delegate type parameters
                        // instead of to the class type parameters
                        foreach (var param in generated_delegate.get_parameters ()) {
-                               unowned GenericType? generic_type = param.variable_type as GenericType;
-                               if (generic_type != null) {
-                                       generic_type.type_parameter = generated_delegate.get_type_parameters ().get (generated_delegate.get_type_parameter_index (generic_type.type_parameter.name));
+                               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);
                                }
                        }
                }