[vala] Use TypeRegisterFunction for enum/flags



commit 240a80c90136272b5d56e538c19ae443a9ba8c70
Author: Marc-André Lureau <marcandre lureau gmail com>
Date:   Tue Jan 26 01:47:55 2010 +0100

    Use TypeRegisterFunction for enum/flags
    
    Fixes bug 592904.

 codegen/Makefile.am                     |    1 +
 codegen/valaccodebasemodule.vala        |   73 -------------------------------
 codegen/valaenumregisterfunction.vala   |   57 ++++++++++++++++++++++++
 codegen/valagtypemodule.vala            |   10 ++++
 codegen/valastructregisterfunction.vala |    8 ++--
 codegen/valatyperegisterfunction.vala   |   51 +++++++++++++++++++++-
 6 files changed, 121 insertions(+), 79 deletions(-)
---
diff --git a/codegen/Makefile.am b/codegen/Makefile.am
index b672c27..8a452b2 100644
--- a/codegen/Makefile.am
+++ b/codegen/Makefile.am
@@ -34,6 +34,7 @@ libvala_la_VALASOURCES = \
 	valadbusinterfaceregisterfunction.vala \
 	valadbusmodule.vala \
 	valadbusservermodule.vala \
+	valaenumregisterfunction.vala \
 	valagerrormodule.vala \
 	valagirwriter.vala \
 	valagobjectmodule.vala \
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 1beb9fa..ea136b2 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -804,79 +804,6 @@ internal class Vala.CCodeBaseModule : CCodeModule {
 		if (!en.is_private_symbol ()) {
 			generate_enum_declaration (en, internal_header_declarations);
 		}
-
-		if (!en.has_type_id) {
-			return;
-		}
-
-		var clist = new CCodeInitializerList (); /* or during visit time? */
-		CCodeInitializerList clist_ev = null;
-		foreach (EnumValue ev in en.get_values ()) {
-			clist_ev = new CCodeInitializerList ();
-			clist_ev.append (new CCodeConstant (ev.get_cname ()));
-			clist_ev.append (new CCodeIdentifier ("\"%s\"".printf (ev.get_cname ())));
-			clist_ev.append (ev.get_canonical_cconstant ());
-			clist.append (clist_ev);
-		}
-
-		clist_ev = new CCodeInitializerList ();
-		clist_ev.append (new CCodeConstant ("0"));
-		clist_ev.append (new CCodeConstant ("NULL"));
-		clist_ev.append (new CCodeConstant ("NULL"));
-		clist.append (clist_ev);
-
-		var enum_decl = new CCodeVariableDeclarator ("values[]", clist);
-
-		CCodeDeclaration cdecl = null;
-		if (en.is_flags) {
-			cdecl = new CCodeDeclaration ("const GFlagsValue");
-		} else {
-			cdecl = new CCodeDeclaration ("const GEnumValue");
-		}
-
-		cdecl.add_declarator (enum_decl);
-		cdecl.modifiers = CCodeModifiers.STATIC;
-
-		var type_init = new CCodeBlock ();
-
-		type_init.add_statement (cdecl);
-
-		var fun_name = "%s_get_type".printf (en.get_lower_case_cname (null));
-		var regfun = new CCodeFunction (fun_name, "GType");
-		var regblock = new CCodeBlock ();
-
-		cdecl = new CCodeDeclaration ("GType");
-		string type_id_name = "%s_type_id".printf (en.get_lower_case_cname (null));
-		cdecl.add_declarator (new CCodeVariableDeclarator (type_id_name, new CCodeConstant ("0")));
-		cdecl.modifiers = CCodeModifiers.STATIC;
-		regblock.add_statement (cdecl);
-
-		CCodeFunctionCall reg_call;
-		if (en.is_flags) {
-			reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_flags_register_static"));
-		} else {
-			reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_enum_register_static"));
-		}
-
-		reg_call.add_argument (new CCodeConstant ("\"%s\"".printf (en.get_cname())));
-		reg_call.add_argument (new CCodeIdentifier ("values"));
-
-		type_init.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (type_id_name), reg_call)));
-
-		var cond = new CCodeFunctionCall (new CCodeIdentifier ("G_UNLIKELY"));
-		cond.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeIdentifier (type_id_name), new CCodeConstant ("0")));
-		var cif = new CCodeIfStatement (cond, type_init);
-		regblock.add_statement (cif);
-
-		regblock.add_statement (new CCodeReturnStatement (new CCodeConstant (type_id_name)));
-
-		if (en.access == SymbolAccessibility.PRIVATE) {
-			regfun.modifiers = CCodeModifiers.STATIC;
-		}
-		regfun.block = regblock;
-
-		source_type_member_definition.append (new CCodeNewline ());
-		source_type_member_definition.append (regfun);
 	}
 
 	public override void visit_member (Member m) {
diff --git a/codegen/valaenumregisterfunction.vala b/codegen/valaenumregisterfunction.vala
new file mode 100644
index 0000000..e54098c
--- /dev/null
+++ b/codegen/valaenumregisterfunction.vala
@@ -0,0 +1,57 @@
+/* valaenumregisterfunction.vala
+ *
+ * Copyright (C) 2008  Jürg Billeter
+ * Copyright (C) 2010  Marc-Andre Lureau
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ * 	Jürg Billeter <j bitron ch>
+ */
+
+using GLib;
+
+/**
+ * C function to register an enum at runtime.
+ */
+public class Vala.EnumRegisterFunction : TypeRegisterFunction {
+	/**
+	 * Specifies the enum to be registered.
+	 */
+	public weak Enum enum_reference { get; set; }
+
+	/**
+	 * Creates a new C function to register the specified enum at runtime.
+	 *
+	 * @param en an enum
+	 * @return   newly created enum register function
+	 */
+	public EnumRegisterFunction (Enum en, CodeContext context) {
+		enum_reference = en;
+		this.context = context;
+	}
+
+	public override TypeSymbol get_type_declaration () {
+		return enum_reference;
+	}
+
+	public override SymbolAccessibility get_accessibility () {
+		return enum_reference.access;
+	}
+
+	public override CCodeFragment get_type_interface_init_statements (bool plugin) {
+		return new CCodeFragment ();
+	}
+}
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 7353e66..152fcae 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -2017,6 +2017,16 @@ internal class Vala.GTypeModule : GErrorModule {
 		}
 	}
 
