From ac004e1bf13d00804c30f55d479b554774798307 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 22 Jan 2021 15:18:39 +0100 Subject: [PATCH] stage1: Allow nameless test blocks Nameless blocks are never filtered, the test prefix is still applied. --- lib/std/zig/ast.zig | 2 +- lib/std/zig/parse.zig | 4 +--- lib/std/zig/render.zig | 3 ++- src/stage1/all_types.hpp | 1 + src/stage1/analyze.cpp | 15 ++++++++++----- src/stage1/parser.cpp | 4 ++-- 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig index eb894fa1f6..b7975fc0f7 100644 --- a/lib/std/zig/ast.zig +++ b/lib/std/zig/ast.zig @@ -3231,7 +3231,7 @@ pub const Node = struct { base: Node = Node{ .tag = .TestDecl }, doc_comments: ?*DocComment, test_token: TokenIndex, - name: *Node, + name: ?*Node, body_node: *Node, pub fn iterate(self: *const TestDecl, index: usize) ?*Node { diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index 6d9b8ff5c6..5dd27cbcb3 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -366,9 +366,7 @@ const Parser = struct { /// TestDecl <- KEYWORD_test STRINGLITERALSINGLE Block fn parseTestDecl(p: *Parser) !?*Node { const test_token = p.eatToken(.Keyword_test) orelse return null; - const name_node = try p.expectNode(parseStringLiteralSingle, .{ - .ExpectedStringLiteral = .{ .token = p.tok_i }, - }); + const name_node = try p.parseStringLiteralSingle(); const block_node = (try p.parseBlock(null)) orelse { try p.errors.append(p.gpa, .{ .ExpectedLBrace = .{ .token = p.tok_i } }); return error.ParseError; diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig index 3cced0dd6b..0fbd6890fc 100644 --- a/lib/std/zig/render.zig +++ b/lib/std/zig/render.zig @@ -228,7 +228,8 @@ fn renderContainerDecl(allocator: *mem.Allocator, ais: anytype, tree: *ast.Tree, try renderDocComments(tree, ais, test_decl, test_decl.doc_comments); try renderToken(tree, ais, test_decl.test_token, .Space); - try renderExpression(allocator, ais, tree, test_decl.name, .Space); + if (test_decl.name) |name| + try renderExpression(allocator, ais, tree, name, .Space); try renderExpression(allocator, ais, tree, test_decl.body_node, space); }, diff --git a/src/stage1/all_types.hpp b/src/stage1/all_types.hpp index c235bb362d..88e47791ab 100644 --- a/src/stage1/all_types.hpp +++ b/src/stage1/all_types.hpp @@ -797,6 +797,7 @@ struct AstNodeVariableDeclaration { }; struct AstNodeTestDecl { + // nullptr if the test declaration has no name Buf *name; AstNode *body; diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp index a98bd28bb6..faf66f59f3 100644 --- a/src/stage1/analyze.cpp +++ b/src/stage1/analyze.cpp @@ -3871,13 +3871,18 @@ static void preview_test_decl(CodeGen *g, AstNode *node, ScopeDecls *decls_scope return; Buf *decl_name_buf = node->data.test_decl.name; + Buf *test_name; - Buf *test_name = g->test_name_prefix ? - buf_sprintf("%s%s", buf_ptr(g->test_name_prefix), buf_ptr(decl_name_buf)) : decl_name_buf; + if (decl_name_buf != nullptr) { + test_name = g->test_name_prefix ? + buf_sprintf("%s%s", buf_ptr(g->test_name_prefix), buf_ptr(decl_name_buf)) : decl_name_buf; - if (g->test_filter != nullptr && buf_len(test_name) > 0 && - strstr(buf_ptr(test_name), buf_ptr(g->test_filter)) == nullptr) { - return; + if (g->test_filter != nullptr && strstr(buf_ptr(test_name), buf_ptr(g->test_filter)) == nullptr) { + return; + } + } else { + // Unnamed test blocks are always executed. + test_name = buf_sprintf("%s", g->test_name_prefix ? buf_ptr(g->test_name_prefix) : ""); } TldFn *tld_fn = heap::c_allocator.create(); diff --git a/src/stage1/parser.cpp b/src/stage1/parser.cpp index 3027c7ae47..3fe85adbf5 100644 --- a/src/stage1/parser.cpp +++ b/src/stage1/parser.cpp @@ -658,10 +658,10 @@ static AstNode *ast_parse_test_decl(ParseContext *pc) { if (test == nullptr) return nullptr; - Token *name = expect_token(pc, TokenIdStringLiteral); + Token *name = eat_token_if(pc, TokenIdStringLiteral); AstNode *block = ast_expect(pc, ast_parse_block); AstNode *res = ast_create_node(pc, NodeTypeTestDecl, test); - res->data.test_decl.name = token_buf(name); + res->data.test_decl.name = name ? token_buf(name) : nullptr; res->data.test_decl.body = block; return res; }