[vala/staging: 9/9] vala: Handle non-null in coalescing expression



commit 50748111d26d839cb8244e1bfc0c6924305a90b1
Author: Marvin W <git larma de>
Date:   Tue Apr 11 17:19:58 2017 +0200

    vala: Handle non-null in coalescing expression
    
    https://bugzilla.gnome.org/show_bug.cgi?id=611223

 tests/Makefile.am                |    8 +++++++-
 tests/nullability/bug611223.vala |    7 +++++++
 vala/valabinaryexpression.vala   |   33 +++++++++++++++++++++++++++++----
 3 files changed, 43 insertions(+), 5 deletions(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e368b6b..2a2f4d4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -286,11 +286,17 @@ TESTS = \
        annotations/description.vala \
        $(NULL)
 
-check-TESTS: $(TESTS)
+NON_NULL_TESTS = \
+       nullability/bug611223.vala \
+       $(NULL)
+
+check-TESTS: $(TESTS) $(NON_NULL_TESTS)
        @EXEEXT=$(EXEEXT) EXEEXT=$(EXEEXT) CFLAGS='$(CFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' 
$(srcdir)/testrunner.sh $(TESTS)
+       @EXEEXT=$(EXEEXT) EXEEXT=$(EXEEXT) CFLAGS='$(CFLAGS)' CPPFLAGS='$(CPPFLAGS)' LDFLAGS='$(LDFLAGS)' 
VALAFLAGS="--enable-experimental-non-null" $(srcdir)/testrunner.sh $(NON_NULL_TESTS)
 
 EXTRA_DIST = \
        testrunner.sh \
        $(TESTS) \
+       $(NON_NULL_TESTS) \
        $(NULL)
 
diff --git a/tests/nullability/bug611223.vala b/tests/nullability/bug611223.vala
new file mode 100644
index 0000000..9fbf30c
--- /dev/null
+++ b/tests/nullability/bug611223.vala
@@ -0,0 +1,7 @@
+void main() {
+       string? nullable = null;
+       string non_null = nullable ?? "";
+       string? some_null = nullable ?? null;
+       string also_non_null = null ?? non_null;
+       string really_non_null = non_null ?? nullable;
+}
diff --git a/vala/valabinaryexpression.vala b/vala/valabinaryexpression.vala
index 82e6053..19287da 100644
--- a/vala/valabinaryexpression.vala
+++ b/vala/valabinaryexpression.vala
@@ -210,12 +210,31 @@ public class Vala.BinaryExpression : Expression {
                        }
 
                        DataType local_type = null;
-                       if (left.value_type != null) {
+                       bool cast_non_null = false;
+                       if (left.value_type is NullType && right.value_type != null) {
+                               Report.warning (left.source_reference, "left operand is always null");
+                               local_type = right.value_type.copy ();
+                               local_type.nullable = true;
+                               if (!right.value_type.nullable) {
+                                       cast_non_null = true;
+                               }
+                       } else if (left.value_type != null) {
                                local_type = left.value_type.copy ();
                                if (right.value_type != null && right.value_type.value_owned) {
                                        // value owned if either left or right is owned
                                        local_type.value_owned = true;
                                }
+                               if (context.experimental_non_null) {
+                                       if (!local_type.nullable) {
+                                               Report.warning (left.source_reference, "left operand is never 
null");
+                                               if (right.value_type != null && right.value_type.nullable) {
+                                                       local_type.nullable = true;
+                                                       cast_non_null = true;
+                                               }
+                                       } else if (right.value_type != null && !right.value_type.nullable) {
+                                               cast_non_null = true;
+                                       }
+                               }
                        } else if (right.value_type != null) {
                                local_type = right.value_type.copy ();
                        }
@@ -246,10 +265,16 @@ public class Vala.BinaryExpression : Expression {
                                return false;
                        }
 
-                       var temp_access = SemanticAnalyzer.create_temp_access (local, target_type);
-                       temp_access.check (context);
+                       var replace_expr = SemanticAnalyzer.create_temp_access (local, target_type);
+                       if (cast_non_null && replace_expr.target_type != null) {
+                               var cast = new CastExpression.non_null (replace_expr, source_reference);
+                               cast.target_type = replace_expr.target_type.copy ();
+                               cast.target_type.nullable = false;
+                               replace_expr = cast;
+                       }
+                       replace_expr.check (context);
 
-                       parent_node.replace_expression (this, temp_access);
+                       parent_node.replace_expression (this, replace_expr);
 
                        return true;
                }


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