vala r2187 - in trunk: . gobject vala



Author: juergbi
Date: Tue Dec 16 21:14:45 2008
New Revision: 2187
URL: http://svn.gnome.org/viewvc/vala?rev=2187&view=rev

Log:
2008-12-16  JÃrg Billeter  <j bitron ch>

	* vala/valaclass.vala:
	* gobject/valaccodebasemodule.vala:
	* gobject/valaccodememberaccessmodule.vala:
	* gobject/valaclassregisterfunction.vala:
	* gobject/valagobjectmodule.vala:
	* gobject/valainterfaceregisterfunction.vala:
	* gobject/valatyperegisterfunction.vala:

	Add support for private class fields, patch by Sebastian DrÃge,
	fixes bug 561469


Modified:
   trunk/ChangeLog
   trunk/gobject/valaccodebasemodule.vala
   trunk/gobject/valaccodememberaccessmodule.vala
   trunk/gobject/valaclassregisterfunction.vala
   trunk/gobject/valagobjectmodule.vala
   trunk/gobject/valainterfaceregisterfunction.vala
   trunk/gobject/valatyperegisterfunction.vala
   trunk/vala/valaclass.vala

Modified: trunk/gobject/valaccodebasemodule.vala
==============================================================================
--- trunk/gobject/valaccodebasemodule.vala	(original)
+++ trunk/gobject/valaccodebasemodule.vala	Tue Dec 16 21:14:45 2008
@@ -52,6 +52,8 @@
 	public CCodeFragment source_signal_marshaller_declaration;
 	public CCodeFragment source_type_member_definition;
 	public CCodeFragment class_init_fragment;
+	public CCodeFragment base_init_fragment;
+	public CCodeFragment base_finalize_fragment;
 	public CCodeFragment instance_init_fragment;
 	public CCodeFragment instance_finalize_fragment;
 	public CCodeFragment source_signal_marshaller_definition;
@@ -61,6 +63,7 @@
 	public CCodeStruct instance_struct;
 	public CCodeStruct type_struct;
 	public CCodeStruct instance_priv_struct;
+	public CCodeStruct type_priv_struct;
 	public CCodeEnum prop_enum;
 	public CCodeEnum cenum;
 	public CCodeFunction function;
@@ -837,7 +840,8 @@
 					lhs = new CCodeMemberAccess.pointer (new CCodeIdentifier ("self"), f.get_cname ());
 				}
 			} else if (f.binding == MemberBinding.CLASS) {
-				st = type_struct;
+				st = type_priv_struct;
+				lhs = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"), f.get_cname ());
 			} else {
 				var cdecl = new CCodeDeclaration (field_ctype);
 				var var_decl = new CCodeVariableDeclarator (f.get_cname ());

Modified: trunk/gobject/valaccodememberaccessmodule.vala
==============================================================================
--- trunk/gobject/valaccodememberaccessmodule.vala	(original)
+++ trunk/gobject/valaccodememberaccessmodule.vala	Tue Dec 16 21:14:45 2008
@@ -129,7 +129,13 @@
 					klass = k;
 				}
 				cast.add_argument (klass);
-				expr.ccodenode = new CCodeMemberAccess.pointer (cast, f.get_cname ());
+
+				if (f.access == SymbolAccessibility.PRIVATE) {
+					expr.ccodenode = new CCodeMemberAccess.pointer (new CCodeMemberAccess.pointer (cast, "priv"), f.get_cname ());
+				} else {
+					expr.ccodenode = new CCodeMemberAccess.pointer (cast, f.get_cname ());
+				}
+
 			} else {
 				expr.ccodenode = new CCodeIdentifier (f.get_cname ());
 			}