+	public override void visit_enum (Enum en) {
+		base.visit_enum (en);
+
+		if (en.has_type_id) {
+			var type_fun = new EnumRegisterFunction (en, context);
+			type_fun.init_from_type (false);
+			source_type_member_definition.append (type_fun.get_definition ());
+		}
+	}
+
 	public override void visit_method_call (MethodCall expr) {
 		var ma = expr.call as MemberAccess;
 		var mtype = expr.call.value_type as MethodType;
diff --git a/codegen/valastructregisterfunction.vala b/codegen/valastructregisterfunction.vala
index 1f79fdb..2684b48 100644
--- a/codegen/valastructregisterfunction.vala
+++ b/codegen/valastructregisterfunction.vala
@@ -23,7 +23,7 @@
 using GLib;
 
 /**
- * C function to register a class at runtime.
+ * C function to register a struct at runtime.
  */
 public class Vala.StructRegisterFunction : TypeRegisterFunction {
 	/**
@@ -32,10 +32,10 @@ public class Vala.StructRegisterFunction : TypeRegisterFunction {
 	public weak Struct struct_reference { get; set; }
 
 	/**
-	 * Creates a new C function to register the specified class at runtime.
+	 * Creates a new C function to register the specified struct at runtime.
 	 *
-	 * @param cl a class
-	 * @return   newly created class register function
+	 * @param st a struct
+	 * @return   newly created struct register function
 	 */
 	public StructRegisterFunction (Struct st, CodeContext context) {
 		struct_reference = st;
diff --git a/codegen/valatyperegisterfunction.vala b/codegen/valatyperegisterfunction.vala
index 571bca6..b56f159 100644
--- a/codegen/valatyperegisterfunction.vala
+++ b/codegen/valatyperegisterfunction.vala
@@ -141,6 +141,13 @@ public abstract class Vala.TypeRegisterFunction {
 		CCodeFunctionCall reg_call;
 		if (get_type_declaration () is Struct) {
 			reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_boxed_type_register_static"));
+		} else if (get_type_declaration () is Enum) {
+			var en = get_type_declaration () as Enum;
+			if (en.is_flags) {
+				reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_flags_register_static"));
+			} else {
+				reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_enum_register_static"));
+			}
 		} else if (fundamental) {
 			reg_call = new CCodeFunctionCall (new CCodeIdentifier ("g_type_register_fundamental"));
 			reg_call.add_argument (new CCodeFunctionCall (new CCodeIdentifier ("g_type_fundamental_next")));
@@ -157,6 +164,39 @@ public abstract class Vala.TypeRegisterFunction {
 			var st = (Struct) get_type_declaration ();
 			reg_call.add_argument (new CCodeCastExpression (new CCodeIdentifier (st.get_dup_function ()), "GBoxedCopyFunc"));
 			reg_call.add_argument (new CCodeCastExpression (new CCodeIdentifier (st.get_free_function ()), "GBoxedFreeFunc"));
+		} else if (get_type_declaration () is Enum) {
+			var en = get_type_declaration () as Enum;
+			var clist = new CCodeInitializerList (); /* or during visit time? */
+
+			CCodeInitializerList clist_ev = null;
+			foreach (EnumValue ev in en.get_values ()) {
+				clist_ev = new CCodeInitializerList ();
+				clist_ev.append (new CCodeConstant (ev.get_cname ()));
+				clist_ev.append (new CCodeIdentifier ("\"%s\"".printf (ev.get_cname ())));
+				clist_ev.append (ev.get_canonical_cconstant ());
+				clist.append (clist_ev);
+			}
+
+			clist_ev = new CCodeInitializerList ();
+			clist_ev.append (new CCodeConstant ("0"));
+			clist_ev.append (new CCodeConstant ("NULL"));
+			clist_ev.append (new CCodeConstant ("NULL"));
+			clist.append (clist_ev);
+
+			var enum_decl = new CCodeVariableDeclarator ("values[]", clist);
+
+			if (en.is_flags) {
+				cdecl = new CCodeDeclaration ("const GFlagsValue");
+			} else {
+				cdecl = new CCodeDeclaration ("const GEnumValue");
+			}
+
+			cdecl.add_declarator (enum_decl);
+			cdecl.modifiers = CCodeModifiers.STATIC;
+
+			type_init.add_statement (cdecl);
+
+			reg_call.add_argument (new CCodeIdentifier ("values"));
 		} else {
 			reg_call.add_argument (new CCodeIdentifier ("&g_define_type_info"));
 			if (fundamental) {
@@ -172,7 +212,7 @@ public abstract class Vala.TypeRegisterFunction {
 		} else {
 			type_init.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (type_id_name), reg_call)));
 		}
-		
+
 		type_init.add_statement (get_type_interface_init_statements (plugin));
 
 		if (!plugin) {
@@ -192,7 +232,14 @@ public abstract class Vala.TypeRegisterFunction {
 				condition = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, id, zero);
 			}
 
-			var cif = new CCodeIfStatement (condition, type_init);
+			CCodeExpression cond;
+			if (use_thread_safe) {
+				cond = condition;
+			} else {
+				cond = new CCodeFunctionCall (new CCodeIdentifier ("G_UNLIKELY"));
+				(cond as CCodeFunctionCall).add_argument (condition);
+			}
+			var cif = new CCodeIfStatement (cond, type_init);
 			type_block.add_statement (cif);
 		} else {
 			type_block = type_init;



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