From: Luca Bruno Date: Tue, 11 Jun 2013 21:02:44 +0000 (+0200) Subject: codegen: Support non-auto property initializer in gobjects X-Git-Tag: 0.21.1~43 X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=refs%2Fkeep-around%2F73e553ac3488d641fb08b275bcf2636e3cf0de67;p=thirdparty%2Fvala.git codegen: Support non-auto property initializer in gobjects Fixes bug 701978 --- diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala index d11021bee..82a74f7c3 100644 --- a/codegen/valaccodeattribute.vala +++ b/codegen/valaccodeattribute.vala @@ -1113,27 +1113,78 @@ public class Vala.CCodeAttribute : AttributeCache { } private string get_default_param_spec_function () { - if (sym is Class) { - var cl = (Class) sym; - if (cl.is_fundamental ()) { - return CCodeBaseModule.get_ccode_lower_case_name (cl, "param_spec_"); - } else if (cl.base_class != null) { - return CCodeBaseModule.get_ccode_param_spec_function (cl.base_class); - } else if (type_id == "G_TYPE_POINTER") { + if (node is Symbol) { + if (sym is Class) { + var cl = (Class) sym; + if (cl.is_fundamental ()) { + return CCodeBaseModule.get_ccode_lower_case_name (cl, "param_spec_"); + } else if (cl.base_class != null) { + return CCodeBaseModule.get_ccode_param_spec_function (cl.base_class); + } else if (type_id == "G_TYPE_POINTER") { + return "g_param_spec_pointer"; + } else { + return "g_param_spec_boxed"; + } + } else if (sym is Interface) { + foreach (var prereq in ((Interface) sym).get_prerequisites ()) { + var func = CCodeBaseModule.get_ccode_param_spec_function (prereq.data_type); + if (func != "") { + return func; + } + } return "g_param_spec_pointer"; - } else { - return "g_param_spec_boxed"; - } - } else if (sym is Interface) { - foreach (var prereq in ((Interface) sym).get_prerequisites ()) { - var func = CCodeBaseModule.get_ccode_param_spec_function (prereq.data_type); - if (func != "") { - return func; + } else if (sym is Enum) { + var e = sym as Enum; + if (CCodeBaseModule.get_ccode_has_type_id (e)) { + if (e.is_flags) { + return "g_param_spec_flags"; + } else { + return "g_param_spec_enum"; + } + } else { + if (e.is_flags) { + return "g_param_spec_uint"; + } else { + return "g_param_spec_int"; + } + } + } else if (sym is Struct) { + var type_id = CCodeBaseModule.get_ccode_type_id (sym); + if (type_id == "G_TYPE_INT") { + return "g_param_spec_int"; + } else if (type_id == "G_TYPE_UINT") { + return "g_param_spec_uint"; + } else if (type_id == "G_TYPE_INT64") { + return "g_param_spec_int64"; + } else if (type_id == "G_TYPE_UINT64") { + return "g_param_spec_uint64"; + } else if (type_id == "G_TYPE_LONG") { + return "g_param_spec_long"; + } else if (type_id == "G_TYPE_ULONG") { + return "g_param_spec_ulong"; + } else if (type_id == "G_TYPE_BOOLEAN") { + return "g_param_spec_boolean"; + } else if (type_id == "G_TYPE_CHAR") { + return "g_param_spec_char"; + } else if (type_id == "G_TYPE_UCHAR") { + return "g_param_spec_uchar"; + }else if (type_id == "G_TYPE_FLOAT") { + return "g_param_spec_float"; + } else if (type_id == "G_TYPE_DOUBLE") { + return "g_param_spec_double"; + } else if (type_id == "G_TYPE_GTYPE") { + return "g_param_spec_gtype"; + } else { + return "g_param_spec_boxed"; } } - return "g_param_spec_pointer"; + } else if (node is ArrayType && ((ArrayType)node).element_type.data_type == CodeContext.get().analyzer.string_type.data_type) { + return "g_param_spec_boxed"; + } else if (node is DataType && ((DataType) node).data_type != null) { + return CCodeBaseModule.get_ccode_param_spec_function (((DataType) node).data_type); } - return ""; + + return "g_param_spec_pointer"; } private string get_default_default_value () { diff --git a/codegen/valagobjectmodule.vala b/codegen/valagobjectmodule.vala index d2e81e35e..cddbc5e67 100644 --- a/codegen/valagobjectmodule.vala +++ b/codegen/valagobjectmodule.vala @@ -668,6 +668,27 @@ public class Vala.GObjectModule : GTypeModule { if (is_gobject_property (prop) && prop.parent_symbol is Class) { prop_enum.add_value (new CCodeEnumValue (get_ccode_upper_case_name (prop))); + + if (prop.initializer != null && prop.set_accessor != null && !prop.set_accessor.automatic_body) { + // generate a custom initializer if it couldn't be done at class_init time + bool has_spec_initializer = prop.property_type.data_type is Enum; + if (!has_spec_initializer && prop.property_type.data_type is Struct) { + var param_spec_func = get_ccode_param_spec_function (prop.property_type.data_type); + has_spec_initializer = param_spec_func != "g_param_spec_boxed"; + } + if (!has_spec_initializer) { + push_context (instance_init_context); + + prop.initializer.emit (this); + + var inst_ma = new MemberAccess.simple ("this"); + inst_ma.target_value = new GLibValue (get_data_type_for_symbol ((Class) prop.parent_symbol), new CCodeIdentifier ("self"), true); + store_property (prop, inst_ma, prop.initializer.target_value); + + temp_ref_values.clear (); + pop_context (); + } + } } } diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index 604456afa..552d4e64c 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -1785,7 +1785,8 @@ public class Vala.GTypeModule : GErrorModule { } } else if (prop.property_type.data_type is Struct) { var st = (Struct) prop.property_type.data_type; - if (get_ccode_type_id (st) == "G_TYPE_INT") { + var type_id = get_ccode_type_id (st); + if (type_id == "G_TYPE_INT") { cspec.call = new CCodeIdentifier ("g_param_spec_int"); cspec.add_argument (new CCodeConstant ("G_MININT")); cspec.add_argument (new CCodeConstant ("G_MAXINT")); @@ -1794,7 +1795,7 @@ public class Vala.GTypeModule : GErrorModule { } else { cspec.add_argument (new CCodeConstant ("0")); } - } else if (get_ccode_type_id (st) == "G_TYPE_UINT") { + } else if (type_id == "G_TYPE_UINT") { cspec.call = new CCodeIdentifier ("g_param_spec_uint"); cspec.add_argument (new CCodeConstant ("0")); cspec.add_argument (new CCodeConstant ("G_MAXUINT")); @@ -1803,7 +1804,7 @@ public class Vala.GTypeModule : GErrorModule { } else { cspec.add_argument (new CCodeConstant ("0U")); } - } else if (get_ccode_type_id (st) == "G_TYPE_INT64") { + } else if (type_id == "G_TYPE_INT64") { cspec.call = new CCodeIdentifier ("g_param_spec_int64"); cspec.add_argument (new CCodeConstant ("G_MININT64")); cspec.add_argument (new CCodeConstant ("G_MAXINT64")); @@ -1812,7 +1813,7 @@ public class Vala.GTypeModule : GErrorModule { } else { cspec.add_argument (new CCodeConstant ("0")); } - } else if (get_ccode_type_id (st) == "G_TYPE_UINT64") { + } else if (type_id == "G_TYPE_UINT64") { cspec.call = new CCodeIdentifier ("g_param_spec_uint64"); cspec.add_argument (new CCodeConstant ("0")); cspec.add_argument (new CCodeConstant ("G_MAXUINT64")); @@ -1821,7 +1822,7 @@ public class Vala.GTypeModule : GErrorModule { } else { cspec.add_argument (new CCodeConstant ("0U")); } - } else if (get_ccode_type_id (st) == "G_TYPE_LONG") { + } else if (type_id == "G_TYPE_LONG") { cspec.call = new CCodeIdentifier ("g_param_spec_long"); cspec.add_argument (new CCodeConstant ("G_MINLONG")); cspec.add_argument (new CCodeConstant ("G_MAXLONG")); @@ -1830,7 +1831,7 @@ public class Vala.GTypeModule : GErrorModule { } else { cspec.add_argument (new CCodeConstant ("0L")); } - } else if (get_ccode_type_id (st) == "G_TYPE_ULONG") { + } else if (type_id == "G_TYPE_ULONG") { cspec.call = new CCodeIdentifier ("g_param_spec_ulong"); cspec.add_argument (new CCodeConstant ("0")); cspec.add_argument (new CCodeConstant ("G_MAXULONG")); @@ -1839,14 +1840,14 @@ public class Vala.GTypeModule : GErrorModule { } else { cspec.add_argument (new CCodeConstant ("0UL")); } - } else if (get_ccode_type_id (st) == "G_TYPE_BOOLEAN") { + } else if (type_id == "G_TYPE_BOOLEAN") { cspec.call = new CCodeIdentifier ("g_param_spec_boolean"); if (prop.initializer != null) { cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer)); } else { cspec.add_argument (new CCodeConstant ("FALSE")); } - } else if (get_ccode_type_id (st) == "G_TYPE_CHAR") { + } else if (type_id == "G_TYPE_CHAR") { cspec.call = new CCodeIdentifier ("g_param_spec_char"); cspec.add_argument (new CCodeConstant ("G_MININT8")); cspec.add_argument (new CCodeConstant ("G_MAXINT8")); @@ -1855,7 +1856,7 @@ public class Vala.GTypeModule : GErrorModule { } else { cspec.add_argument (new CCodeConstant ("0")); } - } else if (get_ccode_type_id (st) == "G_TYPE_UCHAR") { + } else if (type_id == "G_TYPE_UCHAR") { cspec.call = new CCodeIdentifier ("g_param_spec_uchar"); cspec.add_argument (new CCodeConstant ("0")); cspec.add_argument (new CCodeConstant ("G_MAXUINT8")); @@ -1864,7 +1865,7 @@ public class Vala.GTypeModule : GErrorModule { } else { cspec.add_argument (new CCodeConstant ("0")); } - }else if (get_ccode_type_id (st) == "G_TYPE_FLOAT") { + } else if (type_id == "G_TYPE_FLOAT") { cspec.call = new CCodeIdentifier ("g_param_spec_float"); cspec.add_argument (new CCodeConstant ("-G_MAXFLOAT")); cspec.add_argument (new CCodeConstant ("G_MAXFLOAT")); @@ -1873,7 +1874,7 @@ public class Vala.GTypeModule : GErrorModule { } else { cspec.add_argument (new CCodeConstant ("0.0F")); } - } else if (get_ccode_type_id (st) == "G_TYPE_DOUBLE") { + } else if (type_id == "G_TYPE_DOUBLE") { cspec.call = new CCodeIdentifier ("g_param_spec_double"); cspec.add_argument (new CCodeConstant ("-G_MAXDOUBLE")); cspec.add_argument (new CCodeConstant ("G_MAXDOUBLE")); @@ -1882,7 +1883,7 @@ public class Vala.GTypeModule : GErrorModule { } else { cspec.add_argument (new CCodeConstant ("0.0")); } - } else if (get_ccode_type_id (st) == "G_TYPE_GTYPE") { + } else if (type_id == "G_TYPE_GTYPE") { cspec.call = new CCodeIdentifier ("g_param_spec_gtype"); if (prop.initializer != null) { cspec.add_argument ((CCodeExpression) get_ccodenode (prop.initializer)); @@ -1891,7 +1892,7 @@ public class Vala.GTypeModule : GErrorModule { } } else { cspec.call = new CCodeIdentifier ("g_param_spec_boxed"); - cspec.add_argument (new CCodeIdentifier (get_ccode_type_id (st))); + cspec.add_argument (new CCodeIdentifier (type_id)); } } else if (prop.property_type is ArrayType && ((ArrayType)prop.property_type).element_type.data_type == string_type.data_type) { cspec.call = new CCodeIdentifier ("g_param_spec_boxed"); diff --git a/tests/Makefile.am b/tests/Makefile.am index 06ca778d4..d9c7c9689 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -135,6 +135,7 @@ TESTS = \ objects/bug667668.vala \ objects/bug683646.vala \ objects/bug695671.vala \ + objects/bug701978.vala \ errors/errors.vala \ errors/bug567181.vala \ errors/bug579101.vala \ diff --git a/tests/objects/bug701978.vala b/tests/objects/bug701978.vala new file mode 100644 index 000000000..22fcfafdd --- /dev/null +++ b/tests/objects/bug701978.vala @@ -0,0 +1,22 @@ +public struct Foo { + public int val { get; set; } + + public Foo () { + val = 55; + } +} + +public class Bar : Object { + private Foo _foo; + + public Foo foo { + get { return _foo; } + set { _foo = value; } + default = Foo (); + } +} + +void main () { + var bar = new Bar(); + assert (bar.foo.val == 55); +} diff --git a/vala/valaproperty.vala b/vala/valaproperty.vala index 82cfff125..8a8ced49b 100644 --- a/vala/valaproperty.vala +++ b/vala/valaproperty.vala @@ -132,7 +132,17 @@ public class Vala.Property : Symbol, Lockable { /** * Specifies the default value of this property. */ - public Expression initializer { get; set; } + public Expression initializer { + get { + return _initializer; + } + set { + _initializer = value; + _initializer.parent_node = this; + } + } + + private Expression _initializer; private bool lock_used = false; @@ -250,6 +260,12 @@ public class Vala.Property : Symbol, Lockable { } } + public override void replace_expression (Expression old_node, Expression new_node) { + if (initializer == old_node) { + initializer = new_node; + } + } + private void find_base_properties () { if (base_properties_valid) { return;