authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-14 11:19:50+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-14 11:19:50+03:00
log89f2923a8aad5119b1506c3b8e08464e132c228e
tree4c493eeb1af93701fa57a541d1bac56a1d145e02
parentac319b27348f60e37f3f1b478fee00202280715f
signaturelock-open Commit is signed but in an unrecognized format.

recover from missing semicolon


2 files changed, 30 insertions(+), 3 deletions(-)

lib/std/zig/parse.zig+13-3
...@@ -667,7 +667,12 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No...@@ -667,7 +667,12 @@ fn parseStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?*No
667 if (try parseLabeledStatement(arena, it, tree)) |node| return node;667 if (try parseLabeledStatement(arena, it, tree)) |node| return node;
668 if (try parseSwitchExpr(arena, it, tree)) |node| return node;668 if (try parseSwitchExpr(arena, it, tree)) |node| return node;
669 if (try parseAssignExpr(arena, it, tree)) |node| {669 if (try parseAssignExpr(arena, it, tree)) |node| {
670 _ = try expectToken(it, tree, .Semicolon);670 _ = eatToken(it, .Semicolon) orelse {
671 try tree.errors.push(.{
672 .ExpectedToken = .{ .token = it.index, .expected_id = .Semicolon },
673 });
674 // pretend we saw a semicolon and continue parsing
675 };
671 return node;676 return node;
672 }677 }
673678
...@@ -911,7 +916,12 @@ fn parseWhileStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No...@@ -911,7 +916,12 @@ fn parseWhileStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
911fn parseBlockExprStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {916fn parseBlockExprStatement(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
912 if (try parseBlockExpr(arena, it, tree)) |node| return node;917 if (try parseBlockExpr(arena, it, tree)) |node| return node;
913 if (try parseAssignExpr(arena, it, tree)) |node| {918 if (try parseAssignExpr(arena, it, tree)) |node| {
914 _ = try expectToken(it, tree, .Semicolon);919 _ = eatToken(it, .Semicolon) orelse {
920 try tree.errors.push(.{
921 .ExpectedToken = .{ .token = it.index, .expected_id = .Semicolon },
922 });
923 // pretend we saw a semicolon and continue parsing
924 };
915 return node;925 return node;
916 }926 }
917 return null;927 return null;
...@@ -3072,7 +3082,7 @@ fn parseDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.D...@@ -3072,7 +3082,7 @@ fn parseDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node.D
3072}3082}
30733083
3074/// Eat a single-line doc comment on the same line as another node3084/// Eat a single-line doc comment on the same line as another node
3075fn parseAppendedDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree, after_token: TokenIndex) Allocator.Error!?*Node.DocComment {3085fn parseAppendedDocComment(arena: *Allocator, it: *TokenIterator, tree: *Tree, after_token: TokenIndex) !?*Node.DocComment {
3076 const comment_token = eatToken(it, .DocComment) orelse return null;3086 const comment_token = eatToken(it, .DocComment) orelse return null;
3077 if (tree.tokensOnSameLine(after_token, comment_token)) {3087 if (tree.tokensOnSameLine(after_token, comment_token)) {
3078 const node = try arena.create(Node.DocComment);3088 const node = try arena.create(Node.DocComment);
lib/std/zig/parser_test.zig+17
...@@ -102,6 +102,23 @@ test "recovery: invalid extern/inline" {...@@ -102,6 +102,23 @@ test "recovery: invalid extern/inline" {
102 });102 });
103}103}
104104
105test "recovery: missing semicolon" {
106 try testError(
107 \\test "" {
108 \\ comptime a && b
109 \\ c && d
110 \\ @foo
111 \\}
112 , &[_]Error{
113 .InvalidAnd,
114 .ExpectedToken,
115 .InvalidAnd,
116 .ExpectedToken,
117 .ExpectedParamList,
118 .ExpectedToken,
119 });
120}
121
105test "zig fmt: top-level fields" {122test "zig fmt: top-level fields" {
106 try testCanonical(123 try testCanonical(
107 \\a: did_you_know,124 \\a: did_you_know,