recover after invalid inline/extern
This commit is contained in:
@@ -129,6 +129,7 @@ pub const Error = union(enum) {
|
||||
ExpectedStatement: ExpectedStatement,
|
||||
ExpectedVarDeclOrFn: ExpectedVarDeclOrFn,
|
||||
ExpectedVarDecl: ExpectedVarDecl,
|
||||
ExpectedFn: ExpectedFn,
|
||||
ExpectedReturnType: ExpectedReturnType,
|
||||
ExpectedAggregateKw: ExpectedAggregateKw,
|
||||
UnattachedDocComment: UnattachedDocComment,
|
||||
@@ -179,6 +180,7 @@ pub const Error = union(enum) {
|
||||
.ExpectedStatement => |*x| return x.render(tokens, stream),
|
||||
.ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),
|
||||
.ExpectedVarDecl => |*x| return x.render(tokens, stream),
|
||||
.ExpectedFn => |*x| return x.render(tokens, stream),
|
||||
.ExpectedReturnType => |*x| return x.render(tokens, stream),
|
||||
.ExpectedAggregateKw => |*x| return x.render(tokens, stream),
|
||||
.UnattachedDocComment => |*x| return x.render(tokens, stream),
|
||||
@@ -231,6 +233,7 @@ pub const Error = union(enum) {
|
||||
.ExpectedStatement => |x| return x.token,
|
||||
.ExpectedVarDeclOrFn => |x| return x.token,
|
||||
.ExpectedVarDecl => |x| return x.token,
|
||||
.ExpectedFn => |x| return x.token,
|
||||
.ExpectedReturnType => |x| return x.token,
|
||||
.ExpectedAggregateKw => |x| return x.token,
|
||||
.UnattachedDocComment => |x| return x.token,
|
||||
@@ -280,6 +283,7 @@ pub const Error = union(enum) {
|
||||
pub const ExpectedStatement = SingleTokenError("Expected statement, found '{}'");
|
||||
pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found '{}'");
|
||||
pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{}'");
|
||||
pub const ExpectedFn = SingleTokenError("Expected function, found '{}'");
|
||||
pub const ExpectedReturnType = SingleTokenError("Expected 'var' or return type expression, found '{}'");
|
||||
pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Id.Keyword_struct.symbol() ++ "', '" ++ Token.Id.Keyword_union.symbol() ++ "', or '" ++ Token.Id.Keyword_enum.symbol() ++ "', found '{}'");
|
||||
pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{}'");
|
||||
|
||||
@@ -360,15 +360,17 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
|
||||
try tree.errors.push(.{
|
||||
.ExpectedSemiOrLBrace = .{ .token = it.index },
|
||||
});
|
||||
return null;
|
||||
return error.ParseError;
|
||||
}
|
||||
|
||||
if (extern_export_inline_token) |token| {
|
||||
if (tree.tokens.at(token).id == .Keyword_inline or
|
||||
tree.tokens.at(token).id == .Keyword_noinline)
|
||||
{
|
||||
putBackToken(it, token);
|
||||
return null;
|
||||
try tree.errors.push(.{
|
||||
.ExpectedFn = .{ .token = it.index },
|
||||
});
|
||||
return error.ParseError;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,10 +401,11 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
|
||||
}
|
||||
|
||||
if (extern_export_inline_token) |token| {
|
||||
if (lib_name) |string_literal_node|
|
||||
putBackToken(it, string_literal_node.cast(Node.StringLiteral).?.token);
|
||||
putBackToken(it, token);
|
||||
return null;
|
||||
try tree.errors.push(.{
|
||||
.ExpectedVarDeclOrFn = .{ .token = it.index },
|
||||
});
|
||||
// ignore this and try again;
|
||||
return error.ParseError;
|
||||
}
|
||||
|
||||
return parseUse(arena, it, tree) catch |err| switch (err) {
|
||||
|
||||
@@ -84,6 +84,21 @@ test "recovery: continue after invalid decl" {
|
||||
});
|
||||
}
|
||||
|
||||
test "recovery: invalid extern/inline" {
|
||||
try testError(
|
||||
\\inline test "" { a && b; }
|
||||
, &[_]Error{
|
||||
.ExpectedFn,
|
||||
.InvalidAnd,
|
||||
});
|
||||
try testError(
|
||||
\\extern "" test "" { a && b; }
|
||||
, &[_]Error{
|
||||
.ExpectedVarDeclOrFn,
|
||||
.InvalidAnd,
|
||||
});
|
||||
}
|
||||
|
||||
test "zig fmt: top-level fields" {
|
||||
try testCanonical(
|
||||
\\a: did_you_know,
|
||||
|
||||
Reference in New Issue
Block a user