[vala/staging] Support explicit nullable var-type declarations



commit 4f2ef8fa3c391451f0ea788ad6e8ea6c15ef0430
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Thu Apr 15 16:49:14 2021 +0200

    Support explicit nullable var-type declarations
    
        var? foo = "foo";
        unowned var? bar = "bar";
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/1146

 tests/Makefile.am                   |  2 ++
 tests/nullability/var-type.vala     | 11 +++++++++++
 tests/parser/var-type-nullable.vala | 16 ++++++++++++++++
 vala/valaforeachstatement.vala      |  8 ++++++++
 vala/valalocalvariable.vala         |  4 ++++
 vala/valaparser.vala                |  6 ++++++
 vala/valavartype.vala               |  4 +++-
 7 files changed, 50 insertions(+), 1 deletion(-)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 1b3d47831..5b2610dd6 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -879,6 +879,7 @@ TESTS = \
        parser/using-ambiguous-reference.test \
        parser/using-directive.vala \
        parser/using-invalid-namespace.test \
+       parser/var-type-nullable.vala \
        parser/with-embedded.vala \
        parser/with-empty.vala \
        parser/with-invalid-declaration.test \
@@ -1151,6 +1152,7 @@ TESTS = \
        nullability/method-return-invalid-convert.test \
        nullability/string-concat.test \
        nullability/with-non-null.test \
+       nullability/var-type.vala \
        version/since-constant.test \
        version/since-field.test \
        version/since-local-variable.test \
diff --git a/tests/nullability/var-type.vala b/tests/nullability/var-type.vala
new file mode 100644
index 000000000..3497d8606
--- /dev/null
+++ b/tests/nullability/var-type.vala
@@ -0,0 +1,11 @@
+void main () {
+       {
+               unowned var? foo = "foo";
+               assert (foo != null);
+       }
+       {
+               foreach (unowned var? foo in new string[] { "foo", "bar" }) {
+                       assert (foo != null);
+               }
+       }
+}
diff --git a/tests/parser/var-type-nullable.vala b/tests/parser/var-type-nullable.vala
new file mode 100644
index 000000000..fb3256970
--- /dev/null
+++ b/tests/parser/var-type-nullable.vala
@@ -0,0 +1,16 @@
+void main () {
+       {
+               var? foo = "foo";
+       }
+       {
+               unowned var? foo = "foo";
+       }
+       {
+               foreach (var? foo in new string[] { "foo", "bar" }) {
+               }
+       }
+       {
+               foreach (unowned var? foo in new string[] { "foo", "bar" }) {
+               }
+       }
+}
diff --git a/vala/valaforeachstatement.vala b/vala/valaforeachstatement.vala
index bea6c4e93..0af0b52ba 100644
--- a/vala/valaforeachstatement.vala
+++ b/vala/valaforeachstatement.vala
@@ -336,12 +336,16 @@ public class Vala.ForeachStatement : Block {
                // analyze element type
                if (type_reference is VarType) {
                        // var type
+                       bool nullable = type_reference.nullable;
                        bool value_owned = type_reference.value_owned;
                        type_reference = element_type.copy ();
                        // FIXME Only follows "unowned var" otherwise inherit ownership of element-type
                        if (!value_owned) {
                                type_reference.value_owned = false;
                        }
+                       if (nullable) {
+                               type_reference.nullable = true;
+                       }
                } else if (!element_type.compatible (type_reference)) {
                        error = true;
                        Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'", 
element_type.to_string (), type_reference.to_string ());
@@ -359,12 +363,16 @@ public class Vala.ForeachStatement : Block {
                // analyze element type
                if (type_reference is VarType) {
                        // var type
+                       bool nullable = type_reference.nullable;
                        bool value_owned = type_reference.value_owned;
                        type_reference = element_type.copy ();
                        // FIXME Only follows "unowned var" otherwise inherit ownership of element-type
                        if (!value_owned) {
                                type_reference.value_owned = false;
                        }
+                       if (nullable) {
+                               type_reference.nullable = true;
+                       }
                } else if (!element_type.compatible (type_reference)) {
                        error = true;
                        Report.error (source_reference, "Foreach: Cannot convert from `%s' to `%s'", 
element_type.to_string (), type_reference.to_string ());
diff --git a/vala/valalocalvariable.vala b/vala/valalocalvariable.vala
index eeb8e912b..e6d15cf19 100644
--- a/vala/valalocalvariable.vala
+++ b/vala/valalocalvariable.vala
@@ -154,10 +154,14 @@ public class Vala.LocalVariable : Variable {
                                return false;
                        }
 
+                       bool nullable = variable_type.nullable;
                        bool value_owned = variable_type.value_owned;
                        variable_type = initializer.value_type.copy ();
                        variable_type.value_owned = value_owned;
                        variable_type.floating_reference = false;
+                       if (nullable) {
+                               variable_type.nullable = true;
+                       }
 
                        initializer.target_type = variable_type;
                        variable_type.check (context);
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 49336c94c..9ecc96e9b 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -1944,10 +1944,12 @@ public class Vala.Parser : CodeVisitor {
                DataType variable_type;
                if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) {
                        variable_type = new VarType (false);
+                       variable_type.nullable = accept (TokenType.INTERR);
                } else {
                        rollback (begin);
                        if (accept (TokenType.VAR)) {
                                variable_type = new VarType ();
+                               variable_type.nullable = accept (TokenType.INTERR);
                        } else {
                                variable_type = parse_type (true, true);
                        }
@@ -2211,10 +2213,12 @@ public class Vala.Parser : CodeVisitor {
                DataType type;
                if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) {
                        type = new VarType (false);
+                       type.nullable = accept (TokenType.INTERR);
                } else {
                        rollback (var_or_type);
                        if (accept (TokenType.VAR)) {
                                type = new VarType ();
+                               type.nullable = accept (TokenType.INTERR);
                        } else {
                                type = parse_type (true, true);
                                if (accept (TokenType.IN)) {
@@ -2380,10 +2384,12 @@ public class Vala.Parser : CodeVisitor {
                        DataType variable_type;
                        if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) {
                                variable_type = new VarType (false);
+                               variable_type.nullable = accept (TokenType.INTERR);
                        } else {
                                rollback (expr_or_decl);
                                if (accept (TokenType.VAR)) {
                                        variable_type = new VarType ();
+                                       variable_type.nullable = accept (TokenType.INTERR);
                                } else {
                                        variable_type = parse_type (true, true);
                                }
diff --git a/vala/valavartype.vala b/vala/valavartype.vala
index dada3ca32..be97e1752 100644
--- a/vala/valavartype.vala
+++ b/vala/valavartype.vala
@@ -33,6 +33,8 @@ public class Vala.VarType : DataType {
        }
 
        public override DataType copy () {
-               return new VarType (value_owned);
+               var result = new VarType (value_owned);
+               result.nullable = nullable;
+               return result;
        }
 }


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