[vala] Add limited support for derived compact classes



commit fea12020d4f6086fea271f0f1a7832d96fd86169
Author: Jürg Billeter <j bitron ch>
Date:   Tue Jul 28 18:50:25 2009 +0200

    Add limited support for derived compact classes
    
    Fixes bug 578603.

 codegen/valaccodemethodcallmodule.vala |    4 +-
 codegen/valaccodemethodmodule.vala     |   25 ++++++++----
 codegen/valagtypemodule.vala           |   64 +++++++++++++++++++-------------
 vala/valaclass.vala                    |   12 ++++++
 4 files changed, 70 insertions(+), 35 deletions(-)
---
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 4cf641d..cd06e37 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 d8342a6..ac71cae 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 81573a6..18c44fd 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 51efba3..d2bb81c 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 */



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