Modified: trunk/gobject/valaclassregisterfunction.vala
==============================================================================
--- trunk/gobject/valaclassregisterfunction.vala	(original)
+++ trunk/gobject/valaclassregisterfunction.vala	Tue Dec 16 21:14:45 2008
@@ -51,13 +51,21 @@
 	}
 
 	public override string get_base_init_func_name () {
-		if (class_reference.class_constructor != null) {
+		if (class_reference.class_constructor != null || class_reference.has_class_private_fields) {
 			return "%s_base_init".printf (class_reference.get_lower_case_cname (null));
 		} else {
 			return "NULL";
 		}
 	}
 
+	public override string get_base_finalize_func_name () {
+		if (class_reference.has_class_private_fields) {
+			return "%s_base_finalize".printf (class_reference.get_lower_case_cname (null));
+		} else {
+			return "NULL";
+		}
+	}
+
 	public override string get_class_init_func_name () {
 		return "%s_class_init".printf (class_reference.get_lower_case_cname (null));
 	}

Modified: trunk/gobject/valagobjectmodule.vala
==============================================================================
--- trunk/gobject/valagobjectmodule.vala	(original)
+++ trunk/gobject/valagobjectmodule.vala	Tue Dec 16 21:14:45 2008
@@ -39,8 +39,11 @@
 		var old_param_spec_struct = param_spec_struct;
 		var old_type_struct = type_struct;
 		var old_instance_priv_struct = instance_priv_struct;
+		var old_type_priv_struct = type_priv_struct;
 		var old_prop_enum = prop_enum;
 		var old_class_init_fragment = class_init_fragment;
+		var old_base_init_fragment = base_init_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;
 		current_symbol = cl;
@@ -61,9 +64,12 @@
 		instance_struct = new CCodeStruct ("_%s".printf (cl.get_cname ()));
 		type_struct = new CCodeStruct ("_%sClass".printf (cl.get_cname ()));
 		instance_priv_struct = new CCodeStruct ("_%sPrivate".printf (cl.get_cname ()));
+		type_priv_struct = new CCodeStruct ("_%sClassPrivate".printf (cl.get_cname ()));
 		prop_enum = new CCodeEnum ();
 		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 ();
+		base_finalize_fragment = new CCodeFragment ();
 		instance_init_fragment = new CCodeFragment ();
 		instance_finalize_fragment = new CCodeFragment ();
 
@@ -122,14 +128,23 @@
 				decl_frag.append (new CCodeTypeDefinition ("struct %s".printf (type_struct.name), new CCodeVariableDeclarator ("%sClass".printf (cl.get_cname ()))));
 			}
 			decl_frag.append (new CCodeTypeDefinition ("struct %s".printf (instance_priv_struct.name), new CCodeVariableDeclarator ("%sPrivate".printf (cl.get_cname ()))));
+			if (cl.has_class_private_fields) {
+				decl_frag.append (new CCodeTypeDefinition ("struct %s".printf (type_priv_struct.name), new CCodeVariableDeclarator ("%sClassPrivate".printf (cl.get_cname ()))));
+			}
 
 			instance_struct.add_field ("%sPrivate *".printf (cl.get_cname ()), "priv");
 			if (is_fundamental) {
 				type_struct.add_field ("GTypeClass", "parent_class");
-				type_struct.add_field ("void", "(*finalize) (%s *self)".printf (cl.get_cname ()));
 			} else {
 				type_struct.add_field ("%sClass".printf (cl.base_class.get_cname ()), "parent_class");
 			}
+			if (cl.has_class_private_fields) {
+				type_struct.add_field ("%sClassPrivate *".printf (cl.get_cname ()), "priv");
+			}
+
+			if (is_fundamental) {
+				type_struct.add_field ("void", "(*finalize) (%s *self)".printf (cl.get_cname ()));
+			}
 		}
 
 		if (cl.source_reference.comment != null) {
@@ -145,6 +160,10 @@
 				var macro = "(G_TYPE_INSTANCE_GET_PRIVATE ((o), %s, %sPrivate))".printf (cl.get_type_id (), cl.get_cname ());
 				source_type_member_declaration.append (new CCodeMacroReplacement ("%s_GET_PRIVATE(o)".printf (cl.get_upper_case_cname (null)), macro));
 			}
+
+			if (cl.has_class_private_fields) {
+				source_type_member_declaration.append (type_priv_struct);
+			}
 			source_type_member_declaration.append (prop_enum);
 		}
 
@@ -181,8 +200,17 @@
 					add_set_property_function (cl);
 				}
 			}
+
+
+			if (cl.class_constructor != null || cl.has_class_private_fields) {
+				add_base_init_function (cl);
+			}
 			add_class_init_function (cl);
-			
+
+			if (cl.has_class_private_fields) {
+				add_base_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);
@@ -313,8 +341,11 @@
 		param_spec_struct = old_param_spec_struct;
 		type_struct = old_type_struct;
 		instance_priv_struct = old_instance_priv_struct;
