From 724c3c5ecaeaddd54c0f8d5fb744bfeb680fc5e8 Mon Sep 17 00:00:00 2001 From: Rico Tzschichholz Date: Wed, 10 Mar 2021 12:12:06 +0100 Subject: vala: Replace all type parameter occurances in parameters for signal delegate Improves 36999b5ffd63cc56a8648791b02bf07e7da88077 --- tests/Makefile.am | 1 + tests/objects/bug626038-2.vala | 32 ++++++++++++++++++++++++++++++++ vala/valadatatype.vala | 32 ++++++++++++++++++++++++++++++++ vala/valasignal.vala | 7 +++---- 4 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 tests/objects/bug626038-2.vala diff --git a/tests/Makefile.am b/tests/Makefile.am index 6e7bd28b8..3373316ed 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -539,6 +539,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 index 000000000..2a2422846 --- /dev/null +++ b/tests/objects/bug626038-2.vala @@ -0,0 +1,32 @@ +class Bar { + public K k; + public V v; + public Bar (K k, V v) { + this.k = k; + this.v = v; + } +} + +class Foo { + public signal void bar (Bar item); + + public void fire (Bar item) { + bar (item); + } +} + +bool fired; + +void on_bar (Bar item) { + assert (item.k == 42); + assert (item.v == "bar"); + fired = true; +} + +void main () { + Foo foo = new Foo (); + foo.bar.connect (on_bar); + var bar = new Bar (42, "bar"); + foo.fire (bar); + assert (fired); +} diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala index 59be21bd7..8ad4cc0cc 100644 --- a/vala/valadatatype.vala +++ b/vala/valadatatype.vala @@ -506,6 +506,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. diff --git a/vala/valasignal.vala b/vala/valasignal.vala index 3acbf3b03..5c790a7cd 100644 --- a/vala/valasignal.vala +++ b/vala/valasignal.vala @@ -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); } } } -- cgit v1.2.1