Commit b7095912c7
Changed files (3)
std
std/zig/ast.zig
@@ -6,6 +6,7 @@ const mem = std.mem;
pub const Node = struct {
id: Id,
+ comments: ?&LineComment,
pub const Id = enum {
// Top level
@@ -139,7 +140,6 @@ pub const Node = struct {
pub const VarDecl = struct {
base: Node,
- comments: ?&LineComment,
visib_token: ?Token,
name_token: Token,
eq_token: Token,
@@ -421,7 +421,6 @@ pub const Node = struct {
pub const FnProto = struct {
base: Node,
- comments: ?&LineComment,
visib_token: ?Token,
fn_token: Token,
name_token: ?Token,
@@ -1732,7 +1731,6 @@ pub const Node = struct {
pub const TestDecl = struct {
base: Node,
- comments: ?&LineComment,
test_token: Token,
name: &Node,
body_node: &Node,
std/zig/parser.zig
@@ -182,6 +182,11 @@ pub const Parser = struct {
}
};
+ const AddCommentsCtx = struct {
+ node_ptr: &&ast.Node,
+ comments: ?&ast.Node.LineComment,
+ };
+
const State = union(enum) {
TopLevel,
TopLevelExtern: TopLevelDeclCtx,
@@ -221,6 +226,7 @@ pub const Parser = struct {
Statement: &ast.Node.Block,
ComptimeStatement: ComptimeStatementCtx,
Semicolon: &&ast.Node,
+ AddComments: AddCommentsCtx,
AsmOutputItems: &ArrayList(&ast.Node.AsmOutput),
AsmOutputReturnOrType: &ast.Node.AsmOutput,
@@ -345,24 +351,26 @@ pub const Parser = struct {
Token.Id.Keyword_test => {
stack.append(State.TopLevel) catch unreachable;
- const block = try self.createNode(arena, ast.Node.Block,
- ast.Node.Block {
- .base = undefined,
- .label = null,
- .lbrace = undefined,
- .statements = ArrayList(&ast.Node).init(arena),
- .rbrace = undefined,
- }
- );
- const test_node = try self.createAttachNode(arena, &root_node.decls, ast.Node.TestDecl,
- ast.Node.TestDecl {
- .base = undefined,
+ const block = try arena.construct(ast.Node.Block {
+ .base = ast.Node {
+ .id = ast.Node.Id.Block,
+ .comments = null,
+ },
+ .label = null,
+ .lbrace = undefined,
+ .statements = ArrayList(&ast.Node).init(arena),
+ .rbrace = undefined,
+ });
+ const test_node = try arena.construct(ast.Node.TestDecl {
+ .base = ast.Node {
+ .id = ast.Node.Id.TestDecl,
.comments = comments,
- .test_token = token,
- .name = undefined,
- .body_node = &block.base,
- }
- );
+ },
+ .test_token = token,
+ .name = undefined,
+ .body_node = &block.base,
+ });
+ try root_node.decls.append(&test_node.base);
stack.append(State { .Block = block }) catch unreachable;
try stack.append(State {
.ExpectTokenSave = ExpectTokenSave {
@@ -530,24 +538,25 @@ pub const Parser = struct {
},
Token.Id.Keyword_fn, Token.Id.Keyword_nakedcc,
Token.Id.Keyword_stdcallcc, Token.Id.Keyword_async => {
- const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.Node.FnProto,
- ast.Node.FnProto {
- .base = undefined,
+ const fn_proto = try arena.construct(ast.Node.FnProto {
+ .base = ast.Node {
+ .id = ast.Node.Id.FnProto,
.comments = comments,
- .visib_token = ctx.visib_token,
- .name_token = null,
- .fn_token = undefined,
- .params = ArrayList(&ast.Node).init(arena),
- .return_type = undefined,
- .var_args_token = null,
- .extern_export_inline_token = ctx.extern_export_inline_token,
- .cc_token = null,
- .async_attr = null,
- .body_node = null,
- .lib_name = ctx.lib_name,
- .align_expr = null,
- }
- );
+ },
+ .visib_token = ctx.visib_token,
+ .name_token = null,
+ .fn_token = undefined,
+ .params = ArrayList(&ast.Node).init(arena),
+ .return_type = undefined,
+ .var_args_token = null,
+ .extern_export_inline_token = ctx.extern_export_inline_token,
+ .cc_token = null,
+ .async_attr = null,
+ .body_node = null,
+ .lib_name = ctx.lib_name,
+ .align_expr = null,
+ });
+ try ctx.decls.append(&fn_proto.base);
stack.append(State { .FnDef = fn_proto }) catch unreachable;
try stack.append(State { .FnProto = fn_proto });
@@ -789,24 +798,25 @@ pub const Parser = struct {
State.VarDecl => |ctx| {
- const var_decl = try self.createAttachNode(arena, ctx.list, ast.Node.VarDecl,
- ast.Node.VarDecl {
- .base = undefined,
+ const var_decl = try arena.construct(ast.Node.VarDecl {
+ .base = ast.Node {
+ .id = ast.Node.Id.VarDecl,
.comments = ctx.comments,
- .visib_token = ctx.visib_token,
- .mut_token = ctx.mut_token,
- .comptime_token = ctx.comptime_token,
- .extern_export_token = ctx.extern_export_token,
- .type_node = null,
- .align_node = null,
- .init_node = null,
- .lib_name = ctx.lib_name,
- // initialized later
- .name_token = undefined,
- .eq_token = undefined,
- .semicolon_token = undefined,
- }
- );
+ },
+ .visib_token = ctx.visib_token,
+ .mut_token = ctx.mut_token,
+ .comptime_token = ctx.comptime_token,
+ .extern_export_token = ctx.extern_export_token,
+ .type_node = null,
+ .align_node = null,
+ .init_node = null,
+ .lib_name = ctx.lib_name,
+ // initialized later
+ .name_token = undefined,
+ .eq_token = undefined,
+ .semicolon_token = undefined,
+ });
+ try ctx.list.append(&var_decl.base);
stack.append(State { .VarDeclAlign = var_decl }) catch unreachable;
try stack.append(State { .TypeExprBegin = OptionalCtx { .RequiredNull = &var_decl.type_node} });
@@ -1218,19 +1228,23 @@ pub const Parser = struct {
continue;
},
Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
- const node = try self.createAttachNode(arena, &block.statements, ast.Node.Defer,
- ast.Node.Defer {
- .base = undefined,
- .defer_token = token,
- .kind = switch (token.id) {
- Token.Id.Keyword_defer => ast.Node.Defer.Kind.Unconditional,
- Token.Id.Keyword_errdefer => ast.Node.Defer.Kind.Error,
- else => unreachable,
- },
- .expr = undefined,
- }
- );
- stack.append(State { .Semicolon = &&node.base }) catch unreachable;
+ const node = try arena.construct(ast.Node.Defer {
+ .base = ast.Node {
+ .id = ast.Node.Id.Defer,
+ .comments = comments,
+ },
+ .defer_token = token,
+ .kind = switch (token.id) {
+ Token.Id.Keyword_defer => ast.Node.Defer.Kind.Unconditional,
+ Token.Id.Keyword_errdefer => ast.Node.Defer.Kind.Error,
+ else => unreachable,
+ },
+ .expr = undefined,
+ });
+ const node_ptr = try block.statements.addOne();
+ *node_ptr = &node.base;
+
+ stack.append(State { .Semicolon = node_ptr }) catch unreachable;
try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = &node.expr } });
continue;
},
@@ -1249,9 +1263,13 @@ pub const Parser = struct {
},
else => {
self.putBackToken(token);
- const statememt = try block.statements.addOne();
- stack.append(State { .Semicolon = statememt }) catch unreachable;
- try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = statememt } });
+ const statement = try block.statements.addOne();
+ stack.append(State { .Semicolon = statement }) catch unreachable;
+ try stack.append(State { .AddComments = AddCommentsCtx {
+ .node_ptr = statement,
+ .comments = comments,
+ }});
+ try stack.append(State { .AssignmentExpressionBegin = OptionalCtx{ .Required = statement } });
continue;
}
}
@@ -1293,6 +1311,12 @@ pub const Parser = struct {
continue;
},
+ State.AddComments => |add_comments_ctx| {
+ const node = *add_comments_ctx.node_ptr;
+ node.comments = add_comments_ctx.comments;
+ continue;
+ },
+
State.AsmOutputItems => |items| {
const lbracket = self.getNextToken();
@@ -1576,24 +1600,25 @@ pub const Parser = struct {
State.ExternType => |ctx| {
if (self.eatToken(Token.Id.Keyword_fn)) |fn_token| {
- const fn_proto = try self.createToCtxNode(arena, ctx.opt_ctx, ast.Node.FnProto,
- ast.Node.FnProto {
- .base = undefined,
+ const fn_proto = try arena.construct(ast.Node.FnProto {
+ .base = ast.Node {
+ .id = ast.Node.Id.FnProto,
.comments = ctx.comments,
- .visib_token = null,
- .name_token = null,
- .fn_token = fn_token,
- .params = ArrayList(&ast.Node).init(arena),
- .return_type = undefined,
- .var_args_token = null,
- .extern_export_inline_token = ctx.extern_token,
- .cc_token = null,
- .async_attr = null,
- .body_node = null,
- .lib_name = null,
- .align_expr = null,
- }
- );
+ },
+ .visib_token = null,
+ .name_token = null,
+ .fn_token = fn_token,
+ .params = ArrayList(&ast.Node).init(arena),
+ .return_type = undefined,
+ .var_args_token = null,
+ .extern_export_inline_token = ctx.extern_token,
+ .cc_token = null,
+ .async_attr = null,
+ .body_node = null,
+ .lib_name = null,
+ .align_expr = null,
+ });
+ ctx.opt_ctx.store(&fn_proto.base);
stack.append(State { .FnProto = fn_proto }) catch unreachable;
continue;
}
@@ -2546,46 +2571,48 @@ pub const Parser = struct {
continue;
},
Token.Id.Keyword_fn => {
- const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.Node.FnProto,
- ast.Node.FnProto {
- .base = undefined,
+ const fn_proto = try arena.construct(ast.Node.FnProto {
+ .base = ast.Node {
+ .id = ast.Node.Id.FnProto,
.comments = null,
- .visib_token = null,
- .name_token = null,
- .fn_token = token,
- .params = ArrayList(&ast.Node).init(arena),
- .return_type = undefined,
- .var_args_token = null,
- .extern_export_inline_token = null,
- .cc_token = null,
- .async_attr = null,
- .body_node = null,
- .lib_name = null,
- .align_expr = null,
- }
- );
+ },
+ .visib_token = null,
+ .name_token = null,
+ .fn_token = token,
+ .params = ArrayList(&ast.Node).init(arena),
+ .return_type = undefined,
+ .var_args_token = null,
+ .extern_export_inline_token = null,
+ .cc_token = null,
+ .async_attr = null,
+ .body_node = null,
+ .lib_name = null,
+ .align_expr = null,
+ });
+ opt_ctx.store(&fn_proto.base);
stack.append(State { .FnProto = fn_proto }) catch unreachable;
continue;
},
Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
- const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.Node.FnProto,
- ast.Node.FnProto {
- .base = undefined,
+ const fn_proto = try arena.construct(ast.Node.FnProto {
+ .base = ast.Node {
+ .id = ast.Node.Id.FnProto,
.comments = null,
- .visib_token = null,
- .name_token = null,
- .fn_token = undefined,
- .params = ArrayList(&ast.Node).init(arena),
- .return_type = undefined,
- .var_args_token = null,
- .extern_export_inline_token = null,
- .cc_token = token,
- .async_attr = null,
- .body_node = null,
- .lib_name = null,
- .align_expr = null,
- }
- );
+ },
+ .visib_token = null,
+ .name_token = null,
+ .fn_token = undefined,
+ .params = ArrayList(&ast.Node).init(arena),
+ .return_type = undefined,
+ .var_args_token = null,
+ .extern_export_inline_token = null,
+ .cc_token = token,
+ .async_attr = null,
+ .body_node = null,
+ .lib_name = null,
+ .align_expr = null,
+ });
+ opt_ctx.store(&fn_proto.base);
stack.append(State { .FnProto = fn_proto }) catch unreachable;
try stack.append(State {
.ExpectTokenSave = ExpectTokenSave {
@@ -2747,13 +2774,13 @@ pub const Parser = struct {
if (result) |comment_node| {
break :blk comment_node;
} else {
- const comment_node = try arena.create(ast.Node.LineComment);
- *comment_node = ast.Node.LineComment {
+ const comment_node = try arena.construct(ast.Node.LineComment {
.base = ast.Node {
.id = ast.Node.Id.LineComment,
+ .comments = null,
},
.lines = ArrayList(Token).init(arena),
- };
+ });
result = comment_node;
break :blk comment_node;
}
@@ -3096,7 +3123,7 @@ pub const Parser = struct {
*node = *init_to;
node.base = blk: {
const id = ast.Node.typeToId(T);
- break :blk ast.Node {.id = id};
+ break :blk ast.Node {.id = id, .comments = null};
};
return node;
@@ -3269,7 +3296,7 @@ pub const Parser = struct {
switch (decl.id) {
ast.Node.Id.FnProto => {
const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl);
- try self.renderComments(stream, fn_proto, indent);
+ try self.renderComments(stream, &fn_proto.base, indent);
if (fn_proto.body_node) |body_node| {
stack.append(RenderState { .Expression = body_node}) catch unreachable;
@@ -3295,7 +3322,7 @@ pub const Parser = struct {
},
ast.Node.Id.TestDecl => {
const test_decl = @fieldParentPtr(ast.Node.TestDecl, "base", decl);
- try self.renderComments(stream, test_decl, indent);
+ try self.renderComments(stream, &test_decl.base, indent);
try stream.print("test ");
try stack.append(RenderState { .Expression = test_decl.body_node });
try stack.append(RenderState { .Text = " " });
@@ -3338,7 +3365,6 @@ pub const Parser = struct {
},
RenderState.FieldInitializer => |field_init| {
- //TODO try self.renderComments(stream, field_init, indent);
try stream.print(".{}", self.tokenizer.getTokenSlice(field_init.name_token));
try stream.print(" = ");
try stack.append(RenderState { .Expression = field_init.expr });
@@ -3385,7 +3411,6 @@ pub const Parser = struct {
RenderState.ParamDecl => |base| {
const param_decl = @fieldParentPtr(ast.Node.ParamDecl, "base", base);
- // TODO try self.renderComments(stream, param_decl, indent);
if (param_decl.comptime_token) |comptime_token| {
try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));
}
@@ -4328,10 +4353,10 @@ pub const Parser = struct {
ast.Node.Id.ParamDecl => unreachable,
},
RenderState.Statement => |base| {
+ try self.renderComments(stream, base, indent);
switch (base.id) {
ast.Node.Id.VarDecl => {
const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);
- try self.renderComments(stream, var_decl, indent);
try stack.append(RenderState { .VarDecl = var_decl});
},
else => {
@@ -4348,7 +4373,7 @@ pub const Parser = struct {
}
}
- fn renderComments(self: &Parser, stream: var, node: var, indent: usize) !void {
+ fn renderComments(self: &Parser, stream: var, node: &ast.Node, indent: usize) !void {
const comment = node.comments ?? return;
for (comment.lines.toSliceConst()) |line_token| {
try stream.print("{}\n", self.tokenizer.getTokenSlice(line_token));
@@ -4430,6 +4455,16 @@ fn testCanonical(source: []const u8) !void {
}
}
+test "zig fmt: preserve comments before statements" {
+ try testCanonical(
+ \\test "std" {
+ \\ // statement comment
+ \\ _ = @import("foo/bar.zig");
+ \\}
+ \\
+ );
+}
+
test "zig fmt: preserve top level comments" {
try testCanonical(
\\// top level comment
std/mem.zig
@@ -37,6 +37,20 @@ pub const Allocator = struct {
return &slice[0];
}
+ // TODO once #733 is solved, this will replace create
+ fn construct(self: &Allocator, init: var) t: {
+ // TODO this is a workaround for type getting parsed as Error!&const T
+ const T = @typeOf(init).Child;
+ break :t Error!&T;
+ } {
+ const T = @typeOf(init).Child;
+ if (@sizeOf(T) == 0) return &{};
+ const slice = try self.alloc(T, 1);
+ const ptr = &slice[0];
+ *ptr = *init;
+ return ptr;
+ }
+
fn destroy(self: &Allocator, ptr: var) void {
self.free(ptr[0..1]);
}
@@ -54,7 +68,7 @@ pub const Allocator = struct {
const byte_count = math.mul(usize, @sizeOf(T), n) catch return Error.OutOfMemory;
const byte_slice = try self.allocFn(self, byte_count, alignment);
assert(byte_slice.len == byte_count);
- // This loop should get optimized out in ReleaseFast mode
+ // This loop gets optimized out in ReleaseFast mode
for (byte_slice) |*byte| {
*byte = undefined;
}
@@ -81,7 +95,7 @@ pub const Allocator = struct {
const byte_slice = try self.reallocFn(self, old_byte_slice, byte_count, alignment);
assert(byte_slice.len == byte_count);
if (n > old_mem.len) {
- // This loop should get optimized out in ReleaseFast mode
+ // This loop gets optimized out in ReleaseFast mode
for (byte_slice[old_byte_slice.len..]) |*byte| {
*byte = undefined;
}