From: Jürg Billeter Date: Wed, 7 Jan 2009 20:27:57 +0000 (+0000) Subject: Add support for static destructors, patch by Sebastian Dröge, fixes bug X-Git-Tag: VALA_0_5_4~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef5df41724aa52c28d1a2c783bac0a0f81861014;p=thirdparty%2Fvala.git Add support for static destructors, patch by Sebastian Dröge, fixes bug 2009-01-07 Jürg Billeter * vala/valaclass.vala: * vala/valaparser.vala: * gobject/valaccodebasemodule.vala: * gobject/valaclassregisterfunction.vala: * gobject/valagobjectmodule.vala: * gobject/valainterfaceregisterfunction.vala: * gobject/valatyperegisterfunction.vala: Add support for static destructors, patch by Sebastian Dröge, fixes bug 564011 svn path=/trunk/; revision=2284 --- diff --git a/ChangeLog b/ChangeLog index b6f28a9eb..8defc67ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2009-01-07 Jürg Billeter + + * vala/valaclass.vala: + * vala/valaparser.vala: + * gobject/valaccodebasemodule.vala: + * gobject/valaclassregisterfunction.vala: + * gobject/valagobjectmodule.vala: + * gobject/valainterfaceregisterfunction.vala: + * gobject/valatyperegisterfunction.vala: + + Add support for static destructors, patch by Sebastian Dröge, + fixes bug 564011 + 2009-01-07 Jürg Billeter * vapi/taglib_c.vapi: diff --git a/gobject/valaccodebasemodule.vala b/gobject/valaccodebasemodule.vala index acdf90a25..fd8c5e25a 100644 --- a/gobject/valaccodebasemodule.vala +++ b/gobject/valaccodebasemodule.vala @@ -54,6 +54,7 @@ public class Vala.CCodeBaseModule : CCodeModule { public CCodeFragment source_type_member_definition; public CCodeFragment class_init_fragment; public CCodeFragment base_init_fragment; + public CCodeFragment class_finalize_fragment; public CCodeFragment base_finalize_fragment; public CCodeFragment instance_init_fragment; public CCodeFragment instance_finalize_fragment; @@ -1290,6 +1291,12 @@ public class Vala.CCodeBaseModule : CCodeModule { d.accept_children (codegen); + if (d.binding == MemberBinding.STATIC && !in_plugin) { + Report.error (d.source_reference, "static destructors are only supported for dynamic types"); + d.error = true; + return; + } + CCodeFragment cfrag = new CCodeFragment (); if (current_method_inner_error) { diff --git a/gobject/valaclassregisterfunction.vala b/gobject/valaclassregisterfunction.vala index 1de7f7bef..dd552ddb8 100644 --- a/gobject/valaclassregisterfunction.vala +++ b/gobject/valaclassregisterfunction.vala @@ -58,6 +58,14 @@ public class Vala.ClassRegisterFunction : TypeRegisterFunction { } } + public override string get_class_finalize_func_name () { + if (class_reference.static_destructor != null) { + return "%s_class_finalize".printf (class_reference.get_lower_case_cname (null)); + } else { + return "NULL"; + } + } + public override string get_base_finalize_func_name () { if (class_reference.class_destructor != null || class_reference.has_class_private_fields) { return "%s_base_finalize".printf (class_reference.get_lower_case_cname (null)); diff --git a/gobject/valagobjectmodule.vala b/gobject/valagobjectmodule.vala index c92dec8ad..8d3095a89 100644 --- a/gobject/valagobjectmodule.vala +++ b/gobject/valagobjectmodule.vala @@ -43,6 +43,7 @@ public class Vala.GObjectModule : GTypeModule { var old_prop_enum = prop_enum; var old_class_init_fragment = class_init_fragment; var old_base_init_fragment = base_init_fragment; + var old_class_finalize_fragment = class_finalize_fragment; var old_base_finalize_fragment = base_finalize_fragment; var old_instance_init_fragment = instance_init_fragment; var old_instance_finalize_fragment = instance_finalize_fragment; @@ -69,6 +70,7 @@ public class Vala.GObjectModule : GTypeModule { prop_enum.add_value (new CCodeEnumValue ("%s_DUMMY_PROPERTY".printf (cl.get_upper_case_cname (null)))); class_init_fragment = new CCodeFragment (); base_init_fragment = new CCodeFragment (); + class_finalize_fragment = new CCodeFragment (); base_finalize_fragment = new CCodeFragment (); instance_init_fragment = new CCodeFragment (); instance_finalize_fragment = new CCodeFragment (); @@ -215,6 +217,10 @@ public class Vala.GObjectModule : GTypeModule { add_base_finalize_function (cl); } + if (cl.static_destructor != null) { + add_class_finalize_function (cl); + } + foreach (DataType base_type in cl.get_base_types ()) { if (base_type.data_type is Interface) { add_interface_init_function (cl, (Interface) base_type.data_type); @@ -349,6 +355,7 @@ public class Vala.GObjectModule : GTypeModule { prop_enum = old_prop_enum; class_init_fragment = old_class_init_fragment; base_init_fragment = old_base_init_fragment; + class_finalize_fragment = old_class_finalize_fragment; base_finalize_fragment = old_base_finalize_fragment; instance_init_fragment = old_instance_init_fragment; instance_finalize_fragment = old_instance_finalize_fragment; @@ -1200,6 +1207,25 @@ public class Vala.GObjectModule : GTypeModule { source_type_member_definition.append (instance_init); } + private void add_class_finalize_function (Class cl) { + var function = new CCodeFunction ("%s_class_finalize".printf (cl.get_lower_case_cname (null)), "void"); + function.modifiers = CCodeModifiers.STATIC; + + function.add_parameter (new CCodeFormalParameter ("klass", cl.get_cname () + "Class *")); + source_type_member_declaration.append (function.copy ()); + + var cblock = new CCodeBlock (); + + if (cl.class_destructor != null) { + cblock.add_statement (cl.class_destructor.ccodenode); + } + + cblock.add_statement (class_finalize_fragment); + + function.block = cblock; + source_type_member_definition.append (function); + } + private void add_base_finalize_function (Class cl) { var function = new CCodeFunction ("%s_base_finalize".printf (cl.get_lower_case_cname (null)), "void"); function.modifiers = CCodeModifiers.STATIC; diff --git a/gobject/valainterfaceregisterfunction.vala b/gobject/valainterfaceregisterfunction.vala index 306aa3d8c..a3dd1a25b 100644 --- a/gobject/valainterfaceregisterfunction.vala +++ b/gobject/valainterfaceregisterfunction.vala @@ -48,7 +48,11 @@ public class Vala.InterfaceRegisterFunction : TypeRegisterFunction { public override string get_base_init_func_name () { return "%s_base_init".printf (interface_reference.get_lower_case_cname (null)); } - + + public override string get_class_finalize_func_name () { + return "NULL"; + } + public override string get_base_finalize_func_name () { return "NULL"; } diff --git a/gobject/valatyperegisterfunction.vala b/gobject/valatyperegisterfunction.vala index e2260232b..7fe6412b1 100644 --- a/gobject/valatyperegisterfunction.vala +++ b/gobject/valatyperegisterfunction.vala @@ -108,7 +108,7 @@ public abstract class Vala.TypeRegisterFunction { if (get_type_declaration () is ObjectTypeSymbol) { var ctypedecl = new CCodeDeclaration ("const GTypeInfo"); ctypedecl.modifiers = CCodeModifiers.STATIC; - ctypedecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_info", new CCodeConstant ("{ sizeof (%s), (GBaseInitFunc) %s, (GBaseFinalizeFunc) %s, (GClassInitFunc) %s, (GClassFinalizeFunc) NULL, NULL, %s, 0, (GInstanceInitFunc) %s, %s }".printf (get_type_struct_name (), get_base_init_func_name (), get_base_finalize_func_name (), get_class_init_func_name (), get_instance_struct_size (), get_instance_init_func_name (), type_value_table_decl_name)))); + ctypedecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("g_define_type_info", new CCodeConstant ("{ sizeof (%s), (GBaseInitFunc) %s, (GBaseFinalizeFunc) %s, (GClassInitFunc) %s, (GClassFinalizeFunc) %s, NULL, %s, 0, (GInstanceInitFunc) %s, %s }".printf (get_type_struct_name (), get_base_init_func_name (), (plugin) ? get_base_finalize_func_name () : "NULL", get_class_init_func_name (), get_class_finalize_func_name (), get_instance_struct_size (), get_instance_init_func_name (), type_value_table_decl_name)))); type_init.add_statement (ctypedecl); if (fundamental) { var ctypefundamentaldecl = new CCodeDeclaration ("const GTypeFundamentalInfo"); @@ -231,6 +231,15 @@ public abstract class Vala.TypeRegisterFunction { assert_not_reached (); } + /** + * Returns the name of the class_finalize function in C code. + * + * @return C function name + */ + public virtual string get_class_finalize_func_name () { + assert_not_reached (); + } + /** * Returns the name of the base_finalize function in C code. * diff --git a/vala/valaclass.vala b/vala/valaclass.vala index a1b749699..c5ea9ea66 100644 --- a/vala/valaclass.vala +++ b/vala/valaclass.vala @@ -196,11 +196,16 @@ public class Vala.Class : ObjectTypeSymbol { } } } + + /** + * Specifies the class destructor. + */ + public Destructor? static_destructor { get; set; } /** * Specifies the class destructor. */ - public Destructor class_destructor { get; set; } + public Destructor? class_destructor { get; set; } /** * Specifies whether this class denotes an error base. @@ -474,6 +479,10 @@ public class Vala.Class : ObjectTypeSymbol { destructor.accept (visitor); } + if (static_destructor != null) { + static_destructor.accept (visitor); + } + if (class_destructor != null) { class_destructor.accept (visitor); } @@ -930,6 +939,10 @@ public class Vala.Class : ObjectTypeSymbol { if (destructor != null) { destructor.check (analyzer); } + + if (static_destructor != null) { + static_destructor.check (analyzer); + } if (class_destructor != null) { class_destructor.check (analyzer); diff --git a/vala/valaparser.vala b/vala/valaparser.vala index 73d52cbc1..13caccc5a 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -2018,7 +2018,7 @@ public class Vala.Parser : CodeVisitor { } else if (sym is Destructor) { var d = (Destructor) sym; if (d.binding == MemberBinding.STATIC) { - Report.error (sym.source_reference, "static destructors not supported yet"); + cl.static_destructor = (Destructor) d; } else if (d.binding == MemberBinding.CLASS) { cl.class_destructor = (Destructor) d; } else {