+		type_priv_struct = old_type_priv_struct;
 		prop_enum = old_prop_enum;
 		class_init_fragment = old_class_init_fragment;
+		base_init_fragment = old_base_init_fragment;
+		base_finalize_fragment = old_base_finalize_fragment;
 		instance_init_fragment = old_instance_init_fragment;
 		instance_finalize_fragment = old_instance_finalize_fragment;
 	}
@@ -682,6 +713,53 @@
 		source_type_member_definition.append (function);
 	}
 
+	private void add_base_init_function (Class cl) {
+		var base_init = new CCodeFunction ("%s_base_init".printf (cl.get_lower_case_cname (null)), "void");
+		base_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
+		base_init.modifiers = CCodeModifiers.STATIC;
+
+		var init_block = new CCodeBlock ();
+		base_init.block = init_block;
+
+		if (cl.has_class_private_fields) {
+			var block = new CCodeBlock ();
+			var cdecl = new CCodeDeclaration ("%sClassPrivate *".printf (cl.get_cname ()));
+			cdecl.add_declarator (new CCodeVariableDeclarator ("priv"));
+			block.add_statement (cdecl);
+			
+			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
+			ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf(cl.get_cname())));
+
+			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("priv"), ccall)));
+
+			source_include_directives.append (new CCodeIncludeDirective ("string.h"));
+
+			var iftrue = new CCodeBlock ();
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("memcpy"));
+			ccall.add_argument (new CCodeIdentifier ("priv"));
+			ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"));
+			ccall.add_argument (new CCodeIdentifier ("sizeof (%sClassPrivate)".printf(cl.get_cname())));
+			iftrue.add_statement (new CCodeExpressionStatement (ccall));
+
+			block.add_statement (new CCodeIfStatement (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"), iftrue));
+
+			block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"), new CCodeIdentifier ("priv"))));
+
+
+			init_block.add_statement (block);
+
+			ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_free"));
+			ccall.add_argument (new CCodeIdentifier ("%sClassPrivate".printf (cl.get_cname ())));
+			ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"));
+			base_finalize_fragment.append (new CCodeExpressionStatement (ccall));
+			base_finalize_fragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("klass"), "priv"), new CCodeIdentifier ("NULL"))));
+		}
+
+		init_block.add_statement (base_init_fragment);
+
+		source_type_member_definition.append (base_init);
+	}
+
 	private void add_class_init_function (Class cl) {
 		var class_init = new CCodeFunction ("%s_class_init".printf (cl.get_lower_case_cname (null)), "void");
 		class_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
@@ -790,9 +868,15 @@
 			if (field.binding != MemberBinding.CLASS || field.initializer == null) {
 				continue;
 			}
-			CCodeExpression left = new CCodeMemberAccess (new CCodeIdentifier ("klass"),
-			                                              field.get_cname (), true);
-			CCodeExpression right = (CCodeExpression)field.initializer.ccodenode;
+
+			CCodeExpression left;
+
+			if (field.access == SymbolAccessibility.PRIVATE) {
+				left = new CCodeMemberAccess (new CCodeMemberAccess (new CCodeIdentifier ("klass"), "priv", true), field.get_cname (), true);
+			} else {
+				left = new CCodeMemberAccess (new CCodeIdentifier ("klass"), field.get_cname (), true);
+			}
+			CCodeExpression right = (CCodeExpression) field.initializer.ccodenode;
 			CCodeAssignment assign = new CCodeAssignment (left, right);
 			init_block.add_statement (new CCodeExpressionStatement (assign));
 		}
@@ -1072,7 +1156,22 @@
 
 		source_type_member_definition.append (instance_init);
 	}
