[vala] Fix signals with generic parameters



commit 36999b5ffd63cc56a8648791b02bf07e7da88077
Author: Jürg Billeter <j bitron ch>
Date:   Tue Feb 8 22:08:03 2011 +0100

    Fix signals with generic parameters
    
    Fixes bug 628639.

 tests/Makefile.am            |    1 +
 tests/objects/bug628639.vala |   21 +++++++++++++++++++++
 vala/valamethodcall.vala     |   10 +++++++++-
 vala/valasignal.vala         |   23 ++++++++++++++++++++++-
 vala/valasignaltype.vala     |   15 +++++++++++++--
 5 files changed, 66 insertions(+), 4 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 63d0c9d..411f348 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -72,6 +72,7 @@ TESTS = \
 	objects/bug613486.vala \
 	objects/bug620706.vala \
 	objects/bug624594.vala \
+	objects/bug628639.vala \
 	errors/errors.vala \
 	errors/bug567181.vala \
 	errors/bug579101.vala \
diff --git a/tests/objects/bug628639.vala b/tests/objects/bug628639.vala
new file mode 100644
index 0000000..3850958
--- /dev/null
+++ b/tests/objects/bug628639.vala
@@ -0,0 +1,21 @@
+class Foo<G> {
+	public signal void bar (G item);
+
+	public void fire (G item) {
+		bar (item);
+	}
+}
+
+bool fired;
+
+void on_bar (int item) {
+	assert (item == 42);
+	fired = true;
+}
+
+void main() {
+	Foo<int> foo = new Foo<int> ();
+	foo.bar.connect (on_bar);
+	foo.fire (42);
+	assert (fired);
+}
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index ea3c556..73c8171 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -1,6 +1,6 @@
 /* valamethodcall.vala
  *
- * Copyright (C) 2006-2010  Jürg Billeter
+ * Copyright (C) 2006-2011  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -157,6 +157,14 @@ public class Vala.MethodCall : Expression {
 
 			if (ma.inner != null) {
 				target_object_type = ma.inner.value_type;
+
+				// foo is relevant instance in foo.bar.connect (on_bar)
+				if (ma.inner.symbol_reference is Signal) {
+					var sig = ma.inner as MemberAccess;
+					if (sig != null) {
+						target_object_type = sig.inner.value_type;
+					}
+				}
 			}
 
 			if (ma.symbol_reference != null && ma.symbol_reference.get_attribute ("Assert") != null) {
diff --git a/vala/valasignal.vala b/vala/valasignal.vala
index a2ed64a..3c81870 100644
--- a/vala/valasignal.vala
+++ b/vala/valasignal.vala
@@ -1,6 +1,6 @@
 /* valasignal.vala
  *
- * Copyright (C) 2006-2010  Jürg Billeter
+ * Copyright (C) 2006-2011  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -137,10 +137,31 @@ public class Vala.Signal : Symbol, Lockable {
 
 		generated_delegate.sender_type = sender_param_type;
 
+		bool is_generic = false;
+
 		foreach (Parameter param in parameters) {
 			var actual_param = param.copy ();
 			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) {
+				is_generic = true;
+			}
+		}
+
+		if (is_generic) {
+			var cl = (ObjectTypeSymbol) parent_symbol;
+			foreach (var type_param in cl.get_type_parameters ()) {
+				generated_delegate.add_type_parameter (new TypeParameter (type_param.name, type_param.source_reference));
+			}
+
+			// parameter types must refer to the delegate type parameters
+			// instead of to the class type parameters
+			foreach (var param in generated_delegate.get_parameters ()) {
+				if (param.variable_type is GenericType) {
+					param.variable_type.type_parameter = generated_delegate.get_type_parameters ().get (generated_delegate.get_type_parameter_index (param.variable_type.type_parameter.name));
+				}
+			}
 		}
 
 		scope.add (null, generated_delegate);
diff --git a/vala/valasignaltype.vala b/vala/valasignaltype.vala
index 6cdab02..6c6ddf5 100644
--- a/vala/valasignaltype.vala
+++ b/vala/valasignaltype.vala
@@ -1,6 +1,6 @@
 /* valasignaltype.vala
  *
- * Copyright (C) 2007-2009  Jürg Billeter
+ * Copyright (C) 2007-2011  Jürg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -61,9 +61,20 @@ public class Vala.SignalType : DataType {
 	}
 
 	DelegateType get_handler_type () {
-		var sender_type = new ObjectType ((ObjectTypeSymbol) signal_symbol.parent_symbol);
+		var type_sym = (ObjectTypeSymbol) signal_symbol.parent_symbol;
+
+		var sender_type = new ObjectType (type_sym);
 		var result = new DelegateType (signal_symbol.get_delegate (sender_type, this));
 		result.value_owned = true;
+
+		if (result.delegate_symbol.get_type_parameters ().size > 0) {
+			foreach (var type_param in type_sym.get_type_parameters ()) {
+				var type_arg = new GenericType (type_param);
+				type_arg.value_owned = true;
+				result.add_type_argument (type_arg);
+			}
+		}
+
 		return result;
 	}
 



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