summaryrefslogtreecommitdiff
path: root/vala/valaparser.vala
diff options
context:
space:
mode:
authorNick Schrader <nick.schrader@mailbox.org>2020-03-27 13:12:09 -0300
committerRico Tzschichholz <ricotz@ubuntu.com>2020-06-02 13:02:42 +0200
commit35f72f3ecdf0d61d0e67cd4f72c29fee2c3c9a55 (patch)
tree07beb54a046a765a3e19ed2ad138dc166e74a5e9 /vala/valaparser.vala
parented320c6260bfa369f64f41450bc48fd5b664809a (diff)
downloadvala-35f72f3ecdf0d61d0e67cd4f72c29fee2c3c9a55.tar.gz
Add support for "with" statement
Creates data type scoped blocks which allow implicit member access to the given expression or declaration statement. with (expr) { ...; } Within the with-block the expression's members can be directly accessed without the member access operator. Members may hide local, class and instance varibales with the same name. Instance variables are still accessible through this. A local variable can be directly declared in the with statement header. Hidden local and class variables are currently not directly accessible (using this for class members generates the expected warning). Fixes https://gitlab.gnome.org/GNOME/vala/issues/327
Diffstat (limited to 'vala/valaparser.vala')
-rw-r--r--vala/valaparser.vala44
1 files changed, 43 insertions, 1 deletions
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 2d7fb3e3c..191bc75d5 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -266,6 +266,7 @@ public class Vala.Parser : CodeVisitor {
case TokenType.VOLATILE:
case TokenType.WEAK:
case TokenType.WHILE:
+ case TokenType.WITH:
case TokenType.YIELD:
next ();
return;
@@ -1630,6 +1631,9 @@ public class Vala.Parser : CodeVisitor {
case TokenType.DELETE:
stmt = parse_delete_statement ();
break;
+ case TokenType.WITH:
+ stmt = parse_with_statement ();
+ break;
case TokenType.VAR:
is_decl = true;
parse_local_variable_declarations (block);
@@ -1919,7 +1923,7 @@ public class Vala.Parser : CodeVisitor {
expect (TokenType.SEMICOLON);
}
- LocalVariable parse_local_variable (DataType? variable_type) throws ParseError {
+ LocalVariable parse_local_variable (DataType? variable_type, bool expect_initializer = false) throws ParseError {
var begin = get_location ();
string id = parse_identifier ();
var type = parse_inline_array_type (variable_type);
@@ -1928,6 +1932,10 @@ public class Vala.Parser : CodeVisitor {
Expression initializer = null;
if (accept (TokenType.ASSIGN)) {
initializer = parse_expression ();
+ } else if (expect_initializer) {
+ report_parse_error (new ParseError.SYNTAX ("expected initializer"));
+ prev ();
+ initializer = new InvalidExpression ();
}
return new LocalVariable (type, id, initializer, src);
}
@@ -2275,6 +2283,40 @@ public class Vala.Parser : CodeVisitor {
return new DeleteStatement (expr, src);
}
+ Statement? parse_with_statement () throws ParseError {
+ var begin = get_location ();
+ expect (TokenType.WITH);
+ expect (TokenType.OPEN_PARENS);
+ var expr_or_decl = get_location ();
+
+ LocalVariable? local = null;
+
+ // Try "with (expr)"
+ Expression expr = parse_expression ();
+ if (!accept (TokenType.CLOSE_PARENS)) {
+ // Try "with (var identifier = expr)"
+ rollback (expr_or_decl);
+ DataType variable_type;
+ if (accept (TokenType.UNOWNED) && accept (TokenType.VAR)) {
+ variable_type = new VarType (false);
+ } else {
+ rollback (expr_or_decl);
+ if (accept (TokenType.VAR)) {
+ variable_type = new VarType ();
+ } else {
+ variable_type = parse_type (true, true);
+ }
+ }
+ local = parse_local_variable (variable_type, true);
+ expr = local.initializer;
+ expect (TokenType.CLOSE_PARENS);
+ }
+
+ var src = get_src (begin);
+ var body = parse_embedded_statement ("with", false);
+ return new WithStatement (local, expr, body, src);
+ }
+
string parse_attribute_value () throws ParseError {
switch (current ()) {
case TokenType.NULL: