[vala] Fix calling generic methods from generic types



commit 53132636a71fb7074843948eb424c2fe6e9bcdea
Author: Jürg Billeter <j bitron ch>
Date:   Sun Aug 2 20:54:15 2009 +0200

    Fix calling generic methods from generic types

 codegen/valaccodearraymodule.vala      |    4 +-
 codegen/valaccodebasemodule.vala       |   48 +++++++++++++++++--------------
 codegen/valaccodemethodcallmodule.vala |   29 +------------------
 3 files changed, 29 insertions(+), 52 deletions(-)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index 4137a94..515c491 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -613,7 +613,7 @@ internal class Vala.CCodeArrayModule : CCodeMethodCallModule {
 		}
 	}
 
-	public override CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference) {
+	public override CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference, bool is_chainup) {
 		if (type is ArrayType) {
 			var array_type = (ArrayType) type;
 			// fixed length arrays use different code
@@ -621,7 +621,7 @@ internal class Vala.CCodeArrayModule : CCodeMethodCallModule {
 			assert (!array_type.fixed_length);
 			return new CCodeIdentifier (generate_array_dup_wrapper (array_type));
 		} else {
-			return base.get_dup_func_expression (type, source_reference);
+			return base.get_dup_func_expression (type, source_reference, is_chainup);
 		}
 	}
 
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 3351119..0f0a0c2 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1828,10 +1828,10 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 		}
 	}
 
-	private CCodeExpression get_type_id_expression (DataType type) {
+	private CCodeExpression get_type_id_expression (DataType type, bool is_chainup = false) {
 		if (type is GenericType) {
 			string var_name = "%s_type".printf (type.type_parameter.name.down ());
-			if (is_in_generic_type (type)) {
+			if (is_in_generic_type (type) && !is_chainup) {
 				return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), var_name);
 			} else {
 				return new CCodeIdentifier (var_name);
@@ -1847,7 +1847,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 		}
 	}
 
-	public virtual CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference) {
+	public virtual CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference, bool is_chainup = false) {
 		if (type is ErrorType) {
 			return new CCodeIdentifier ("g_error_copy");
 		} else if (type.data_type != null) {
@@ -1881,7 +1881,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 			return new CCodeIdentifier (dup_function);
 		} else if (type.type_parameter != null && current_type_symbol is Class) {
 			string func_name = "%s_dup_func".printf (type.type_parameter.name.down ());
-			if (is_in_generic_type (type)) {
+			if (is_in_generic_type (type) && !is_chainup) {
 				return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
 			} else {
 				return new CCodeIdentifier (func_name);
@@ -1993,7 +1993,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 		return destroy_func;
 	}
 
-	public CCodeExpression? get_destroy_func_expression (DataType type) {
+	public CCodeExpression? get_destroy_func_expression (DataType type, bool is_chainup = false) {
 		if (context.profile == Profile.GOBJECT && (type.data_type == glist_type || type.data_type == gslist_type)) {
 			// create wrapper function to free list elements if necessary
 
@@ -2048,7 +2048,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 			return new CCodeIdentifier (unref_function);
 		} else if (type.type_parameter != null && current_type_symbol is Class) {
 			string func_name = "%s_destroy_func".printf (type.type_parameter.name.down ());
-			if (is_in_generic_type (type)) {
+			if (is_in_generic_type (type) && !is_chainup) {
 				return new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), "priv"), func_name);
 			} else {
 				return new CCodeIdentifier (func_name);
@@ -3062,6 +3062,25 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 	public virtual void generate_error_domain_declaration (ErrorDomain edomain, CCodeDeclarationSpace decl_space) {
 	}
 
+	public void add_generic_type_arguments (CCodeFunctionCall ccall, Gee.List<DataType> type_args, CodeNode expr, bool is_chainup = false) {
+		foreach (var type_arg in type_args) {
+			ccall.add_argument (get_type_id_expression (type_arg, is_chainup));
+			if (requires_copy (type_arg)) {
+				var dup_func = get_dup_func_expression (type_arg, type_arg.source_reference, is_chainup);
+				if (dup_func == null) {
+					// type doesn't contain a copy function
+					expr.error = true;
+					return;
+				}
+				ccall.add_argument (new CCodeCastExpression (dup_func, "GBoxedCopyFunc"));
+				ccall.add_argument (get_destroy_func_expression (type_arg, is_chainup));
+			} else {
+				ccall.add_argument (new CCodeConstant ("NULL"));
+				ccall.add_argument (new CCodeConstant ("NULL"));
+			}
+		}
+	}
+
 	public override void visit_object_creation_expression (ObjectCreationExpression expr) {
 		expr.accept_children (codegen);
 
@@ -3125,22 +3144,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 
 			var cl = expr.type_reference.data_type as Class;
 			if (cl != null && !cl.is_compact) {
-				foreach (DataType type_arg in expr.type_reference.get_type_arguments ()) {
-					creation_call.add_argument (get_type_id_expression (type_arg));
-					if (requires_copy (type_arg)) {
-						var dup_func = get_dup_func_expression (type_arg, type_arg.source_reference);
-						if (dup_func == null) {
-							// type doesn't contain a copy function
-							expr.error = true;
-							return;
-						}
-						creation_call.add_argument (new CCodeCastExpression (dup_func, "GBoxedCopyFunc"));
-						creation_call.add_argument (get_destroy_func_expression (type_arg));
-					} else {
-						creation_call.add_argument (new CCodeConstant ("NULL"));
-						creation_call.add_argument (new CCodeConstant ("NULL"));
-					}
-				}
+				add_generic_type_arguments (creation_call, expr.type_reference.get_type_arguments (), expr);
 			}
 
 			var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index f9ff372..61d1ed8 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -104,7 +104,7 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 
 			foreach (DataType base_type in current_class.get_base_types ()) {
 				if (base_type.data_type is Class) {
-					add_generic_type_arguments (ccall, base_type.get_type_arguments (), expr);
+					add_generic_type_arguments (ccall, base_type.get_type_arguments (), expr, true);
 					break;
 				}
 			}
@@ -685,32 +685,5 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 			expr.ccodenode = ccomma;
 		}
 	}
-
-	void add_generic_type_arguments (CCodeFunctionCall ccall, Gee.List<DataType> type_args, CodeNode expr) {
-		foreach (var type_arg in type_args) {
-			if (type_arg is GenericType) {
-				// map generic type parameter
-				string type_param = type_arg.type_parameter.name.down ();
-				ccall.add_argument (new CCodeIdentifier ("%s_type".printf (type_param)));
-				ccall.add_argument (new CCodeIdentifier ("%s_dup_func".printf (type_param)));
-				ccall.add_argument (new CCodeIdentifier ("%s_destroy_func".printf (type_param)));
-			} else {
-				ccall.add_argument (new CCodeIdentifier (type_arg.get_type_id ()));
-				if (requires_copy (type_arg)) {
-					var dup_func = get_dup_func_expression (type_arg, type_arg.source_reference);
-					if (dup_func == null) {
-						// type doesn't contain a copy function
-						expr.error = true;
-						return;
-					}
-					ccall.add_argument (new CCodeCastExpression (dup_func, "GBoxedCopyFunc"));
-					ccall.add_argument (get_destroy_func_expression (type_arg));
-				} else {
-					ccall.add_argument (new CCodeConstant ("NULL"));
-					ccall.add_argument (new CCodeConstant ("NULL"));
-				}
-			}
-		}
-	}
 }
 



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