-	
+
+	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;
+
+		function.add_parameter (new CCodeFormalParameter ("klass", cl.get_cname () + "Class *"));
+		source_type_member_declaration.append (function.copy ());
+		
+		var cblock = new CCodeBlock ();
+
+		cblock.add_statement (base_finalize_fragment);
+
+		function.block = cblock;
+		source_type_member_definition.append (function);
+	}
+
 	private void add_finalize_function (Class cl) {
 		var function = new CCodeFunction ("%s_finalize".printf (cl.get_lower_case_cname (null)), "void");
 		function.modifiers = CCodeModifiers.STATIC;
@@ -1602,25 +1701,16 @@
 		} else if (c.binding == MemberBinding.CLASS) {
 			// class constructor
 
-			var base_init = new CCodeFunction ("%s_base_init".printf (cl.get_lower_case_cname (null)), "void");
-			base_init.add_parameter (new CCodeFormalParameter ("klass", "%sClass *".printf (cl.get_cname ())));
-			base_init.modifiers = CCodeModifiers.STATIC;
-
-			source_type_member_declaration.append (base_init.copy ());
-
-			var block = (CCodeBlock) c.body.ccodenode;
 			if (current_method_inner_error) {
 				/* always separate error parameter and inner_error local variable
 				 * as error may be set to NULL but we're always interested in inner errors
 				 */
 				var cdecl = new CCodeDeclaration ("GError *");
 				cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("inner_error", new CCodeConstant ("NULL")));
-				block.prepend_statement (cdecl);
+				base_init_fragment.append (cdecl);
 			}
 
-			base_init.block = block;
-		
-			source_type_member_definition.append (base_init);
+			base_init_fragment.append (c.body.ccodenode);
 		} else if (c.binding == MemberBinding.STATIC) {
 			// static class constructor
 			// add to class_init

Modified: trunk/gobject/valainterfaceregisterfunction.vala
==============================================================================
--- trunk/gobject/valainterfaceregisterfunction.vala	(original)
+++ trunk/gobject/valainterfaceregisterfunction.vala	Tue Dec 16 21:14:45 2008
@@ -48,11 +48,15 @@
 	public override string get_base_init_func_name () {
 		return "%s_base_init".printf (interface_reference.get_lower_case_cname (null));
 	}
+	
+	public override string get_base_finalize_func_name () {
+		return "NULL";
+	}
 
 	public override string get_class_init_func_name () {
 		return "NULL";
 	}
-	
+
 	public override string get_instance_struct_size () {
 		return "0";
 	}

Modified: trunk/gobject/valatyperegisterfunction.vala
==============================================================================
--- trunk/gobject/valatyperegisterfunction.vala	(original)
+++ trunk/gobject/valatyperegisterfunction.vala	Tue Dec 16 21:14:45 2008
@@ -1,6 +1,6 @@
 /* valatyperegisterfunction.vala
  *
- * Copyright (C) 2006-2007  JÃrg Billeter
+ * Copyright (C) 2006-2008  JÃrg Billeter
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -108,7 +108,7 @@
 		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) NULL, (GClassInitFunc) %s, (GClassFinalizeFunc) NULL, NULL, %s, 0, (GInstanceInitFunc) %s, %s }".printf (get_type_struct_name (), get_base_init_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) 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))));
 			type_init.add_statement (ctypedecl);
 			if (fundamental) {
 				var ctypefundamentaldecl = new CCodeDeclaration ("const GTypeFundamentalInfo");
@@ -208,7 +208,6 @@
 	public virtual string get_type_struct_name () {
 		assert_not_reached ();
 	}
-
 	/**
 	 * Returns the name of the base_init function in C code.
 	 *
@@ -219,6 +218,15 @@
 	}
 
 	/**
+	 * Returns the name of the base_finalize function in C code.
+	 *
+	 * @return C function name
+	 */
+	public virtual string get_base_finalize_func_name () {
+		assert_not_reached ();
+	}
+
+	/**
 	 * Returns the name of the class_init function in C code.
 	 *
 	 * @return C function name

Modified: trunk/vala/valaclass.vala
==============================================================================
--- trunk/vala/valaclass.vala	(original)
+++ trunk/vala/valaclass.vala	Tue Dec 16 21:14:45 2008
@@ -81,6 +81,11 @@
 	 * Specifies whether this class has private fields.
 	 */
 	public bool has_private_fields { get; private set; }
+	
+	/**
+	 * Specifies whether this class has class fields.
+	 */
+	public bool has_class_private_fields { get; private set; }
 
 	private string cname;
 	private string const_cname;
@@ -247,6 +252,8 @@
 		fields.add (f);
 		if (f.access == SymbolAccessibility.PRIVATE && f.binding == MemberBinding.INSTANCE) {
 			has_private_fields = true;
+		} else if (f.access == SymbolAccessibility.PRIVATE && f.binding == MemberBinding.CLASS) {
+			has_class_private_fields = true;
 		}
 		scope.add (f.name, f);
 	}



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