[vala] Support to_string() for non-GType enums



commit 8166abea81a4767977dfa7340b5f6bcf288c1f04
Author: Luca Bruno <lucabru src gnome org>
Date:   Tue Aug 31 10:36:51 2010 +0200

    Support to_string() for non-GType enums
    
    Fixes bug 612081.

 codegen/valaccodemethodcallmodule.vala |   40 ++++++++++++++++++++++++++++++++
 codegen/valagtypemodule.vala           |    6 +++-
 vala/valaenumvaluetype.vala            |   18 ++++++++++++-
 vapi/gobject-2.0.vapi                  |    5 ----
 4 files changed, 60 insertions(+), 9 deletions(-)
---
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 65dc986..5a01c91 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -43,6 +43,11 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 		if (itype is MethodType) {
 			assert (ma != null);
 			m = ((MethodType) itype).method_symbol;
+			if (ma.inner != null && ma.inner.value_type is EnumValueType && ((EnumValueType) ma.inner.value_type).get_to_string_method() == m) {
+				// Enum.VALUE.to_string()
+				var en = (Enum) ma.inner.value_type.data_type;
+				ccall.call = new CCodeIdentifier (generate_enum_tostring_function (en));
+			}
 		} else if (itype is SignalType) {
 			var sig_type = (SignalType) itype;
 			if (ma != null && ma.inner is BaseAccess && sig_type.signal_symbol.is_virtual) {
@@ -792,5 +797,40 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
 			expr.ccodenode = ccomma;
 		}
 	}
+
+	private string generate_enum_tostring_function (Enum en) {
+		var to_string_func = "_%s_to_string".printf (en.get_lower_case_cname ());
+
+		if (!add_wrapper (to_string_func)) {
+			// wrapper already defined
+			return to_string_func;
+		}
+		// declaration
+
+		var function = new CCodeFunction (to_string_func, "const char*");
+		function.modifiers = CCodeModifiers.STATIC;
+
+		function.add_parameter (new CCodeFormalParameter ("value", en.get_cname ()));
+
+		// definition
+		var cblock = new CCodeBlock ();
+
+		var cswitch = new CCodeSwitchStatement (new CCodeConstant ("value"));
+		foreach (var enum_value in en.get_values ()) {
+			cswitch.add_statement (new CCodeCaseStatement (new CCodeIdentifier (enum_value.get_cname ())));
+			cswitch.add_statement (new CCodeReturnStatement (new CCodeConstant ("\""+enum_value.get_cname ()+"\"")));
+		}
+		cblock.add_statement (cswitch);
+		cblock.add_statement (new CCodeReturnStatement (new CCodeConstant ("NULL")));
+
+		// append to file
+
+		cfile.add_type_member_declaration (function.copy ());
+
+		function.block = cblock;
+		cfile.add_function (function);
+
+		return to_string_func;
+	}
 }
 
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index d8531a5..82b3ba0 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -2055,11 +2055,13 @@ public class Vala.GTypeModule : GErrorModule {
 	public override void visit_method_call (MethodCall expr) {
 		var ma = expr.call as MemberAccess;
 		var mtype = expr.call.value_type as MethodType;
-		if (mtype == null || mtype.method_symbol.get_full_name () != "GLib.Enum.to_string" ||
-		    ma == null || ma.inner.value_type.get_type_id () == null) {
+		if (mtype == null || ma == null || ma.inner == null ||
+			!(ma.inner.value_type is EnumValueType) || !((Enum) ma.inner.value_type.data_type).has_type_id ||
+			mtype.method_symbol != ((EnumValueType) ma.inner.value_type).get_to_string_method ()) {
 			base.visit_method_call (expr);
 			return;
 		}
+		// to_string() on a gtype enum
 
 		var ccomma = new CCodeCommaExpression ();
 		var temp_var = get_temp_variable (new CType ("GEnumValue*"), false, expr, false);
diff --git a/vala/valaenumvaluetype.vala b/vala/valaenumvaluetype.vala
index 979bfe2..8a5b7d6 100644
--- a/vala/valaenumvaluetype.vala
+++ b/vala/valaenumvaluetype.vala
@@ -26,6 +26,8 @@ using GLib;
  * An enum value type.
  */
 public class Vala.EnumValueType : ValueType {
+	private Method? to_string_method;
+
 	public EnumValueType (Enum type_symbol) {
 		base (type_symbol);
 	}
@@ -39,10 +41,22 @@ public class Vala.EnumValueType : ValueType {
 		return result;
 	}
 
+	public Method get_to_string_method () {
+		if (to_string_method == null) {
+			var string_type = new ObjectType ((Class) CodeContext.get ().root.scope.lookup ("string"));
+			string_type.value_owned = false;
+			to_string_method = new Method ("to_string", string_type);
+			to_string_method.access = SymbolAccessibility.PUBLIC;
+			to_string_method.external = true;
+			to_string_method.owner = type_symbol.scope;
+		}
+		return to_string_method;
+	}
+
 	public override Symbol? get_member (string member_name) {
 		var result = base.get_member (member_name);
-		if (result == null) {
-			result = CodeContext.get ().root.scope.lookup ("GLib").scope.lookup ("Enum").scope.lookup (member_name);
+		if (result == null && member_name == "to_string") {
+			return get_to_string_method ();
 		}
 		return result;
 	}
diff --git a/vapi/gobject-2.0.vapi b/vapi/gobject-2.0.vapi
index 873e2d5..d9cd08b 100644
--- a/vapi/gobject-2.0.vapi
+++ b/vapi/gobject-2.0.vapi
@@ -366,11 +366,6 @@ namespace GLib {
 		protected InitiallyUnowned ();
 	}
 
-	[CCode (cname = "int")]
-	public struct Enum : int {
-		public unowned string to_string ();
-	}
-
 	[CCode (lower_case_csuffix = "enum")]
 	public class EnumClass : TypeClass {
 		public unowned EnumValue? get_value (int value);



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