From: wxx <769218589@qq.com> Date: Tue, 30 Nov 2021 18:54:04 +0000 (+0800) Subject: vala: Transform assignment of an array element as needed X-Git-Tag: 0.52.11~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5bab6ff1872610e6b6afe0b23ceeda7b2ca364f;p=thirdparty%2Fvala.git vala: Transform assignment of an array element as needed Fixes https://gitlab.gnome.org/GNOME/vala/issues/889 Fixes https://gitlab.gnome.org/GNOME/vala/issues/1258 --- diff --git a/tests/Makefile.am b/tests/Makefile.am index 69f687dc1..48369672a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -50,6 +50,7 @@ TESTS = \ basic-types/custom-types.vala \ basic-types/default-gtype.vala \ basic-types/strings.vala \ + basic-types/string-array-append.vala \ basic-types/string-concat-null.test \ basic-types/arrays.vala \ basic-types/arrays-generics.vala \ @@ -111,6 +112,7 @@ TESTS = \ arrays/class-field-initializer.vala \ arrays/class-field-length-cname.vala \ arrays/constant-element-access.vala \ + arrays/element-nullable-assignment.vala \ arrays/empty-length-0.vala \ arrays/expression-bracket.test \ arrays/fixed-length-init0-not-allowed.vala \ diff --git a/tests/arrays/element-nullable-assignment.vala b/tests/arrays/element-nullable-assignment.vala new file mode 100644 index 000000000..29dc2950e --- /dev/null +++ b/tests/arrays/element-nullable-assignment.vala @@ -0,0 +1,11 @@ +void main () { + int?[] foo = { 23, 42, 4711 }; + + foo[0] += 1; + foo[1] *= 3; + foo[2] -= 2; + + assert (foo[0] == 24); + assert (foo[1] == 126); + assert (foo[2] == 4709); +} diff --git a/tests/basic-types/string-array-append.vala b/tests/basic-types/string-array-append.vala new file mode 100644 index 000000000..4b1ae328e --- /dev/null +++ b/tests/basic-types/string-array-append.vala @@ -0,0 +1,12 @@ +void main () { + string[] foo = { "foo", "bar", "foo bar" }; + + foo[0] += "abc"; + foo[1] += 123.to_string (); + foo[2] += " abc" + 123.to_string (); + + assert (foo[0] == "fooabc"); + assert (foo[1] == "bar123"); + assert (foo[2] == "foo bar abc123"); +} + diff --git a/vala/valaassignment.vala b/vala/valaassignment.vala index 8c0948ef3..150c34723 100644 --- a/vala/valaassignment.vala +++ b/vala/valaassignment.vala @@ -229,13 +229,36 @@ public class Vala.Assignment : Expression { } unowned MemberAccess? ma = left as MemberAccess; - if (operator != AssignmentOperator.SIMPLE && ma != null - && !(left.value_type.is_non_null_simple_type () && ma.symbol_reference is LocalVariable)) { + unowned ElementAccess? ea = left as ElementAccess; + bool transform_assignment = false; + + if (ma != null && !(ma.symbol_reference is LocalVariable)) { + transform_assignment = true; + } else if (left.value_type != null && !left.value_type.is_non_null_simple_type ()) { + transform_assignment = true; + } else if (ea != null && ea.container.value_type is ArrayType) { + // check if the left is an array and its element is non-null simple type + unowned ArrayType array_type = (ArrayType) ea.container.value_type; + transform_assignment = !array_type.element_type.is_non_null_simple_type (); + } + + if ((operator != AssignmentOperator.SIMPLE) && transform_assignment) { // transform into simple assignment // FIXME: only do this if the backend doesn't support // the assignment natively - - var old_value = new MemberAccess (ma.inner, ma.member_name, source_reference); + Expression old_value = null; + + if (ma != null) { + old_value = new MemberAccess (ma.inner, ma.member_name, left.source_reference); + } else if (ea !=null) { + old_value = new ElementAccess (ea.container, left.source_reference); + var indices = ea.get_indices (); + foreach (var index in indices) { + ((ElementAccess) old_value).append_index (index); + } + } else { + assert_not_reached (); + } BinaryOperator bop; @@ -361,9 +384,7 @@ public class Vala.Assignment : Expression { } } } - } else if (left is ElementAccess) { - unowned ElementAccess ea = (ElementAccess) left; - + } else if (ea != null) { if (!right.value_type.compatible (left.value_type)) { error = true; Report.error (source_reference, "Assignment: Cannot convert from `%s' to `%s'", right.value_type.to_string (), left.value_type.to_string ());