From: Jürg Billeter Date: Sun, 2 Aug 2009 18:54:15 +0000 (+0200) Subject: Fix calling generic methods from generic types X-Git-Tag: 0.7.5~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=53132636a71fb7074843948eb424c2fe6e9bcdea;p=thirdparty%2Fvala.git Fix calling generic methods from generic types --- diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala index 4137a9412..515c4919f 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 335111979..0f0a0c220 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 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 (direct_hash, direct_equal); diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala index f9ff372e0..61d1ed811 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 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")); - } - } - } - } }