[vala/staging] vala: Correctly replace "in" expression in pre-/postconditions of method



commit 0a89cce6990aae413cb42e3d9ce79070f925ec5b
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Mon Dec 20 20:40:30 2021 +0100

    vala: Correctly replace "in" expression in pre-/postconditions of method
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/1269

 tests/Makefile.am                                  |  1 +
 .../methods/prepostconditions-contains.c-expected  | 83 ++++++++++++++++++++++
 tests/methods/prepostconditions-contains.vala      | 13 ++++
 vala/valabinaryexpression.vala                     |  1 +
 vala/valamethod.vala                               | 17 +++++
 5 files changed, 115 insertions(+)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ef7444ba0..b3e51dc7b 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -189,6 +189,7 @@ TESTS = \
        methods/preconditions-temp-variables.vala \
        methods/prepostconditions.vala \
        methods/prepostconditions-captured.vala \
+       methods/prepostconditions-contains.vala \
        methods/postconditions.vala \
        methods/postconditions-temp-variables.vala \
        methods/return-unowned-delegate.vala \
diff --git a/tests/methods/prepostconditions-contains.c-expected 
b/tests/methods/prepostconditions-contains.c-expected
new file mode 100644
index 000000000..f1cd71e0c
--- /dev/null
+++ b/tests/methods/prepostconditions-contains.c-expected
@@ -0,0 +1,83 @@
+/* methods_prepostconditions_contains.c generated by valac, the Vala compiler
+ * generated from methods_prepostconditions_contains.vala, do not modify */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#if !defined(VALA_EXTERN)
+#if defined(_MSC_VER)
+#define VALA_EXTERN __declspec(dllexport) extern
+#elif __GNUC__ >= 4
+#define VALA_EXTERN __attribute__((visibility("default"))) extern
+#else
+#define VALA_EXTERN extern
+#endif
+#endif
+
+#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);
+
+VALA_EXTERN void foo (const gchar* s);
+static gboolean _vala_string_array_contains (const gchar* * stack,
+                                      gssize stack_length,
+                                      const const gchar* needle);
+VALA_EXTERN gchar* bar (void);
+static void _vala_main (void);
+
+const gchar* array[3] = {"foo", "bar", "manam"};
+
+static gboolean
+_vala_string_array_contains (const gchar* * stack,
+                             gssize stack_length,
+                             const const gchar* needle)
+{
+       gssize i;
+       for (i = 0; i < stack_length; i++) {
+               if (g_strcmp0 (stack[i], needle) == 0) {
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
+void
+foo (const gchar* s)
+{
+       g_return_if_fail (s != NULL);
+       _vala_return_if_fail (_vala_string_array_contains (array, G_N_ELEMENTS (array), s), "s in array");
+}
+
+gchar*
+bar (void)
+{
+       gchar* _tmp0_;
+       gchar* result = NULL;
+       _tmp0_ = g_strdup ("manam");
+       result = _tmp0_;
+       _vala_warn_if_fail (_vala_string_array_contains (array, G_N_ELEMENTS (array), result), "result in 
array");
+       return result;
+}
+
+static void
+_vala_main (void)
+{
+       gchar* _tmp0_;
+       gchar* _tmp1_;
+       foo ("bar");
+       _tmp0_ = bar ();
+       _tmp1_ = _tmp0_;
+       _g_free0 (_tmp1_);
+}
+
+int
+main (int argc,
+      char ** argv)
+{
+       _vala_main ();
+       return 0;
+}
+
diff --git a/tests/methods/prepostconditions-contains.vala b/tests/methods/prepostconditions-contains.vala
new file mode 100644
index 000000000..9135da3c7
--- /dev/null
+++ b/tests/methods/prepostconditions-contains.vala
@@ -0,0 +1,13 @@
+const string[] array = { "foo", "bar", "manam" };
+
+void foo (string s) requires (s in array) {
+}
+
+string bar () ensures (result in array) {
+       return "manam";
+}
+
+void main () {
+       foo ("bar");
+       bar ();
+}
diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala
index 6545e1cff..7f5f12442 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -607,6 +607,7 @@ public class Vala.BinaryExpression : Expression {
                                var contains_call = new MethodCall (new MemberAccess (right, "contains", 
source_reference), source_reference);
                                contains_call.add_argument (left);
                                parent_node.replace_expression (this, contains_call);
+                               value_type = context.analyzer.bool_type;
                                return contains_call.check (context);
                        }
 
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index 5eb1b9a95..27e417291 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -577,6 +577,23 @@ public class Vala.Method : Subroutine, Callable {
                }
        }
 
+       public override void replace_expression (Expression old_node, Expression new_node) {
+               if (preconditions != null) {
+                       var index = preconditions.index_of (old_node);
+                       if (index >= 0) {
+                               preconditions[index] = new_node;
+                               new_node.parent_node = this;
+                       }
+               }
+               if (postconditions != null) {
+                       var index = postconditions.index_of (old_node);
+                       if (index >= 0) {
+                               postconditions[index] = new_node;
+                               new_node.parent_node = this;
+                       }
+               }
+       }
+
        public override void replace_type (DataType old_type, DataType new_type) {
                if (base_interface_type == old_type) {
                        base_interface_type = new_type;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]