From: Jürg Billeter Date: Thu, 5 Apr 2007 09:03:37 +0000 (+0000) Subject: pass destroy function pointer when creating instances of generic types add X-Git-Tag: VALA_0_0_9~17 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=712760196f810694eee5f1e9ac7d6b77b0846c23;p=platform%2Fupstream%2Fvala.git pass destroy function pointer when creating instances of generic types add 2007-04-05 Jürg Billeter * vala/valacodegenerator.vala: pass destroy function pointer when creating instances of generic types * vala/valaclass.vala: add get_type_parameters method svn path=/trunk/; revision=279 --- diff --git a/vala/ChangeLog b/vala/ChangeLog index 738ec0c..c34cd0e 100644 --- a/vala/ChangeLog +++ b/vala/ChangeLog @@ -1,3 +1,9 @@ +2007-04-05 Jürg Billeter + + * vala/valacodegenerator.vala: pass destroy function pointer when + creating instances of generic types + * vala/valaclass.vala: add get_type_parameters method + 2007-04-04 Jürg Billeter * vala/scanner.l: improve cast support diff --git a/vala/vala/valaclass.vala b/vala/vala/valaclass.vala index aacf05e..4cbc1b9 100644 --- a/vala/vala/valaclass.vala +++ b/vala/vala/valaclass.vala @@ -123,7 +123,16 @@ public class Vala.Class : DataType { type_parameters.append (p); p.type = this; } - + + /** + * Returns a copy of the type parameter list. + * + * @return list of type parameters + */ + public List get_type_parameters () { + return type_parameters.copy (); + } + /** * Adds the specified constant as a member to this class. * diff --git a/vala/vala/valacodegenerator.vala b/vala/vala/valacodegenerator.vala index 0b94c3a..b1ecbb3 100644 --- a/vala/vala/valacodegenerator.vala +++ b/vala/vala/valacodegenerator.vala @@ -1300,7 +1300,15 @@ public class Vala.CodeGenerator : CodeVisitor { vdeclarator.add_parameter (instance_param); } } - + + if (m is CreationMethod && current_class != null) { + // memory management for generic types + foreach (TypeParameter type_param in current_class.get_type_parameters ()) { + var cparam = new CCodeFormalParameter ("%s_destroy_func".printf (type_param.name.down ()), "GDestroyNotify"); + function.add_parameter (cparam); + } + } + var params = m.get_parameters (); foreach (FormalParameter param in params) { if (!param.no_array_length && param.type_reference.data_type is Array) { @@ -2157,7 +2165,23 @@ public class Vala.CodeGenerator : CodeVisitor { return decl; } - + + private CCodeExpression get_destroy_func_expression (TypeReference! type) { + if (type.data_type != null) { + string unref_function; + if (type.data_type.is_reference_counting ()) { + unref_function = type.data_type.get_unref_function (); + } else { + unref_function = type.data_type.get_free_function (); + } + return new CCodeIdentifier (unref_function); + } else if (type.type_parameter != null) { + // TODO add support for type parameters + return new CCodeConstant ("NULL"); + } + Report.error (null, "internal error: destroy function requested for unknown type %s".printf (type.to_string ())); + } + private ref CCodeExpression get_unref_expression (CCodeExpression! cvar, TypeReference! type) { /* (foo == NULL ? NULL : foo = (unref (foo), NULL)) */ @@ -2168,43 +2192,40 @@ public class Vala.CodeGenerator : CodeVisitor { var cisnull = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, cvar, new CCodeConstant ("NULL")); - string unref_function; - if (type.data_type.is_reference_counting ()) { - unref_function = type.data_type.get_unref_function (); - } else { - unref_function = type.data_type.get_free_function (); - } - - var ccall = new CCodeFunctionCall (new CCodeIdentifier (unref_function)); + var ccall = new CCodeFunctionCall (get_destroy_func_expression (type)); ccall.add_argument (cvar); /* set freed references to NULL to prevent further use */ var ccomma = new CCodeCommaExpression (); - - if (unref_function == "g_list_free") { - bool is_ref = false; - bool is_class = false; - bool is_interface = false; - foreach (TypeReference type_arg in type.get_type_arguments ()) { - is_ref |= type_arg.takes_ownership; - is_class |= type_arg.data_type is Class; - is_interface |= type_arg.data_type is Interface; - } - - if (is_ref) { - var cunrefcall = new CCodeFunctionCall (new CCodeIdentifier ("g_list_foreach")); - cunrefcall.add_argument (cvar); - if (is_class || is_interface) { - cunrefcall.add_argument (new CCodeIdentifier ("(GFunc) g_object_unref")); - } else { - cunrefcall.add_argument (new CCodeIdentifier ("(GFunc) g_free")); + // TODO cleanup + if (type.data_type != null && !type.data_type.is_reference_counting ()) { + string unref_function = type.data_type.get_free_function (); + if (unref_function == "g_list_free") { + bool is_ref = false; + bool is_class = false; + bool is_interface = false; + + foreach (TypeReference type_arg in type.get_type_arguments ()) { + is_ref |= type_arg.takes_ownership; + is_class |= type_arg.data_type is Class; + is_interface |= type_arg.data_type is Interface; + } + + if (is_ref) { + var cunrefcall = new CCodeFunctionCall (new CCodeIdentifier ("g_list_foreach")); + cunrefcall.add_argument (cvar); + if (is_class || is_interface) { + cunrefcall.add_argument (new CCodeIdentifier ("(GFunc) g_object_unref")); + } else { + cunrefcall.add_argument (new CCodeIdentifier ("(GFunc) g_free")); + } + cunrefcall.add_argument (new CCodeConstant ("NULL")); + ccomma.append_expression (cunrefcall); } - cunrefcall.add_argument (new CCodeConstant ("NULL")); - ccomma.append_expression (cunrefcall); + } else if (unref_function == "g_string_free") { + ccall.add_argument (new CCodeConstant ("TRUE")); } - } else if (unref_function == "g_string_free") { - ccall.add_argument (new CCodeConstant ("TRUE")); } ccomma.append_expression (ccall); @@ -3529,6 +3550,16 @@ public class Vala.CodeGenerator : CodeVisitor { var ccall = new CCodeFunctionCall (new CCodeIdentifier (m.get_cname ())); + if (expr.type_reference.data_type is Class) { + foreach (TypeReference type_arg in expr.type_reference.get_type_arguments ()) { + if (type_arg.takes_ownership) { + ccall.add_argument (get_destroy_func_expression (type_arg)); + } else { + ccall.add_argument (new CCodeConstant ("NULL")); + } + } + } + bool ellipsis = false; int i = 1;