From: Jürg Billeter Date: Tue, 28 Jul 2009 16:50:25 +0000 (+0200) Subject: Add limited support for derived compact classes X-Git-Tag: 0.7.5~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fea12020d4f6086fea271f0f1a7832d96fd86169;p=thirdparty%2Fvala.git Add limited support for derived compact classes Fixes bug 578603. --- diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala index 4cf641d4e..cd06e3744 100644 --- a/codegen/valaccodemethodcallmodule.vala +++ b/codegen/valaccodemethodcallmodule.vala @@ -95,7 +95,9 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule { if (m is CreationMethod) { if (context.profile == Profile.GOBJECT) { - ccall.add_argument (new CCodeIdentifier ("object_type")); + if (!((Class) m.parent_symbol).is_compact) { + ccall.add_argument (new CCodeIdentifier ("object_type")); + } } else { ccall.add_argument (new CCodeIdentifier ("self")); } diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index d8342a6f1..ac71cae3b 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -530,15 +530,24 @@ internal class Vala.CCodeMethodModule : CCodeStructModule { } } else if (current_type_symbol is Class) { var cl = (Class) m.parent_symbol; - var cdecl = new CCodeDeclaration (cl.get_cname () + "*"); - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0")); - ccall.add_argument (new CCodeIdentifier (cl.get_cname ())); - cdecl.add_declarator (new CCodeVariableDeclarator ("self", ccall)); - cinit.append (cdecl); + var cdeclaration = new CCodeDeclaration (cl.get_cname () + "*"); + var cdecl = new CCodeVariableDeclarator ("self"); + cdeclaration.add_declarator (cdecl); + cinit.append (cdeclaration); - var cinitcall = new CCodeFunctionCall (new CCodeIdentifier ("%s_instance_init".printf (cl.get_lower_case_cname (null)))); - cinitcall.add_argument (new CCodeIdentifier ("self")); - cinit.append (new CCodeExpressionStatement (cinitcall)); + if (!((CreationMethod) m).chain_up) { + // TODO implicitly chain up to base class as in add_object_creation + var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0")); + ccall.add_argument (new CCodeIdentifier (cl.get_cname ())); + cdecl.initializer = ccall; + } + + if (cl.base_class == null) { + // derived compact classes do not have fields + var cinitcall = new CCodeFunctionCall (new CCodeIdentifier ("%s_instance_init".printf (cl.get_lower_case_cname (null)))); + cinitcall.add_argument (new CCodeIdentifier ("self")); + cinit.append (new CCodeExpressionStatement (cinitcall)); + } } else { var st = (Struct) m.parent_symbol; diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index 81573a690..18c44fd77 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -87,7 +87,11 @@ internal class Vala.GTypeModule : GErrorModule { decl_space.add_type_declaration (new CCodeNewline ()); } - decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (cl.get_cname ()), new CCodeVariableDeclarator (cl.get_cname ()))); + if (cl.is_compact && cl.base_class != null) { + decl_space.add_type_declaration (new CCodeTypeDefinition (cl.base_class.get_cname (), new CCodeVariableDeclarator (cl.get_cname ()))); + } else { + decl_space.add_type_declaration (new CCodeTypeDefinition ("struct _%s".printf (cl.get_cname ()), new CCodeVariableDeclarator (cl.get_cname ()))); + } if (is_fundamental) { var ref_fun = new CCodeFunction (cl.get_lower_case_cprefix () + "ref", "gpointer"); @@ -310,7 +314,10 @@ internal class Vala.GTypeModule : GErrorModule { if (cl.source_reference.comment != null) { decl_space.add_type_definition (new CCodeComment (cl.source_reference.comment)); } - decl_space.add_type_definition (instance_struct); + if (!cl.is_compact || cl.base_class == null) { + // derived compact classes do not have a struct + decl_space.add_type_definition (instance_struct); + } if (is_gtypeinstance) { decl_space.add_type_definition (type_struct); @@ -435,18 +442,20 @@ internal class Vala.GTypeModule : GErrorModule { } decl_space.add_type_member_declaration (prop_enum); } else { - var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void"); - if (cl.access == SymbolAccessibility.PRIVATE) { - function.modifiers = CCodeModifiers.STATIC; - } - if (cl.has_private_fields) { Report.error (cl.source_reference, "Private fields not supported in compact classes"); } - function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*")); + if (cl.base_class == null) { + var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void"); + if (cl.access == SymbolAccessibility.PRIVATE) { + function.modifiers = CCodeModifiers.STATIC; + } + + function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*")); - decl_space.add_type_member_declaration (function); + decl_space.add_type_member_declaration (function); + } } } @@ -612,31 +621,34 @@ internal class Vala.GTypeModule : GErrorModule { source_type_member_definition.append (unref_fun); } } else { - add_instance_init_function (cl); + if (cl.base_class == null) { + // derived compact classes do not have fields + add_instance_init_function (cl); - var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void"); - if (cl.access == SymbolAccessibility.PRIVATE) { - function.modifiers = CCodeModifiers.STATIC; - } + var function = new CCodeFunction (cl.get_lower_case_cprefix () + "free", "void"); + if (cl.access == SymbolAccessibility.PRIVATE) { + function.modifiers = CCodeModifiers.STATIC; + } - function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*")); + function.add_parameter (new CCodeFormalParameter ("self", cl.get_cname () + "*")); - var cblock = new CCodeBlock (); + var cblock = new CCodeBlock (); - cblock.add_statement (instance_finalize_fragment); + cblock.add_statement (instance_finalize_fragment); - if (cl.destructor != null) { - cblock.add_statement (cl.destructor.ccodenode); - } + if (cl.destructor != null) { + cblock.add_statement (cl.destructor.ccodenode); + } - var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free")); - ccall.add_argument (new CCodeIdentifier (cl.get_cname ())); - ccall.add_argument (new CCodeIdentifier ("self")); - cblock.add_statement (new CCodeExpressionStatement (ccall)); + var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free")); + ccall.add_argument (new CCodeIdentifier (cl.get_cname ())); + ccall.add_argument (new CCodeIdentifier ("self")); + cblock.add_statement (new CCodeExpressionStatement (ccall)); - function.block = cblock; + function.block = cblock; - source_type_member_definition.append (function); + source_type_member_definition.append (function); + } } current_symbol = old_symbol; diff --git a/vala/valaclass.vala b/vala/valaclass.vala index 51efba31b..d2bb81c84 100644 --- a/vala/valaclass.vala +++ b/vala/valaclass.vala @@ -825,6 +825,9 @@ public class Vala.Class : ObjectTypeSymbol { public override string? get_free_function () { if (free_function == null) { + if (base_class != null) { + return base_class.get_free_function (); + } free_function = get_default_free_function (); } return free_function; @@ -1007,6 +1010,15 @@ public class Vala.Class : ObjectTypeSymbol { Report.error (source_reference, "compact classes `%s` may not implement interfaces".printf (get_full_name ())); } } + + if (base_class != null) { + foreach (Field f in fields) { + if (f.binding == MemberBinding.INSTANCE) { + error = true; + Report.error (source_reference, "derived compact classes may not have instance fields"); + } + } + } } /* gather all prerequisites */