[vala/0.42] codegen: Move implicit GValue cast for comparison to BinaryExpression



commit 5bc2b532e4f07aa107bd174d36af75254b2d542c
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Mon Mar 25 12:46:15 2019 +0100

    codegen: Move implicit GValue cast for comparison to BinaryExpression
    
    Handle "==" and "!=" only as it was done before.
    
    This generates correct c-code for boxed simple-types and will perform
    value-based comparisons.
    
    See https://bugzilla.gnome.org/show_bug.cgi?id=585063

 codegen/valaccodebasemodule.vala              | 17 -----
 tests/Makefile.am                             |  1 +
 tests/structs/gvalue-implicit-comparison.vala | 98 +++++++++++++++++++++++++++
 vala/valabinaryexpression.vala                | 20 ++++++
 4 files changed, 119 insertions(+), 17 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index f2c2fc61f..114bbaa3f 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2806,23 +2806,6 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                var left_type_as_struct = left_type.data_type as Struct;
                var right_type_as_struct = right_type.data_type as Struct;
 
-               // GValue support
-               var valuecast = try_cast_value_to_type (cleft, left_type, right_type);
-               if (valuecast != null) {
-                       cleft = valuecast;
-                       left_type = right_type;
-                       make_comparable_cexpression (ref left_type, ref cleft, ref right_type, ref cright);
-                       return;
-               }
-
-               valuecast = try_cast_value_to_type (cright, right_type, left_type);
-               if (valuecast != null) {
-                       cright = valuecast;
-                       right_type = left_type;
-                       make_comparable_cexpression (ref left_type, ref cleft, ref right_type, ref cright);
-                       return;
-               }
-
                if (left_type.data_type is Class && !((Class) left_type.data_type).is_compact &&
                    right_type.data_type is Class && !((Class) right_type.data_type).is_compact) {
                        var left_cl = (Class) left_type.data_type;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 48939cfb9..b7bbed0f8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -206,6 +206,7 @@ TESTS = \
        structs/struct-no-gtype.vala \
        structs/structs.vala \
        structs/gvalue.vala \
+       structs/gvalue-implicit-comparison.vala \
        structs/bug530605.vala \
        structs/bug572091.vala \
        structs/bug583603.vala \
diff --git a/tests/structs/gvalue-implicit-comparison.vala b/tests/structs/gvalue-implicit-comparison.vala
new file mode 100644
index 000000000..91865fbcf
--- /dev/null
+++ b/tests/structs/gvalue-implicit-comparison.vala
@@ -0,0 +1,98 @@
+Value get_value (Value v) {
+    return v;
+}
+
+Value? get_nullable_value (Value? v) {
+    return v;
+}
+
+void main () {
+       {
+               Value v = Value (typeof (int));
+               v.set_int (42);
+               if (v == 42) {
+               } else {
+                       assert_not_reached ();
+               }
+               if (42 == v) {
+               } else {
+                       assert_not_reached ();
+               }
+       }
+       {
+               Value? v = Value (typeof (int));
+               v.set_int (42);
+               if (v == 42) {
+               } else {
+                       assert_not_reached ();
+               }
+               if (42 == v) {
+               } else {
+                       assert_not_reached ();
+               }
+       }
+       {
+               Value v = Value (typeof (string));
+               v.set_string ("foo");
+               if (v == "foo") {
+               } else {
+                       assert_not_reached ();
+               }
+               if ("foo" == v) {
+               } else {
+                       assert_not_reached ();
+               }
+       }
+       {
+               Value? v = Value (typeof (string));
+               v.set_string ("foo");
+               if (v == "foo") {
+               } else {
+                       assert_not_reached ();
+               }
+               if ("foo" == v) {
+               } else {
+                       assert_not_reached ();
+               }
+       }
+       {
+               Value v = Value (typeof (int));
+               v.set_int (23);
+               if (get_value (v) != 23) {
+                       assert_not_reached ();
+               }
+               if (23 != get_value (v)) {
+                       assert_not_reached ();
+               }
+       }
+       {
+               Value? v = Value (typeof (int));
+               v.set_int (23);
+               if (get_nullable_value (v) != 23) {
+                       assert_not_reached ();
+               }
+               if (23 != get_nullable_value (v)) {
+                       assert_not_reached ();
+               }
+       }
+       {
+               Value v = Value (typeof (string));
+               v.set_string ("bar");
+               if (get_value (v) != "bar") {
+                       assert_not_reached ();
+               }
+               if ("bar" != get_value (v)) {
+                       assert_not_reached ();
+               }
+       }
+       {
+               Value? v = Value (typeof (string));
+               v.set_string ("bar");
+               if (get_nullable_value (v) != "bar") {
+                       assert_not_reached ();
+               }
+               if ("bar" != get_nullable_value (v)) {
+                       assert_not_reached ();
+               }
+       }
+}
diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala
index beebe118d..a3241c71c 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -463,6 +463,26 @@ public class Vala.BinaryExpression : Expression {
                           || operator == BinaryOperator.INEQUALITY) {
                        /* relational operation */
 
+                       // Implicit cast for comparsion expression of GValue with other type
+                       var gvalue_type = context.analyzer.gvalue_type.data_type;
+                       if ((left.target_type.data_type == gvalue_type && right.target_type.data_type != 
gvalue_type)
+                           || (left.target_type.data_type != gvalue_type && right.target_type.data_type == 
gvalue_type)) {
+                               Expression gvalue_expr;
+                               DataType target_type;
+                               if (left.target_type.data_type == gvalue_type) {
+                                       gvalue_expr = left;
+                                       target_type = right.target_type;
+                               } else {
+                                       gvalue_expr = right;
+                                       target_type = left.target_type;
+                               }
+
+                               var cast_expr = new CastExpression (gvalue_expr, target_type, 
gvalue_expr.source_reference);
+                               replace_expression (gvalue_expr, cast_expr);
+                               checked = false;
+                               return check (context);
+                       }
+
                        if (!right.value_type.compatible (left.value_type)
                            && !left.value_type.compatible (right.value_type)) {
                                Report.error (source_reference, "Equality operation: `%s' and `%s' are 
incompatible".printf (right.value_type.to_string (), left.value_type.to_string ()));


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