]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Support non-auto property initializer in gobjects 73e553ac3488d641fb08b275bcf2636e3cf0de67
authorLuca Bruno <lucabru@src.gnome.org>
Tue, 11 Jun 2013 21:02:44 +0000 (23:02 +0200)
committerLuca Bruno <lucabru@src.gnome.org>
Tue, 11 Jun 2013 21:07:16 +0000 (23:07 +0200)
Fixes bug 701978

codegen/valaccodeattribute.vala
codegen/valagobjectmodule.vala
codegen/valagtypemodule.vala
tests/Makefile.am
tests/objects/bug701978.vala [new file with mode: 0644]
vala/valaproperty.vala

index d11021beefb56176c2eebd8166c343f3d5d484da..82a74f7c3b2333e18e761d520ea802db3a7667f8 100644 (file)
@@ -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 () {
index d2e81e35ef6b8017238521f6ab7d82ee80ec7fe5..cddbc5e67bec812ae93a768e40fdc1746b5257c5 100644 (file)
@@ -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 ();
+                               }
+                       }
                }
        }
 
index 604456afa8c4315f58718aca887e06edc99360a1..552d4e64c07541ca0bb8265951207b0c0051c010 100644 (file)
@@ -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");
index 06ca778d4b91b9bcaf1ac47911138b872f349a04..d9c7c9689164a8ff6be451eaa009af3385fd7b02 100644 (file)
@@ -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 (file)
index 0000000..22fcfaf
--- /dev/null
@@ -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);
+}
index 82cfff125033cf556c5ee6a6caa0981adc185576..8a8ced49b432f2dcec63741441281b0badc4ebd7 100644 (file)
@@ -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;