Fixes bug 612081.
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) {
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;
+ }
}
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);
* An enum value type.
*/
public class Vala.EnumValueType : ValueType {
+ private Method? to_string_method;
+
public EnumValueType (Enum type_symbol) {
base (type_symbol);
}
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;
}
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);