diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-04-19 03:52:53 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-19 03:52:53 -0400 |
| commit | 051620dcaf7df2f0dafb721a192dc5fb9f899987 (patch) | |
| tree | 59a35d4c4a7a9f613a5b618f62764b2fb14c589b /src/parser.cpp | |
| parent | d415ffd7d95f9c88210154c19e64dabd6b546809 (diff) | |
| parent | b6fe839248751f6e2cfbdbe2cc31e47aee154555 (diff) | |
| download | zig-051620dcaf7df2f0dafb721a192dc5fb9f899987.tar.gz zig-051620dcaf7df2f0dafb721a192dc5fb9f899987.zip | |
Merge pull request #5097 from Vexu/field
Disallow declarations between fields
Diffstat (limited to 'src/parser.cpp')
| -rw-r--r-- | src/parser.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index 20ad179a75..1391393c26 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -526,6 +526,15 @@ static void ast_parse_container_doc_comments(ParseContext *pc, Buf *buf) { } } +enum ContainerFieldState { + // no fields have been seen + ContainerFieldStateNone, + // currently parsing fields + ContainerFieldStateSeen, + // saw fields and then a declaration after them + ContainerFieldStateEnd, +}; + // ContainerMembers // <- TestDecl ContainerMembers // / TopLevelComptime ContainerMembers @@ -537,17 +546,29 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) { AstNodeContainerDecl res = {}; Buf tld_doc_comment_buf = BUF_INIT; buf_resize(&tld_doc_comment_buf, 0); + ContainerFieldState field_state = ContainerFieldStateNone; + Token *first_token = nullptr; for (;;) { ast_parse_container_doc_comments(pc, &tld_doc_comment_buf); + Token *peeked_token = peek_token(pc); + AstNode *test_decl = ast_parse_test_decl(pc); if (test_decl != nullptr) { + if (field_state == ContainerFieldStateSeen) { + field_state = ContainerFieldStateEnd; + first_token = peeked_token; + } res.decls.append(test_decl); continue; } AstNode *top_level_comptime = ast_parse_top_level_comptime(pc); if (top_level_comptime != nullptr) { + if (field_state == ContainerFieldStateSeen) { + field_state = ContainerFieldStateEnd; + first_token = peeked_token; + } res.decls.append(top_level_comptime); continue; } @@ -555,11 +576,17 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) { Buf doc_comment_buf = BUF_INIT; ast_parse_doc_comments(pc, &doc_comment_buf); + peeked_token = peek_token(pc); + Token *visib_token = eat_token_if(pc, TokenIdKeywordPub); VisibMod visib_mod = visib_token != nullptr ? VisibModPub : VisibModPrivate; AstNode *top_level_decl = ast_parse_top_level_decl(pc, visib_mod, &doc_comment_buf); if (top_level_decl != nullptr) { + if (field_state == ContainerFieldStateSeen) { + field_state = ContainerFieldStateEnd; + first_token = peeked_token; + } res.decls.append(top_level_decl); continue; } @@ -572,6 +599,16 @@ static AstNodeContainerDecl ast_parse_container_members(ParseContext *pc) { AstNode *container_field = ast_parse_container_field(pc); if (container_field != nullptr) { + switch (field_state) { + case ContainerFieldStateNone: + field_state = ContainerFieldStateSeen; + break; + case ContainerFieldStateSeen: + break; + case ContainerFieldStateEnd: + ast_error(pc, first_token, "declarations are not allowed between container fields"); + } + assert(container_field->type == NodeTypeStructField); container_field->data.struct_field.doc_comments = doc_comment_buf; container_field->data.struct_field.comptime_token = comptime_token; |
