]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Support "unowned var" to declare local variables
authorRico Tzschichholz <ricotz@ubuntu.com>
Thu, 3 Oct 2019 18:42:58 +0000 (20:42 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Tue, 5 Nov 2019 21:52:00 +0000 (22:52 +0100)
Based on patch by Aaron Andersen

Fixes https://gitlab.gnome.org/GNOME/vala/issues/152

tests/Makefile.am
tests/parser/local-variable.vala [new file with mode: 0644]
vala/Makefile.am
vala/valalocalvariable.vala
vala/valaparser.vala
vala/valavartype.vala [new file with mode: 0644]

index daf29e9dc59ee917a4c377431218b7a53a646185..757cc0851494349199c323cdad571d8af76b2ba6 100644 (file)
@@ -586,6 +586,7 @@ TESTS = \
        parser/function-syntax-error.test \
        parser/inner-array-size.test \
        parser/invalid-brace.test \
+       parser/local-variable.vala \
        parser/lock-statement.vala \
        parser/main-block.vala \
        parser/method-no-abstract-override.test \
diff --git a/tests/parser/local-variable.vala b/tests/parser/local-variable.vala
new file mode 100644 (file)
index 0000000..fc22135
--- /dev/null
@@ -0,0 +1,10 @@
+void main () {
+       {
+               var foo = "foo";
+               var bar = 42;
+       }
+       {
+               unowned var foo = "foo";
+               unowned var bar = 42;
+       }
+}
index c6aed1c5453d4b455d3b7ea3f915da85e988cd78..78e4c93909e7b23f166b9174ff780bffca153c51 100644 (file)
@@ -177,6 +177,7 @@ libvala_la_VALASOURCES = \
        valausingdirective.vala \
        valavaluetype.vala \
        valavariable.vala \
+       valavartype.vala \
        valaversion.vala \
        valaversionattribute.vala \
        valavoidtype.vala \
index f6a39ba8e96ac0453ec5681ed6f13252e65e6c42..e334301c536061f3d31b2575b00a9e2302eccad2 100644 (file)
@@ -79,6 +79,10 @@ public class Vala.LocalVariable : Variable {
 
                checked = true;
 
+               if (variable_type == null) {
+                       variable_type = new VarType ();
+               }
+
                if (!context.experimental_non_null) {
                        // local reference variables are considered nullable
                        // except when using experimental non-null enhancements
@@ -92,7 +96,7 @@ public class Vala.LocalVariable : Variable {
                        }
                }
 
-               if (variable_type != null) {
+               if (!(variable_type is VarType)) {
                        if (variable_type is VoidType) {
                                error = true;
                                Report.error (source_reference, "'void' not supported as variable type");
@@ -122,7 +126,7 @@ public class Vala.LocalVariable : Variable {
                        }
                }
 
-               if (variable_type == null) {
+               if (variable_type is VarType) {
                        /* var type */
 
                        if (initializer == null) {
@@ -141,8 +145,9 @@ public class Vala.LocalVariable : Variable {
                                return false;
                        }
 
+                       bool value_owned = variable_type.value_owned;
                        variable_type = initializer.value_type.copy ();
-                       variable_type.value_owned = true;
+                       variable_type.value_owned = value_owned;
                        variable_type.floating_reference = false;
 
                        initializer.target_type = variable_type;
index fe4e1691573a4b86f973bfa73b8d47c2272d7dae..587f6b159e8c32f2ef76dac532c8a96e86e2ede9 100644 (file)
@@ -1784,14 +1784,19 @@ public class Vala.Parser : CodeVisitor {
        void parse_local_variable_declarations (Block block) throws ParseError {
                var begin = get_location ();
                DataType variable_type;
-               if (accept (TokenType.VAR)) {
-                       variable_type = null;
+               if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) {
+                       variable_type = new VarType (false);
                } else {
-                       variable_type = parse_type (true, true);
+                       rollback (begin);
+                       if (accept (TokenType.VAR)) {
+                               variable_type = new VarType ();
+                       } else {
+                               variable_type = parse_type (true, true);
+                       }
                }
                bool is_first = true;
                do {
-                       if (variable_type == null && accept (TokenType.OPEN_PARENS)) {
+                       if (variable_type is VarType && variable_type.value_owned && accept (TokenType.OPEN_PARENS)) {
                                // tuple
                                begin = get_location ();
 
diff --git a/vala/valavartype.vala b/vala/valavartype.vala
new file mode 100644 (file)
index 0000000..7187fc2
--- /dev/null
@@ -0,0 +1,38 @@
+/* valavartype.vala
+ *
+ * Copyright (C) 2019  Rico Tzschichholz
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Rico Tzschichholz <ricotz@ubuntu.com>
+ */
+
+/**
+ * A to be inferred data type.
+ */
+public class Vala.VarType : DataType {
+       public VarType (bool value_owned = true) {
+               this.value_owned = value_owned;
+       }
+
+       public override string to_qualified_string (Scope? scope) {
+               return (value_owned ? "var" : "unowned var");
+       }
+
+       public override DataType copy () {
+               return new VarType (value_owned);
+       }
+}