aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-04-19 03:52:53 -0400
committerGitHub <noreply@github.com>2020-04-19 03:52:53 -0400
commit051620dcaf7df2f0dafb721a192dc5fb9f899987 (patch)
tree59a35d4c4a7a9f613a5b618f62764b2fb14c589b /src/parser.cpp
parentd415ffd7d95f9c88210154c19e64dabd6b546809 (diff)
parentb6fe839248751f6e2cfbdbe2cc31e47aee154555 (diff)
downloadzig-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.cpp37
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;