[vala] codegen: Support non-auto property initializer in gobjects
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] codegen: Support non-auto property initializer in gobjects
- Date: Tue, 11 Jun 2013 21:07:49 +0000 (UTC)
commit 73e553ac3488d641fb08b275bcf2636e3cf0de67
Author: Luca Bruno <lucabru src gnome org>
Date: Tue Jun 11 23:02:44 2013 +0200
codegen: Support non-auto property initializer in gobjects
Fixes bug 701978
codegen/valaccodeattribute.vala | 85 +++++++++++++++++++++++++++++++--------
codegen/valagobjectmodule.vala | 21 ++++++++++
codegen/valagtypemodule.vala | 27 ++++++------
tests/Makefile.am | 1 +
tests/objects/bug701978.vala | 22 ++++++++++
vala/valaproperty.vala | 18 ++++++++-
6 files changed, 143 insertions(+), 31 deletions(-)
---
diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala
index d11021b..82a74f7 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 d2e81e3..cddbc5e 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 604456a..552d4e6 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 06ca778..d9c7c96 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 0000000..22fcfaf
--- /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 82cfff1..8a8ced4 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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]