summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Werbeck <simon.werbeck@gmail.com>2020-03-24 17:35:09 +0100
committerRico Tzschichholz <ricotz@ubuntu.com>2020-03-25 18:04:40 +0100
commitbb85929a76cbb114fd7992b5f30dc105cc673523 (patch)
treea2b46a0236f1df6d8718ddbac6ee631d2378b9bd
parent74725956b2c99da3ff289ff2d294c525ff2f85c9 (diff)
downloadvala-bb85929a76cbb114fd7992b5f30dc105cc673523.tar.gz
vala: Support struct initializer list in non-constant array
A struct initializer list contained in an array initializer list is now transformed to a struct creation expression. The pre-existing logic ensures that constant expressions are not transformed. Fixes https://gitlab.gnome.org/GNOME/vala/issues/949
-rw-r--r--tests/Makefile.am1
-rwxr-xr-xtests/structs/struct-initializer-list-in-array.vala24
-rw-r--r--vala/valaarraycreationexpression.vala2
-rw-r--r--vala/valainitializerlist.vala28
4 files changed, 51 insertions, 4 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7a6d37d8f..c7d6e4554 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -259,6 +259,7 @@ TESTS = \
structs/struct_only.vala \
structs/struct-base-types.vala \
structs/struct-empty-still.test \
+ structs/struct-initializer-list-in-array.vala \
structs/struct-no-gtype.vala \
structs/struct-no-gtype-inherit.vala \
structs/struct-static-field-initializer.vala \
diff --git a/tests/structs/struct-initializer-list-in-array.vala b/tests/structs/struct-initializer-list-in-array.vala
new file mode 100755
index 000000000..a37271b99
--- /dev/null
+++ b/tests/structs/struct-initializer-list-in-array.vala
@@ -0,0 +1,24 @@
+struct Foo {
+ public string s;
+ public Bar b;
+ public bool[] ba;
+ public int i;
+}
+
+struct Bar {
+ public string s;
+ public int i;
+}
+
+void main () {
+ Foo[] foos = {
+ { "foo", { "foo", 42 }, { true }, 23 },
+ { "bar", { "bar", 4711 }, { false }, 42 },
+ };
+
+ var f = foos[0];
+ assert (f.i == 23 && f.s == "foo" && f.b.s == "foo" && f.ba[0]);
+
+ f = foos[1];
+ assert (f.i == 42 && f.s == "bar" && f.b.i == 4711 && !f.ba[0]);
+}
diff --git a/vala/valaarraycreationexpression.vala b/vala/valaarraycreationexpression.vala
index 95e83e226..8bf42ea26 100644
--- a/vala/valaarraycreationexpression.vala
+++ b/vala/valaarraycreationexpression.vala
@@ -201,7 +201,7 @@ public class Vala.ArrayCreationExpression : Expression {
int subsize = -1;
foreach (Expression e in il.get_initializers ()) {
- if (e is InitializerList) {
+ if (e is InitializerList && e.target_type is ArrayType) {
if (rank == 1) {
il.error = true;
e.error = true;
diff --git a/vala/valainitializerlist.vala b/vala/valainitializerlist.vala
index 50d1ed487..8372be3cd 100644
--- a/vala/valainitializerlist.vala
+++ b/vala/valainitializerlist.vala
@@ -194,6 +194,17 @@ public class Vala.InitializerList : Expression {
st = st.base_struct;
}
+ var in_array_creation_initializer = parent_node is InitializerList && parent_node.parent_node is ArrayCreationExpression;
+ ObjectCreationExpression? struct_creation = null;
+ if (in_array_creation_initializer) {
+ var ma = new MemberAccess.simple (st.name, source_reference);
+ ma.creation_member = true;
+ ma.symbol_reference = st;
+ struct_creation = new ObjectCreationExpression (ma, source_reference);
+ struct_creation.target_type = target_type.copy ();
+ struct_creation.struct_creation = true;
+ }
+
var field_it = st.get_fields ().iterator ();
foreach (Expression e in get_initializers ()) {
Field field = null;
@@ -210,11 +221,22 @@ public class Vala.InitializerList : Expression {
}
}
- e.target_type = field.variable_type.copy ();
- if (!target_type.value_owned) {
- e.target_type.value_owned = false;
+ if (in_array_creation_initializer) {
+ var member_init = new MemberInitializer (field.name, e, e.source_reference);
+ struct_creation.add_member_initializer (member_init);
+ } else {
+ e.target_type = field.variable_type.copy ();
+ if (!target_type.value_owned) {
+ e.target_type.value_owned = false;
+ }
}
}
+
+ if (in_array_creation_initializer) {
+ parent_node.replace_expression (this, struct_creation);
+ checked = false;
+ return struct_creation.check (context);
+ }
} else {
error = true;
Report.error (source_reference, "initializer list used for `%s', which is neither array nor struct".printf (target_type.to_string ()));