[vala/wip/ricotz/lsp-rev: 8/13] parser: Handle exprs before try block



commit 828ea825fd9e35ad0bcb6c1eaa88f543c6043ec3
Author: Princeton Ferro <princetonferro gmail com>
Date:   Sun Jan 26 00:40:16 2020 -0500

    parser: Handle exprs before try block
    
    In keep-going mode, handle incomplete member access expressions before
    special blocks like `try', by attempting to parse them as
    expressions rather than declaration statements.

 vala/valaparser.vala | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)
---
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index c0c0a7192..7d3dab267 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -1630,7 +1630,7 @@ public class Vala.Parser : CodeVisitor {
                                        stmt = parse_expression_statement ();
                                        break;
                                default:
-                                       bool is_expr = is_expression ();
+                                       bool is_expr = is_expression (true);
                                        if (is_expr) {
                                                stmt = parse_expression_statement ();
                                        } else {
@@ -1654,7 +1654,7 @@ public class Vala.Parser : CodeVisitor {
                }
        }
 
-       bool is_expression () throws ParseError {
+       bool is_expression (bool in_block = false) throws ParseError {
                if (current () == TokenType.OPEN_PARENS) {
                        return !is_inner_array_type ();
                }
@@ -1700,6 +1700,15 @@ public class Vala.Parser : CodeVisitor {
                case TokenType.OP_PTR:
                        rollback (begin);
                        return true;
+               case TokenType.OPEN_BRACE:
+                       rollback (begin);
+                       if (context.keep_going) {
+                               // if we reach the start of a block, and we've already
+                               // ruled out other special blocks (like `try'),
+                               // then this is probably an incomplete expression
+                               return in_block;
+                       }
+                       return false;
                default:
                        rollback (begin);
                        return false;
@@ -1811,7 +1820,7 @@ public class Vala.Parser : CodeVisitor {
                case TokenType.NEW:
                        return parse_expression_statement ();
                default:
-                       if (is_expression ()) {
+                       if (is_expression (true)) {
                                return parse_expression_statement ();
                        } else {
                                throw new ParseError.SYNTAX ("embedded statement cannot be declaration");
@@ -1960,7 +1969,16 @@ public class Vala.Parser : CodeVisitor {
                var begin = get_location ();
                var expr = parse_statement_expression ();
                var src = get_src (begin);
+               prev ();
+               var prev_token = current ();
+               next ();
+               var token = current ();
                expect (TokenType.SEMICOLON);
+               if (context.keep_going && token == TokenType.OPEN_BRACE && prev_token == TokenType.TRY) {
+                       // if we've hit an open brace instead of a semicolon, and the previous token was
+                       // a try, then perform some minor recovery:
+                       prev ();
+               }
                return new ExpressionStatement (expr, src);
        }
 


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