authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-01-20 19:59:40+01:00
committergravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-01-21 22:00:57+01:00
log98fddd1c54171b080eb254527203b6f4e4e2f6ca
treee03dd6476556c97102fb7a42da0ae06be92427a1
parent3010ccfca5f65a8ee0d70559a38d39c2c56f7367

add field doc comments to zir

Doc comment information is stored in `extra` unconditionally for each field. This commmit covers Structs, Enums, Unions, and ErrSets.

4 files changed, 79 insertions(+), 20 deletions(-)

src/AstGen.zig+21-6
...@@ -3193,7 +3193,7 @@ fn fnDecl(...@@ -3193,7 +3193,7 @@ fn fnDecl(
3193 // missing function name already happened in scanDecls()3193 // missing function name already happened in scanDecls()
3194 const fn_name_token = fn_proto.name_token orelse return error.AnalysisFail;3194 const fn_name_token = fn_proto.name_token orelse return error.AnalysisFail;
3195 const fn_name_str_index = try astgen.identAsString(fn_name_token);3195 const fn_name_str_index = try astgen.identAsString(fn_name_token);
3196 const doc_comment_index = try docCommentAsString(astgen, fn_name_token - 1);3196 const doc_comment_index = try astgen.docCommentAsString(fn_name_token - 1);
31973197
3198 // We insert this at the beginning so that its instruction index marks the3198 // We insert this at the beginning so that its instruction index marks the
3199 // start of the top level declaration.3199 // start of the top level declaration.
...@@ -3474,7 +3474,7 @@ fn globalVarDecl(...@@ -3474,7 +3474,7 @@ fn globalVarDecl(
34743474
3475 const name_token = var_decl.ast.mut_token + 1;3475 const name_token = var_decl.ast.mut_token + 1;
3476 const name_str_index = try astgen.identAsString(name_token);3476 const name_str_index = try astgen.identAsString(name_token);
3477 const doc_comment_index = try docCommentAsString(astgen, var_decl.ast.mut_token);3477 const doc_comment_index = try astgen.docCommentAsString(var_decl.ast.mut_token);
34783478
3479 var block_scope: GenZir = .{3479 var block_scope: GenZir = .{
3480 .parent = scope,3480 .parent = scope,
...@@ -3864,7 +3864,7 @@ fn structDeclInner(...@@ -3864,7 +3864,7 @@ fn structDeclInner(
3864 const field_count = @intCast(u32, container_decl.ast.members.len - decl_count);3864 const field_count = @intCast(u32, container_decl.ast.members.len - decl_count);
38653865
3866 const bits_per_field = 4;3866 const bits_per_field = 4;
3867 const max_field_size = 4;3867 const max_field_size = 5;
3868 var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size);3868 var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size);
3869 defer wip_members.deinit();3869 defer wip_members.deinit();
38703870
...@@ -3888,6 +3888,9 @@ fn structDeclInner(...@@ -3888,6 +3888,9 @@ fn structDeclInner(
3888 try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);3888 try typeExpr(&block_scope, &namespace.base, member.ast.type_expr);
3889 wip_members.appendToField(@enumToInt(field_type));3889 wip_members.appendToField(@enumToInt(field_type));
38903890
3891 const doc_comment_index = try astgen.docCommentAsString(member.ast.name_token);
3892 wip_members.appendToField(doc_comment_index);
3893
3891 known_has_bits = known_has_bits or nodeImpliesRuntimeBits(tree, member.ast.type_expr);3894 known_has_bits = known_has_bits or nodeImpliesRuntimeBits(tree, member.ast.type_expr);
38923895
3893 const have_align = member.ast.align_expr != 0;3896 const have_align = member.ast.align_expr != 0;
...@@ -3986,7 +3989,7 @@ fn unionDeclInner(...@@ -3986,7 +3989,7 @@ fn unionDeclInner(
3986 .none;3989 .none;
39873990
3988 const bits_per_field = 4;3991 const bits_per_field = 4;
3989 const max_field_size = 4;3992 const max_field_size = 5;
3990 var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size);3993 var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, field_count, bits_per_field, max_field_size);
3991 defer wip_members.deinit();3994 defer wip_members.deinit();
39923995
...@@ -4002,6 +4005,9 @@ fn unionDeclInner(...@@ -4002,6 +4005,9 @@ fn unionDeclInner(
4002 const field_name = try astgen.identAsString(member.ast.name_token);4005 const field_name = try astgen.identAsString(member.ast.name_token);
4003 wip_members.appendToField(field_name);4006 wip_members.appendToField(field_name);
40044007
4008 const doc_comment_index = try astgen.docCommentAsString(member.ast.name_token);
4009 wip_members.appendToField(doc_comment_index);
4010
4005 const have_type = member.ast.type_expr != 0;4011 const have_type = member.ast.type_expr != 0;
4006 const have_align = member.ast.align_expr != 0;4012 const have_align = member.ast.align_expr != 0;
4007 const have_value = member.ast.value_expr != 0;4013 const have_value = member.ast.value_expr != 0;
...@@ -4265,7 +4271,7 @@ fn containerDecl(...@@ -4265,7 +4271,7 @@ fn containerDecl(
4265 .none;4271 .none;
42664272
4267 const bits_per_field = 1;4273 const bits_per_field = 1;
4268 const max_field_size = 2;4274 const max_field_size = 3;
4269 var wip_members = try WipMembers.init(gpa, &astgen.scratch, @intCast(u32, counts.decls), @intCast(u32, counts.total_fields), bits_per_field, max_field_size);4275 var wip_members = try WipMembers.init(gpa, &astgen.scratch, @intCast(u32, counts.decls), @intCast(u32, counts.total_fields), bits_per_field, max_field_size);
4270 defer wip_members.deinit();4276 defer wip_members.deinit();
42714277
...@@ -4283,6 +4289,9 @@ fn containerDecl(...@@ -4283,6 +4289,9 @@ fn containerDecl(
4283 const field_name = try astgen.identAsString(member.ast.name_token);4289 const field_name = try astgen.identAsString(member.ast.name_token);
4284 wip_members.appendToField(field_name);4290 wip_members.appendToField(field_name);
42854291
4292 const doc_comment_index = try astgen.docCommentAsString(member.ast.name_token);
4293 wip_members.appendToField(doc_comment_index);
4294
4286 const have_value = member.ast.value_expr != 0;4295 const have_value = member.ast.value_expr != 0;
4287 wip_members.nextField(bits_per_field, .{have_value});4296 wip_members.nextField(bits_per_field, .{have_value});
42884297
...@@ -4513,8 +4522,14 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir...@@ -4513,8 +4522,14 @@ fn errorSetDecl(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir
4513 switch (token_tags[tok_i]) {4522 switch (token_tags[tok_i]) {
4514 .doc_comment, .comma => {},4523 .doc_comment, .comma => {},
4515 .identifier => {4524 .identifier => {
4525 // TODO: maybe consider not using `docCommentAsString`
4526 // since we're already visiting the first doc comment
4527 // token.
4528 try astgen.extra.ensureUnusedCapacity(gpa, 2);
4516 const str_index = try astgen.identAsString(tok_i);4529 const str_index = try astgen.identAsString(tok_i);
4517 try astgen.extra.append(gpa, str_index);4530 astgen.extra.appendAssumeCapacity(str_index);
4531 const doc_comment_index = try astgen.docCommentAsString(tok_i);
4532 astgen.extra.appendAssumeCapacity(doc_comment_index);
4518 fields_len += 1;4533 fields_len += 1;
4519 },4534 },
4520 .r_brace => break,4535 .r_brace => break,
src/Sema.zig+15-3
...@@ -1916,6 +1916,9 @@ fn zirEnumDecl(...@@ -1916,6 +1916,9 @@ fn zirEnumDecl(
1916 const field_name_zir = sema.code.nullTerminatedString(sema.code.extra[extra_index]);1916 const field_name_zir = sema.code.nullTerminatedString(sema.code.extra[extra_index]);
1917 extra_index += 1;1917 extra_index += 1;
19181918
1919 // doc comment
1920 extra_index += 1;
1921
1919 // This string needs to outlive the ZIR code.1922 // This string needs to outlive the ZIR code.
1920 const field_name = try new_decl_arena_allocator.dupe(u8, field_name_zir);1923 const field_name = try new_decl_arena_allocator.dupe(u8, field_name_zir);
19211924
...@@ -2103,7 +2106,6 @@ fn zirErrorSetDecl(...@@ -2103,7 +2106,6 @@ fn zirErrorSetDecl(
2103 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;2106 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
2104 const src = inst_data.src();2107 const src = inst_data.src();
2105 const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);2108 const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
2106 const fields = sema.code.extra[extra.end..][0..extra.data.fields_len];
21072109
2108 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);2110 var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
2109 errdefer new_decl_arena.deinit();2111 errdefer new_decl_arena.deinit();
...@@ -2121,8 +2123,12 @@ fn zirErrorSetDecl(...@@ -2121,8 +2123,12 @@ fn zirErrorSetDecl(
2121 errdefer sema.mod.abortAnonDecl(new_decl);2123 errdefer sema.mod.abortAnonDecl(new_decl);
21222124
2123 var names = Module.ErrorSet.NameMap{};2125 var names = Module.ErrorSet.NameMap{};
2124 try names.ensureUnusedCapacity(new_decl_arena_allocator, fields.len);2126 try names.ensureUnusedCapacity(new_decl_arena_allocator, extra.data.fields_len);
2125 for (fields) |str_index| {2127
2128 var extra_index = @intCast(u32, extra.end);
2129 const extra_index_end = extra_index + (extra.data.fields_len * 2);
2130 while (extra_index < extra_index_end) : (extra_index += 2) { // +2 to skip over doc_string
2131 const str_index = sema.code.extra[extra_index];
2126 const name = try new_decl_arena_allocator.dupe(u8, sema.code.nullTerminatedString(str_index));2132 const name = try new_decl_arena_allocator.dupe(u8, sema.code.nullTerminatedString(str_index));
21272133
2128 // TODO: This check should be performed in AstGen instead.2134 // TODO: This check should be performed in AstGen instead.
...@@ -16313,6 +16319,9 @@ fn semaStructFields(...@@ -16313,6 +16319,9 @@ fn semaStructFields(
16313 const field_type_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);16319 const field_type_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
16314 extra_index += 1;16320 extra_index += 1;
1631516321
16322 // doc_comment
16323 extra_index += 1;
16324
16316 // This string needs to outlive the ZIR code.16325 // This string needs to outlive the ZIR code.
16317 const field_name = try decl_arena_allocator.dupe(u8, field_name_zir);16326 const field_name = try decl_arena_allocator.dupe(u8, field_name_zir);
16318 const field_ty: Type = if (field_type_ref == .none)16327 const field_ty: Type = if (field_type_ref == .none)
...@@ -16502,6 +16511,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -16502,6 +16511,9 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
16502 const field_name_zir = zir.nullTerminatedString(zir.extra[extra_index]);16511 const field_name_zir = zir.nullTerminatedString(zir.extra[extra_index]);
16503 extra_index += 1;16512 extra_index += 1;
1650416513
16514 // doc_comment
16515 extra_index += 1;
16516
16505 const field_type_ref: Zir.Inst.Ref = if (has_type) blk: {16517 const field_type_ref: Zir.Inst.Ref = if (has_type) blk: {
16506 const field_type_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);16518 const field_type_ref = @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
16507 extra_index += 1;16519 extra_index += 1;
src/Zir.zig+7
...@@ -2571,6 +2571,7 @@ pub const Inst = struct {...@@ -2571,6 +2571,7 @@ pub const Inst = struct {
2571 /// - if there is a 0 byte at the position `name` indexes, it indicates2571 /// - if there is a 0 byte at the position `name` indexes, it indicates
2572 /// this is a test decl, and the name starts at `name+1`.2572 /// this is a test decl, and the name starts at `name+1`.
2573 /// value: Index,2573 /// value: Index,
2574 /// doc_comment: u32, // 0 if no doc comment
2574 /// align: Ref, // if corresponding bit is set2575 /// align: Ref, // if corresponding bit is set
2575 /// link_section_or_address_space: { // if corresponding bit is set.2576 /// link_section_or_address_space: { // if corresponding bit is set.
2576 /// link_section: Ref,2577 /// link_section: Ref,
...@@ -2588,6 +2589,7 @@ pub const Inst = struct {...@@ -2588,6 +2589,7 @@ pub const Inst = struct {
2588 /// field_name: u32,2589 /// field_name: u32,
2589 /// field_type: Ref,2590 /// field_type: Ref,
2590 /// - if none, means `anytype`.2591 /// - if none, means `anytype`.
2592 /// doc_comment: u32, // 0 if no doc comment
2591 /// align: Ref, // if corresponding bit is set2593 /// align: Ref, // if corresponding bit is set
2592 /// default_value: Ref, // if corresponding bit is set2594 /// default_value: Ref, // if corresponding bit is set
2593 /// }2595 /// }
...@@ -2638,6 +2640,7 @@ pub const Inst = struct {...@@ -2638,6 +2640,7 @@ pub const Inst = struct {
2638 /// - if there is a 0 byte at the position `name` indexes, it indicates2640 /// - if there is a 0 byte at the position `name` indexes, it indicates
2639 /// this is a test decl, and the name starts at `name+1`.2641 /// this is a test decl, and the name starts at `name+1`.
2640 /// value: Index,2642 /// value: Index,
2643 /// doc_comment: u32, // 0 if no doc_comment
2641 /// align: Ref, // if corresponding bit is set2644 /// align: Ref, // if corresponding bit is set
2642 /// link_section_or_address_space: { // if corresponding bit is set.2645 /// link_section_or_address_space: { // if corresponding bit is set.
2643 /// link_section: Ref,2646 /// link_section: Ref,
...@@ -2649,6 +2652,7 @@ pub const Inst = struct {...@@ -2649,6 +2652,7 @@ pub const Inst = struct {
2649 /// - the bit is whether corresponding field has an value expression2652 /// - the bit is whether corresponding field has an value expression
2650 /// 9. fields: { // for every fields_len2653 /// 9. fields: { // for every fields_len
2651 /// field_name: u32,2654 /// field_name: u32,
2655 /// doc_comment: u32, // 0 if no doc_comment
2652 /// value: Ref, // if corresponding bit is set2656 /// value: Ref, // if corresponding bit is set
2653 /// }2657 /// }
2654 pub const EnumDecl = struct {2658 pub const EnumDecl = struct {
...@@ -2686,6 +2690,7 @@ pub const Inst = struct {...@@ -2686,6 +2690,7 @@ pub const Inst = struct {
2686 /// - if there is a 0 byte at the position `name` indexes, it indicates2690 /// - if there is a 0 byte at the position `name` indexes, it indicates
2687 /// this is a test decl, and the name starts at `name+1`.2691 /// this is a test decl, and the name starts at `name+1`.
2688 /// value: Index,2692 /// value: Index,
2693 /// doc_comment: u32, // 0 if no doc comment
2689 /// align: Ref, // if corresponding bit is set2694 /// align: Ref, // if corresponding bit is set
2690 /// link_section_or_address_space: { // if corresponding bit is set.2695 /// link_section_or_address_space: { // if corresponding bit is set.
2691 /// link_section: Ref,2696 /// link_section: Ref,
...@@ -2701,6 +2706,7 @@ pub const Inst = struct {...@@ -2701,6 +2706,7 @@ pub const Inst = struct {
2701 /// 0bX000: unused2706 /// 0bX000: unused
2702 /// 9. fields: { // for every fields_len2707 /// 9. fields: { // for every fields_len
2703 /// field_name: u32, // null terminated string index2708 /// field_name: u32, // null terminated string index
2709 /// doc_comment: u32, // 0 if no doc comment
2704 /// field_type: Ref, // if corresponding bit is set2710 /// field_type: Ref, // if corresponding bit is set
2705 /// - if none, means `anytype`.2711 /// - if none, means `anytype`.
2706 /// align: Ref, // if corresponding bit is set2712 /// align: Ref, // if corresponding bit is set
...@@ -2745,6 +2751,7 @@ pub const Inst = struct {...@@ -2745,6 +2751,7 @@ pub const Inst = struct {
2745 /// - if there is a 0 byte at the position `name` indexes, it indicates2751 /// - if there is a 0 byte at the position `name` indexes, it indicates
2746 /// this is a test decl, and the name starts at `name+1`.2752 /// this is a test decl, and the name starts at `name+1`.
2747 /// value: Index,2753 /// value: Index,
2754 /// doc_comment: u32, // 0 if no doc comment,
2748 /// align: Ref, // if corresponding bit is set2755 /// align: Ref, // if corresponding bit is set
2749 /// link_section_or_address_space: { // if corresponding bit is set.2756 /// link_section_or_address_space: { // if corresponding bit is set.
2750 /// link_section: Ref,2757 /// link_section: Ref,
src/print_zir.zig+36-11
...@@ -1207,6 +1207,10 @@ const Writer = struct {...@@ -1207,6 +1207,10 @@ const Writer = struct {
1207 extra_index += 1;1207 extra_index += 1;
1208 const field_type = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);1208 const field_type = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
1209 extra_index += 1;1209 extra_index += 1;
1210 const doc_comment_index = self.code.extra[extra_index];
1211 extra_index += 1;
1212
1213 try self.writeDocComment(stream, doc_comment_index);
12101214
1211 try stream.writeByteNTimes(' ', self.indent);1215 try stream.writeByteNTimes(' ', self.indent);
1212 try self.writeFlag(stream, "comptime ", is_comptime);1216 try self.writeFlag(stream, "comptime ", is_comptime);
...@@ -1332,6 +1336,10 @@ const Writer = struct {...@@ -1332,6 +1336,10 @@ const Writer = struct {
13321336
1333 const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]);1337 const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
1334 extra_index += 1;1338 extra_index += 1;
1339 const doc_comment_index = self.code.extra[extra_index];
1340 extra_index += 1;
1341
1342 try self.writeDocComment(stream, doc_comment_index);
1335 try stream.writeByteNTimes(' ', self.indent);1343 try stream.writeByteNTimes(' ', self.indent);
1336 try stream.print("{}", .{std.zig.fmtId(field_name)});1344 try stream.print("{}", .{std.zig.fmtId(field_name)});
13371345
...@@ -1419,12 +1427,13 @@ const Writer = struct {...@@ -1419,12 +1427,13 @@ const Writer = struct {
14191427
1420 const pub_str = if (is_pub) "pub " else "";1428 const pub_str = if (is_pub) "pub " else "";
1421 const hash_bytes = @bitCast([16]u8, hash_u32s.*);1429 const hash_bytes = @bitCast([16]u8, hash_u32s.*);
1422 try stream.writeByteNTimes(' ', self.indent);
1423 if (decl_name_index == 0) {1430 if (decl_name_index == 0) {
1431 try stream.writeByteNTimes(' ', self.indent);
1424 const name = if (is_exported) "usingnamespace" else "comptime";1432 const name = if (is_exported) "usingnamespace" else "comptime";
1425 try stream.writeAll(pub_str);1433 try stream.writeAll(pub_str);
1426 try stream.writeAll(name);1434 try stream.writeAll(name);
1427 } else if (decl_name_index == 1) {1435 } else if (decl_name_index == 1) {
1436 try stream.writeByteNTimes(' ', self.indent);
1428 try stream.writeAll("test");1437 try stream.writeAll("test");
1429 } else {1438 } else {
1430 const raw_decl_name = self.code.nullTerminatedString(decl_name_index);1439 const raw_decl_name = self.code.nullTerminatedString(decl_name_index);
...@@ -1435,15 +1444,9 @@ const Writer = struct {...@@ -1435,15 +1444,9 @@ const Writer = struct {
1435 const test_str = if (raw_decl_name.len == 0) "test " else "";1444 const test_str = if (raw_decl_name.len == 0) "test " else "";
1436 const export_str = if (is_exported) "export " else "";1445 const export_str = if (is_exported) "export " else "";
14371446
1438 if (doc_comment_index != 0) {1447 try self.writeDocComment(stream, doc_comment_index);
1439 const doc_comment = self.code.nullTerminatedString(doc_comment_index);
1440 var it = std.mem.tokenize(u8, doc_comment, "\n");
1441 while (it.next()) |doc_line| {
1442 try stream.print("///{s}\n", .{doc_line});
1443 try stream.writeByteNTimes(' ', self.indent);
1444 }
1445 }
14461448
1449 try stream.writeByteNTimes(' ', self.indent);
1447 try stream.print("[{d}] {s}{s}{s}{}", .{1450 try stream.print("[{d}] {s}{s}{s}{}", .{
1448 sub_index, pub_str, test_str, export_str, std.zig.fmtId(decl_name),1451 sub_index, pub_str, test_str, export_str, std.zig.fmtId(decl_name),
1449 });1452 });
...@@ -1569,6 +1572,11 @@ const Writer = struct {...@@ -1569,6 +1572,11 @@ const Writer = struct {
1569 const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]);1572 const field_name = self.code.nullTerminatedString(self.code.extra[extra_index]);
1570 extra_index += 1;1573 extra_index += 1;
15711574
1575 const doc_comment_index = self.code.extra[extra_index];
1576 extra_index += 1;
1577
1578 try self.writeDocComment(stream, doc_comment_index);
1579
1572 try stream.writeByteNTimes(' ', self.indent);1580 try stream.writeByteNTimes(' ', self.indent);
1573 try stream.print("{}", .{std.zig.fmtId(field_name)});1581 try stream.print("{}", .{std.zig.fmtId(field_name)});
15741582
...@@ -1632,17 +1640,23 @@ const Writer = struct {...@@ -1632,17 +1640,23 @@ const Writer = struct {
1632 ) !void {1640 ) !void {
1633 const inst_data = self.code.instructions.items(.data)[inst].pl_node;1641 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
1634 const extra = self.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);1642 const extra = self.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
1635 const fields = self.code.extra[extra.end..][0..extra.data.fields_len];
16361643
1637 try stream.print("{s}, ", .{@tagName(name_strategy)});1644 try stream.print("{s}, ", .{@tagName(name_strategy)});
16381645
1639 try stream.writeAll("{\n");1646 try stream.writeAll("{\n");
1640 self.indent += 2;1647 self.indent += 2;
1641 for (fields) |str_index| {1648
1649 var extra_index = @intCast(u32, extra.end);
1650 const extra_index_end = extra_index + (extra.data.fields_len * 2);
1651 while (extra_index < extra_index_end) : (extra_index += 2) {
1652 const str_index = self.code.extra[extra_index];
1642 const name = self.code.nullTerminatedString(str_index);1653 const name = self.code.nullTerminatedString(str_index);
1654 const doc_comment_index = self.code.extra[extra_index + 1];
1655 try self.writeDocComment(stream, doc_comment_index);
1643 try stream.writeByteNTimes(' ', self.indent);1656 try stream.writeByteNTimes(' ', self.indent);
1644 try stream.print("{},\n", .{std.zig.fmtId(name)});1657 try stream.print("{},\n", .{std.zig.fmtId(name)});
1645 }1658 }
1659
1646 self.indent -= 2;1660 self.indent -= 2;
1647 try stream.writeByteNTimes(' ', self.indent);1661 try stream.writeByteNTimes(' ', self.indent);
1648 try stream.writeAll("}) ");1662 try stream.writeAll("}) ");
...@@ -2134,6 +2148,17 @@ const Writer = struct {...@@ -2134,6 +2148,17 @@ const Writer = struct {
2134 }2148 }
2135 }2149 }
21362150
2151 fn writeDocComment(self: *Writer, stream: anytype, doc_comment_index: u32) !void {
2152 if (doc_comment_index != 0) {
2153 const doc_comment = self.code.nullTerminatedString(doc_comment_index);
2154 var it = std.mem.tokenize(u8, doc_comment, "\n");
2155 while (it.next()) |doc_line| {
2156 try stream.writeByteNTimes(' ', self.indent);
2157 try stream.print("///{s}\n", .{doc_line});
2158 }
2159 }
2160 }
2161
2137 fn writeBody(self: *Writer, stream: anytype, body: []const Zir.Inst.Index) !void {2162 fn writeBody(self: *Writer, stream: anytype, body: []const Zir.Inst.Index) !void {
2138 for (body) |inst| {2163 for (body) |inst| {
2139 try stream.writeByteNTimes(' ', self.indent);2164 try stream.writeByteNTimes(' ', self.indent);