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 \
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 \
--- /dev/null
+/* arrays_element_nullable_assignment.c generated by valac, the Vala compiler
+ * generated from arrays_element_nullable_assignment.vala, do not modify */
+
+#include <glib.h>
+#include <string.h>
+
+#define _g_free0(var) ((var == NULL) ? NULL : (var = (g_free (var), NULL)))
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+static void _vala_main (void);
+static gint* _int_dup (gint* self);
+static gboolean _int_equal (const gint * s1,
+ const gint * s2);
+static void _vala_array_destroy (gpointer array,
+ gssize array_length,
+ GDestroyNotify destroy_func);
+static void _vala_array_free (gpointer array,
+ gssize array_length,
+ GDestroyNotify destroy_func);
+
+static gint*
+_int_dup (gint* self)
+{
+ gint* dup;
+ dup = g_new0 (gint, 1);
+ memcpy (dup, self, sizeof (gint));
+ return dup;
+}
+
+static gpointer
+__int_dup0 (gpointer self)
+{
+ return self ? _int_dup (self) : NULL;
+}
+
+static gboolean
+_int_equal (const gint * s1,
+ const gint * s2)
+{
+ if (s1 == s2) {
+ return TRUE;
+ }
+ if (s1 == NULL) {
+ return FALSE;
+ }
+ if (s2 == NULL) {
+ return FALSE;
+ }
+ return (*s1) == (*s2);
+}
+
+static void
+_vala_main (void)
+{
+ gint** foo = NULL;
+ gint _tmp0_;
+ gint* _tmp1_;
+ gint _tmp2_;
+ gint* _tmp3_;
+ gint _tmp4_;
+ gint* _tmp5_;
+ gint** _tmp6_;
+ gint foo_length1;
+ gint _foo_size_;
+ gint* _tmp7_;
+ gint _tmp8_;
+ gint* _tmp9_;
+ gint* _tmp10_;
+ gint _tmp11_;
+ gint* _tmp12_;
+ gint* _tmp13_;
+ gint _tmp14_;
+ gint* _tmp15_;
+ gint* _tmp16_;
+ gint _tmp17_;
+ gint* _tmp18_;
+ gint _tmp19_;
+ gint* _tmp20_;
+ gint _tmp21_;
+ _tmp0_ = 23;
+ _tmp1_ = __int_dup0 (&_tmp0_);
+ _tmp2_ = 42;
+ _tmp3_ = __int_dup0 (&_tmp2_);
+ _tmp4_ = 4711;
+ _tmp5_ = __int_dup0 (&_tmp4_);
+ _tmp6_ = g_new0 (gint*, 3);
+ _tmp6_[0] = _tmp1_;
+ _tmp6_[1] = _tmp3_;
+ _tmp6_[2] = _tmp5_;
+ foo = _tmp6_;
+ foo_length1 = 3;
+ _foo_size_ = foo_length1;
+ _tmp7_ = foo[0];
+ _tmp8_ = (*_tmp7_) + 1;
+ _tmp9_ = __int_dup0 (&_tmp8_);
+ _g_free0 (foo[0]);
+ foo[0] = _tmp9_;
+ _tmp10_ = foo[1];
+ _tmp11_ = (*_tmp10_) * 3;
+ _tmp12_ = __int_dup0 (&_tmp11_);
+ _g_free0 (foo[1]);
+ foo[1] = _tmp12_;
+ _tmp13_ = foo[2];
+ _tmp14_ = (*_tmp13_) - 2;
+ _tmp15_ = __int_dup0 (&_tmp14_);
+ _g_free0 (foo[2]);
+ foo[2] = _tmp15_;
+ _tmp16_ = foo[0];
+ _tmp17_ = 24;
+ _vala_assert (_int_equal (_tmp16_, &_tmp17_) == TRUE, "foo[0] == 24");
+ _tmp18_ = foo[1];
+ _tmp19_ = 126;
+ _vala_assert (_int_equal (_tmp18_, &_tmp19_) == TRUE, "foo[1] == 126");
+ _tmp20_ = foo[2];
+ _tmp21_ = 4709;
+ _vala_assert (_int_equal (_tmp20_, &_tmp21_) == TRUE, "foo[2] == 4709");
+ foo = (_vala_array_free (foo, foo_length1, (GDestroyNotify) g_free), NULL);
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
+static void
+_vala_array_destroy (gpointer array,
+ gssize array_length,
+ GDestroyNotify destroy_func)
+{
+ if ((array != NULL) && (destroy_func != NULL)) {
+ gssize i;
+ for (i = 0; i < array_length; i = i + 1) {
+ if (((gpointer*) array)[i] != NULL) {
+ destroy_func (((gpointer*) array)[i]);
+ }
+ }
+ }
+}
+
+static void
+_vala_array_free (gpointer array,
+ gssize array_length,
+ GDestroyNotify destroy_func)
+{
+ _vala_array_destroy (array, array_length, destroy_func);
+ g_free (array);
+}
+
--- /dev/null
+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);
+}
--- /dev/null
+/* basic_types_string_array_append.c generated by valac, the Vala compiler
+ * generated from basic_types_string_array_append.vala, do not modify */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#define _g_free0(var) (var = (g_free (var), NULL))
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+static void _vala_main (void);
+static void _vala_array_destroy (gpointer array,
+ gssize array_length,
+ GDestroyNotify destroy_func);
+static void _vala_array_free (gpointer array,
+ gssize array_length,
+ GDestroyNotify destroy_func);
+
+static void
+_vala_main (void)
+{
+ gchar** foo = NULL;
+ gchar* _tmp0_;
+ gchar* _tmp1_;
+ gchar* _tmp2_;
+ gchar** _tmp3_;
+ gint foo_length1;
+ gint _foo_size_;
+ const gchar* _tmp4_;
+ gchar* _tmp5_;
+ const gchar* _tmp6_;
+ gchar* _tmp7_;
+ gchar* _tmp8_;
+ gchar* _tmp9_;
+ const gchar* _tmp10_;
+ gchar* _tmp11_;
+ gchar* _tmp12_;
+ gchar* _tmp13_;
+ gchar* _tmp14_;
+ gchar* _tmp15_;
+ const gchar* _tmp16_;
+ const gchar* _tmp17_;
+ const gchar* _tmp18_;
+ _tmp0_ = g_strdup ("foo");
+ _tmp1_ = g_strdup ("bar");
+ _tmp2_ = g_strdup ("foo bar");
+ _tmp3_ = g_new0 (gchar*, 3 + 1);
+ _tmp3_[0] = _tmp0_;
+ _tmp3_[1] = _tmp1_;
+ _tmp3_[2] = _tmp2_;
+ foo = _tmp3_;
+ foo_length1 = 3;
+ _foo_size_ = foo_length1;
+ _tmp4_ = foo[0];
+ _tmp5_ = g_strconcat (_tmp4_, "abc", NULL);
+ _g_free0 (foo[0]);
+ foo[0] = _tmp5_;
+ _tmp6_ = foo[1];
+ _tmp7_ = g_strdup_printf ("%i", 123);
+ _tmp8_ = _tmp7_;
+ _tmp9_ = g_strconcat (_tmp6_, _tmp8_, NULL);
+ _g_free0 (foo[1]);
+ foo[1] = _tmp9_;
+ _g_free0 (_tmp8_);
+ _tmp10_ = foo[2];
+ _tmp11_ = g_strdup_printf ("%i", 123);
+ _tmp12_ = _tmp11_;
+ _tmp13_ = g_strconcat (" abc", _tmp12_, NULL);
+ _tmp14_ = _tmp13_;
+ _tmp15_ = g_strconcat (_tmp10_, _tmp14_, NULL);
+ _g_free0 (foo[2]);
+ foo[2] = _tmp15_;
+ _g_free0 (_tmp14_);
+ _g_free0 (_tmp12_);
+ _tmp16_ = foo[0];
+ _vala_assert (g_strcmp0 (_tmp16_, "fooabc") == 0, "foo[0] == \"fooabc\"");
+ _tmp17_ = foo[1];
+ _vala_assert (g_strcmp0 (_tmp17_, "bar123") == 0, "foo[1] == \"bar123\"");
+ _tmp18_ = foo[2];
+ _vala_assert (g_strcmp0 (_tmp18_, "foo bar abc123") == 0, "foo[2] == \"foo bar abc123\"");
+ foo = (_vala_array_free (foo, foo_length1, (GDestroyNotify) g_free), NULL);
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
+static void
+_vala_array_destroy (gpointer array,
+ gssize array_length,
+ GDestroyNotify destroy_func)
+{
+ if ((array != NULL) && (destroy_func != NULL)) {
+ gssize i;
+ for (i = 0; i < array_length; i = i + 1) {
+ if (((gpointer*) array)[i] != NULL) {
+ destroy_func (((gpointer*) array)[i]);
+ }
+ }
+ }
+}
+
+static void
+_vala_array_free (gpointer array,
+ gssize array_length,
+ GDestroyNotify destroy_func)
+{
+ _vala_array_destroy (array, array_length, destroy_func);
+ g_free (array);
+}
+
--- /dev/null
+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");
+}
+
}
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;
}
}
}
- } 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 ());