authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-09-02 17:26:41+02:00
committergravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-09-02 17:28:12+02:00
log081d5a96907ca844dcbfed0fce32b7ea29d933ab
tree9ae0c01cd28ce6181cf07ca879b7e00dd2f91294
parent5581b60393cd03773945f773942a8dcfbaffb5e8

autodoc: correct line number implementation

we also correctly take advantage of the starting byte offset of the parent decl when calling `tree.tokenLocation()`!

2 files changed, 184 insertions(+), 118 deletions(-)

lib/docs/main.js+1-1
......@@ -2285,7 +2285,7 @@ var zigAnalysis;
22852285
22862286 return "<a style=\"float: right;\" href=\"" +
22872287 sourceFileUrlTemplate.replace("{{file}}",
2288 zigAnalysis.files[srcNode.file]).replace("{{line}}", srcNode.line) + "\">[src]</a>";
2288 zigAnalysis.files[srcNode.file]).replace("{{line}}", srcNode.line + 1) + "\">[src]</a>";
22892289 }
22902290
22912291 function renderContainer(container) {
src/Autodoc.zig+183-117
......@@ -1,6 +1,7 @@
11const builtin = @import("builtin");
22const std = @import("std");
33const build_options = @import("build_options");
4const Ast = std.zig.Ast;
45const Autodoc = @This();
56const Compilation = @import("Compilation.zig");
67const Module = @import("Module.zig");
......@@ -47,6 +48,19 @@ const RefPathResumeInfo = struct {
4748 ref_path: []DocData.Expr,
4849};
4950
51/// Used to accumulate src_node offsets.
52/// In ZIR, all ast node indices are relative to the parent decl.
53/// More concretely, `union_decl`, `struct_decl`, `enum_decl` and `opaque_decl`
54/// and the value of each of their decls participate in the relative offset
55/// counting, and nothing else.
56/// We keep track of the line and byte values for these instructions in order
57/// to avoid tokenizing every file (on new lines) from the start every time.
58const SrcLocInfo = struct {
59 bytes: u32 = 0,
60 line: usize = 0,
61 src_node: i32 = 0,
62};
63
5064var arena_allocator: std.heap.ArenaAllocator = undefined;
5165pub fn init(m: *Module, doc_location: Compilation.EmitLoc) Autodoc {
5266 arena_allocator = std.heap.ArenaAllocator.init(m.gpa);
......@@ -202,7 +216,7 @@ pub fn generateZirData(self: *Autodoc) !void {
202216
203217 try self.ast_nodes.append(self.arena, .{ .name = "(root)" });
204218 try self.files.put(self.arena, file, main_type_index);
205 _ = try self.walkInstruction(file, &root_scope, 1, Zir.main_struct_inst, false);
219 _ = try self.walkInstruction(file, &root_scope, .{}, Zir.main_struct_inst, false);
206220
207221 if (self.ref_paths_pending_on_decls.count() > 0) {
208222 @panic("some decl paths were never fully analized (pending on decls)");
......@@ -758,8 +772,8 @@ const DocData = struct {
758772const AutodocErrors = error{
759773 OutOfMemory,
760774 CurrentWorkingDirectoryUnlinked,
761 Unexpected,
762};
775 UnexpectedEndOfFile,
776} || std.fs.File.OpenError || std.fs.File.ReadError;
763777
764778/// Called when we need to analyze a Zir instruction.
765779/// For example it gets called by `generateZirData` on instruction 0,
......@@ -773,7 +787,7 @@ fn walkInstruction(
773787 self: *Autodoc,
774788 file: *File,
775789 parent_scope: *Scope,
776 parent_line: usize,
790 parent_src: SrcLocInfo,
777791 inst_index: usize,
778792 need_type: bool, // true if the caller needs us to provide also a typeRef
779793) AutodocErrors!DocData.WalkResult {
......@@ -865,7 +879,7 @@ fn walkInstruction(
865879 return self.walkInstruction(
866880 new_file,
867881 &root_scope,
868 1,
882 .{},
869883 Zir.main_struct_inst,
870884 false,
871885 );
......@@ -890,14 +904,14 @@ fn walkInstruction(
890904 return self.walkInstruction(
891905 new_file.file,
892906 &new_scope,
893 1,
907 .{},
894908 Zir.main_struct_inst,
895909 need_type,
896910 );
897911 },
898912 .ret_node => {
899913 const un_node = data[inst_index].un_node;
900 return self.walkRef(file, parent_scope, parent_line, un_node.operand, false);
914 return self.walkRef(file, parent_scope, parent_src, un_node.operand, false);
901915 },
902916 .ret_load => {
903917 const un_node = data[inst_index].un_node;
......@@ -928,7 +942,7 @@ fn walkInstruction(
928942 }
929943
930944 if (result_ref) |rr| {
931 return self.walkRef(file, parent_scope, parent_line, rr, need_type);
945 return self.walkRef(file, parent_scope, parent_src, rr, need_type);
932946 }
933947
934948 return DocData.WalkResult{
......@@ -937,11 +951,11 @@ fn walkInstruction(
937951 },
938952 .closure_get => {
939953 const inst_node = data[inst_index].inst_node;
940 return try self.walkInstruction(file, parent_scope, parent_line, inst_node.inst, need_type);
954 return try self.walkInstruction(file, parent_scope, parent_src, inst_node.inst, need_type);
941955 },
942956 .closure_capture => {
943957 const un_tok = data[inst_index].un_tok;
944 return try self.walkRef(file, parent_scope, parent_line, un_tok.operand, need_type);
958 return try self.walkRef(file, parent_scope, parent_src, un_tok.operand, need_type);
945959 },
946960 .cmpxchg_strong, .cmpxchg_weak => {
947961 const pl_node = data[inst_index].pl_node;
......@@ -956,7 +970,7 @@ fn walkInstruction(
956970 var ptr: DocData.WalkResult = try self.walkRef(
957971 file,
958972 parent_scope,
959 parent_line,
973 parent_src,
960974 extra.data.ptr,
961975 false,
962976 );
......@@ -966,7 +980,7 @@ fn walkInstruction(
966980 var expected_value: DocData.WalkResult = try self.walkRef(
967981 file,
968982 parent_scope,
969 parent_line,
983 parent_src,
970984 extra.data.expected_value,
971985 false,
972986 );
......@@ -976,7 +990,7 @@ fn walkInstruction(
976990 var new_value: DocData.WalkResult = try self.walkRef(
977991 file,
978992 parent_scope,
979 parent_line,
993 parent_src,
980994 extra.data.new_value,
981995 false,
982996 );
......@@ -986,7 +1000,7 @@ fn walkInstruction(
9861000 var success_order: DocData.WalkResult = try self.walkRef(
9871001 file,
9881002 parent_scope,
989 parent_line,
1003 parent_src,
9901004 extra.data.success_order,
9911005 false,
9921006 );
......@@ -996,7 +1010,7 @@ fn walkInstruction(
9961010 var failure_order: DocData.WalkResult = try self.walkRef(
9971011 file,
9981012 parent_scope,
999 parent_line,
1013 parent_src,
10001014 extra.data.failure_order,
10011015 false,
10021016 );
......@@ -1047,10 +1061,11 @@ fn walkInstruction(
10471061 },
10481062 .compile_error => {
10491063 const un_node = data[inst_index].un_node;
1064
10501065 var operand: DocData.WalkResult = try self.walkRef(
10511066 file,
10521067 parent_scope,
1053 parent_line,
1068 parent_src,
10541069 un_node.operand,
10551070 false,
10561071 );
......@@ -1105,14 +1120,14 @@ fn walkInstruction(
11051120 var lhs: DocData.WalkResult = try self.walkRef(
11061121 file,
11071122 parent_scope,
1108 parent_line,
1123 parent_src,
11091124 extra.data.lhs,
11101125 false,
11111126 );
11121127 var start: DocData.WalkResult = try self.walkRef(
11131128 file,
11141129 parent_scope,
1115 parent_line,
1130 parent_src,
11161131 extra.data.start,
11171132 false,
11181133 );
......@@ -1138,21 +1153,21 @@ fn walkInstruction(
11381153 var lhs: DocData.WalkResult = try self.walkRef(
11391154 file,
11401155 parent_scope,
1141 parent_line,
1156 parent_src,
11421157 extra.data.lhs,
11431158 false,
11441159 );
11451160 var start: DocData.WalkResult = try self.walkRef(
11461161 file,
11471162 parent_scope,
1148 parent_line,
1163 parent_src,
11491164 extra.data.start,
11501165 false,
11511166 );
11521167 var end: DocData.WalkResult = try self.walkRef(
11531168 file,
11541169 parent_scope,
1155 parent_line,
1170 parent_src,
11561171 extra.data.end,
11571172 false,
11581173 );
......@@ -1180,28 +1195,28 @@ fn walkInstruction(
11801195 var lhs: DocData.WalkResult = try self.walkRef(
11811196 file,
11821197 parent_scope,
1183 parent_line,
1198 parent_src,
11841199 extra.data.lhs,
11851200 false,
11861201 );
11871202 var start: DocData.WalkResult = try self.walkRef(
11881203 file,
11891204 parent_scope,
1190 parent_line,
1205 parent_src,
11911206 extra.data.start,
11921207 false,
11931208 );
11941209 var end: DocData.WalkResult = try self.walkRef(
11951210 file,
11961211 parent_scope,
1197 parent_line,
1212 parent_src,
11981213 extra.data.end,
11991214 false,
12001215 );
12011216 var sentinel: DocData.WalkResult = try self.walkRef(
12021217 file,
12031218 parent_scope,
1204 parent_line,
1219 parent_src,
12051220 extra.data.sentinel,
12061221 false,
12071222 );
......@@ -1251,14 +1266,14 @@ fn walkInstruction(
12511266 var lhs: DocData.WalkResult = try self.walkRef(
12521267 file,
12531268 parent_scope,
1254 parent_line,
1269 parent_src,
12551270 extra.data.lhs,
12561271 false,
12571272 );
12581273 var rhs: DocData.WalkResult = try self.walkRef(
12591274 file,
12601275 parent_scope,
1261 parent_line,
1276 parent_src,
12621277 extra.data.rhs,
12631278 false,
12641279 );
......@@ -1319,7 +1334,7 @@ fn walkInstruction(
13191334 const un_node = data[inst_index].un_node;
13201335 const bin_index = self.exprs.items.len;
13211336 try self.exprs.append(self.arena, .{ .builtin = .{ .param = 0 } });
1322 const param = try self.walkRef(file, parent_scope, parent_line, un_node.operand, false);
1337 const param = try self.walkRef(file, parent_scope, parent_src, un_node.operand, false);
13231338
13241339 const param_index = self.exprs.items.len;
13251340 try self.exprs.append(self.arena, param.expr);
......@@ -1368,14 +1383,14 @@ fn walkInstruction(
13681383 var lhs: DocData.WalkResult = try self.walkRef(
13691384 file,
13701385 parent_scope,
1371 parent_line,
1386 parent_src,
13721387 extra.data.lhs,
13731388 false,
13741389 );
13751390 var rhs: DocData.WalkResult = try self.walkRef(
13761391 file,
13771392 parent_scope,
1378 parent_line,
1393 parent_src,
13791394 extra.data.rhs,
13801395 false,
13811396 );
......@@ -1398,14 +1413,14 @@ fn walkInstruction(
13981413 var lhs: DocData.WalkResult = try self.walkRef(
13991414 file,
14001415 parent_scope,
1401 parent_line,
1416 parent_src,
14021417 extra.data.lhs,
14031418 false,
14041419 );
14051420 var rhs: DocData.WalkResult = try self.walkRef(
14061421 file,
14071422 parent_scope,
1408 parent_line,
1423 parent_src,
14091424 extra.data.rhs,
14101425 false,
14111426 );
......@@ -1428,14 +1443,14 @@ fn walkInstruction(
14281443 var lhs: DocData.WalkResult = try self.walkRef(
14291444 file,
14301445 parent_scope,
1431 parent_line,
1446 parent_src,
14321447 extra.data.lhs,
14331448 false,
14341449 );
14351450 var rhs: DocData.WalkResult = try self.walkRef(
14361451 file,
14371452 parent_scope,
1438 parent_line,
1453 parent_src,
14391454 extra.data.rhs,
14401455 false,
14411456 );
......@@ -1455,7 +1470,7 @@ fn walkInstruction(
14551470
14561471 // var operand: DocData.WalkResult = try self.walkRef(
14571472 // file,
1458 // parent_scope, parent_line,
1473 // parent_scope, parent_src,
14591474 // un_node.operand,
14601475 // false,
14611476 // );
......@@ -1464,7 +1479,8 @@ fn walkInstruction(
14641479 // },
14651480 .overflow_arithmetic_ptr => {
14661481 const un_node = data[inst_index].un_node;
1467 const elem_type_ref = try self.walkRef(file, parent_scope, parent_line, un_node.operand, false);
1482
1483 const elem_type_ref = try self.walkRef(file, parent_scope, parent_src, un_node.operand, false);
14681484 const type_slot_index = self.types.items.len;
14691485 try self.types.append(self.arena, .{
14701486 .Pointer = .{
......@@ -1489,7 +1505,7 @@ fn walkInstruction(
14891505 const elem_type_ref = try self.walkRef(
14901506 file,
14911507 parent_scope,
1492 parent_line,
1508 parent_src,
14931509 extra.data.elem_type,
14941510 false,
14951511 );
......@@ -1499,7 +1515,7 @@ fn walkInstruction(
14991515 var sentinel: ?DocData.Expr = null;
15001516 if (ptr.flags.has_sentinel) {
15011517 const ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
1502 const ref_result = try self.walkRef(file, parent_scope, parent_line, ref, false);
1518 const ref_result = try self.walkRef(file, parent_scope, parent_src, ref, false);
15031519 sentinel = ref_result.expr;
15041520 extra_index += 1;
15051521 }
......@@ -1507,21 +1523,21 @@ fn walkInstruction(
15071523 var @"align": ?DocData.Expr = null;
15081524 if (ptr.flags.has_align) {
15091525 const ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
1510 const ref_result = try self.walkRef(file, parent_scope, parent_line, ref, false);
1526 const ref_result = try self.walkRef(file, parent_scope, parent_src, ref, false);
15111527 @"align" = ref_result.expr;
15121528 extra_index += 1;
15131529 }
15141530 var address_space: ?DocData.Expr = null;
15151531 if (ptr.flags.has_addrspace) {
15161532 const ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
1517 const ref_result = try self.walkRef(file, parent_scope, parent_line, ref, false);
1533 const ref_result = try self.walkRef(file, parent_scope, parent_src, ref, false);
15181534 address_space = ref_result.expr;
15191535 extra_index += 1;
15201536 }
15211537 var bit_start: ?DocData.Expr = null;
15221538 if (ptr.flags.has_bit_range) {
15231539 const ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
1524 const ref_result = try self.walkRef(file, parent_scope, parent_line, ref, false);
1540 const ref_result = try self.walkRef(file, parent_scope, parent_src, ref, false);
15251541 address_space = ref_result.expr;
15261542 extra_index += 1;
15271543 }
......@@ -1529,7 +1545,7 @@ fn walkInstruction(
15291545 var host_size: ?DocData.Expr = null;
15301546 if (ptr.flags.has_bit_range) {
15311547 const ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
1532 const ref_result = try self.walkRef(file, parent_scope, parent_line, ref, false);
1548 const ref_result = try self.walkRef(file, parent_scope, parent_src, ref, false);
15331549 host_size = ref_result.expr;
15341550 }
15351551
......@@ -1558,9 +1574,10 @@ fn walkInstruction(
15581574 },
15591575 .array_type => {
15601576 const pl_node = data[inst_index].pl_node;
1577
15611578 const bin = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index).data;
1562 const len = try self.walkRef(file, parent_scope, parent_line, bin.lhs, false);
1563 const child = try self.walkRef(file, parent_scope, parent_line, bin.rhs, false);
1579 const len = try self.walkRef(file, parent_scope, parent_src, bin.lhs, false);
1580 const child = try self.walkRef(file, parent_scope, parent_src, bin.rhs, false);
15641581
15651582 const type_slot_index = self.types.items.len;
15661583 try self.types.append(self.arena, .{
......@@ -1578,9 +1595,9 @@ fn walkInstruction(
15781595 .array_type_sentinel => {
15791596 const pl_node = data[inst_index].pl_node;
15801597 const extra = file.zir.extraData(Zir.Inst.ArrayTypeSentinel, pl_node.payload_index);
1581 const len = try self.walkRef(file, parent_scope, parent_line, extra.data.len, false);
1582 const sentinel = try self.walkRef(file, parent_scope, parent_line, extra.data.sentinel, false);
1583 const elem_type = try self.walkRef(file, parent_scope, parent_line, extra.data.elem_type, false);
1598 const len = try self.walkRef(file, parent_scope, parent_src, extra.data.len, false);
1599 const sentinel = try self.walkRef(file, parent_scope, parent_src, extra.data.sentinel, false);
1600 const elem_type = try self.walkRef(file, parent_scope, parent_src, extra.data.elem_type, false);
15841601
15851602 const type_slot_index = self.types.items.len;
15861603 try self.types.append(self.arena, .{
......@@ -1602,10 +1619,10 @@ fn walkInstruction(
16021619 const array_data = try self.arena.alloc(usize, operands.len - 1);
16031620
16041621 std.debug.assert(operands.len > 0);
1605 var array_type = try self.walkRef(file, parent_scope, parent_line, operands[0], false);
1622 var array_type = try self.walkRef(file, parent_scope, parent_src, operands[0], false);
16061623
16071624 for (operands[1..]) |op, idx| {
1608 const wr = try self.walkRef(file, parent_scope, parent_line, op, false);
1625 const wr = try self.walkRef(file, parent_scope, parent_src, op, false);
16091626 const expr_index = self.exprs.items.len;
16101627 try self.exprs.append(self.arena, wr.expr);
16111628 array_data[idx] = expr_index;
......@@ -1623,7 +1640,7 @@ fn walkInstruction(
16231640 const array_data = try self.arena.alloc(usize, operands.len);
16241641
16251642 for (operands) |op, idx| {
1626 const wr = try self.walkRef(file, parent_scope, parent_line, op, false);
1643 const wr = try self.walkRef(file, parent_scope, parent_src, op, false);
16271644 const expr_index = self.exprs.items.len;
16281645 try self.exprs.append(self.arena, wr.expr);
16291646 array_data[idx] = expr_index;
......@@ -1641,10 +1658,10 @@ fn walkInstruction(
16411658 const array_data = try self.arena.alloc(usize, operands.len - 1);
16421659
16431660 std.debug.assert(operands.len > 0);
1644 var array_type = try self.walkRef(file, parent_scope, parent_line, operands[0], false);
1661 var array_type = try self.walkRef(file, parent_scope, parent_src, operands[0], false);
16451662
16461663 for (operands[1..]) |op, idx| {
1647 const wr = try self.walkRef(file, parent_scope, parent_line, op, false);
1664 const wr = try self.walkRef(file, parent_scope, parent_src, op, false);
16481665 const expr_index = self.exprs.items.len;
16491666 try self.exprs.append(self.arena, wr.expr);
16501667 array_data[idx] = expr_index;
......@@ -1673,7 +1690,7 @@ fn walkInstruction(
16731690 const array_data = try self.arena.alloc(usize, operands.len);
16741691
16751692 for (operands) |op, idx| {
1676 const wr = try self.walkRef(file, parent_scope, parent_line, op, false);
1693 const wr = try self.walkRef(file, parent_scope, parent_src, op, false);
16771694 const expr_index = self.exprs.items.len;
16781695 try self.exprs.append(self.arena, wr.expr);
16791696 array_data[idx] = expr_index;
......@@ -1705,10 +1722,11 @@ fn walkInstruction(
17051722 },
17061723 .negate => {
17071724 const un_node = data[inst_index].un_node;
1725
17081726 var operand: DocData.WalkResult = try self.walkRef(
17091727 file,
17101728 parent_scope,
1711 parent_line,
1729 parent_src,
17121730 un_node.operand,
17131731 need_type,
17141732 );
......@@ -1727,10 +1745,11 @@ fn walkInstruction(
17271745 },
17281746 .size_of => {
17291747 const un_node = data[inst_index].un_node;
1748
17301749 const operand = try self.walkRef(
17311750 file,
17321751 parent_scope,
1733 parent_line,
1752 parent_src,
17341753 un_node.operand,
17351754 false,
17361755 );
......@@ -1744,10 +1763,11 @@ fn walkInstruction(
17441763 .bit_size_of => {
17451764 // not working correctly with `align()`
17461765 const un_node = data[inst_index].un_node;
1766
17471767 const operand = try self.walkRef(
17481768 file,
17491769 parent_scope,
1750 parent_line,
1770 parent_src,
17511771 un_node.operand,
17521772 need_type,
17531773 );
......@@ -1765,7 +1785,7 @@ fn walkInstruction(
17651785 const operand = try self.walkRef(
17661786 file,
17671787 parent_scope,
1768 parent_line,
1788 parent_src,
17691789 un_node.operand,
17701790 false,
17711791 );
......@@ -1782,7 +1802,8 @@ fn walkInstruction(
17821802 const pl_node = data[inst_index].pl_node;
17831803 const extra = file.zir.extraData(Zir.Inst.SwitchBlock, pl_node.payload_index);
17841804 const cond_index = self.exprs.items.len;
1785 _ = try self.walkRef(file, parent_scope, parent_line, extra.data.operand, false);
1805
1806 _ = try self.walkRef(file, parent_scope, parent_src, extra.data.operand, false);
17861807
17871808 const ast_index = self.ast_nodes.items.len;
17881809 const type_index = self.types.items.len - 1;
......@@ -1810,7 +1831,7 @@ fn walkInstruction(
18101831 const operand = try self.walkRef(
18111832 file,
18121833 parent_scope,
1813 parent_line,
1834 parent_src,
18141835 un_node.operand,
18151836 need_type,
18161837 );
......@@ -1833,10 +1854,11 @@ fn walkInstruction(
18331854
18341855 .typeof => {
18351856 const un_node = data[inst_index].un_node;
1857
18361858 const operand = try self.walkRef(
18371859 file,
18381860 parent_scope,
1839 parent_line,
1861 parent_src,
18401862 un_node.operand,
18411863 need_type,
18421864 );
......@@ -1852,11 +1874,10 @@ fn walkInstruction(
18521874 const pl_node = data[inst_index].pl_node;
18531875 const extra = file.zir.extraData(Zir.Inst.Block, pl_node.payload_index);
18541876 const body = file.zir.extra[extra.end..][extra.data.body_len - 1];
1855
18561877 var operand: DocData.WalkResult = try self.walkRef(
18571878 file,
18581879 parent_scope,
1859 parent_line,
1880 parent_src,
18601881 data[body].@"break".operand,
18611882 false,
18621883 );
......@@ -1872,10 +1893,11 @@ fn walkInstruction(
18721893 .type_info => {
18731894 // @check
18741895 const un_node = data[inst_index].un_node;
1896
18751897 const operand = try self.walkRef(
18761898 file,
18771899 parent_scope,
1878 parent_line,
1900 parent_src,
18791901 un_node.operand,
18801902 need_type,
18811903 );
......@@ -1894,7 +1916,7 @@ fn walkInstruction(
18941916 const dest_type_walk = try self.walkRef(
18951917 file,
18961918 parent_scope,
1897 parent_line,
1919 parent_src,
18981920 extra.data.dest_type,
18991921 false,
19001922 );
......@@ -1902,7 +1924,7 @@ fn walkInstruction(
19021924 const operand = try self.walkRef(
19031925 file,
19041926 parent_scope,
1905 parent_line,
1927 parent_src,
19061928 extra.data.operand,
19071929 false,
19081930 );
......@@ -1927,10 +1949,11 @@ fn walkInstruction(
19271949 },
19281950 .optional_type => {
19291951 const un_node = data[inst_index].un_node;
1952
19301953 const operand: DocData.WalkResult = try self.walkRef(
19311954 file,
19321955 parent_scope,
1933 parent_line,
1956 parent_src,
19341957 un_node.operand,
19351958 false,
19361959 );
......@@ -2014,7 +2037,7 @@ fn walkInstruction(
20142037 }
20152038 }
20162039
2017 break :blk try self.walkRef(file, parent_scope, parent_line, lhs_ref, false);
2040 break :blk try self.walkRef(file, parent_scope, parent_src, lhs_ref, false);
20182041 };
20192042 try path.append(self.arena, wr.expr);
20202043
......@@ -2065,7 +2088,7 @@ fn walkInstruction(
20652088 return self.walkRef(
20662089 file,
20672090 parent_scope,
2068 parent_line,
2091 parent_src,
20692092 getBlockInlineBreak(file.zir, inst_index),
20702093 need_type,
20712094 );
......@@ -2092,13 +2115,18 @@ fn walkInstruction(
20922115 Zir.Inst.FieldType,
20932116 field_pl_node.payload_index,
20942117 );
2118 const field_src = try self.srcLocInfo(
2119 file,
2120 field_pl_node.src_node,
2121 parent_src,
2122 );
20952123
20962124 // On first iteration use field info to find out the struct type
20972125 if (idx == extra.end) {
20982126 const wr = try self.walkRef(
20992127 file,
21002128 parent_scope,
2101 parent_line,
2129 field_src,
21022130 field_extra.data.container_type,
21032131 false,
21042132 );
......@@ -2109,7 +2137,7 @@ fn walkInstruction(
21092137 const value = try self.walkRef(
21102138 file,
21112139 parent_scope,
2112 parent_line,
2140 parent_src,
21132141 init_extra.data.init,
21142142 need_type,
21152143 );
......@@ -2123,10 +2151,11 @@ fn walkInstruction(
21232151 },
21242152 .struct_init_empty => {
21252153 const un_node = data[inst_index].un_node;
2154
21262155 var operand: DocData.WalkResult = try self.walkRef(
21272156 file,
21282157 parent_scope,
2129 parent_line,
2158 parent_src,
21302159 un_node.operand,
21312160 false,
21322161 );
......@@ -2159,7 +2188,7 @@ fn walkInstruction(
21592188 const value = try self.walkRef(
21602189 file,
21612190 parent_scope,
2162 parent_line,
2191 parent_src,
21632192 init_extra.data.init,
21642193 need_type,
21652194 );
......@@ -2235,7 +2264,7 @@ fn walkInstruction(
22352264 const pl_node = data[inst_index].pl_node;
22362265 const extra = file.zir.extraData(Zir.Inst.Call, pl_node.payload_index);
22372266
2238 const callee = try self.walkRef(file, parent_scope, parent_line, extra.data.callee, need_type);
2267 const callee = try self.walkRef(file, parent_scope, parent_src, extra.data.callee, need_type);
22392268
22402269 const args_len = extra.data.flags.args_len;
22412270 var args = try self.arena.alloc(DocData.Expr, args_len);
......@@ -2250,7 +2279,7 @@ fn walkInstruction(
22502279 // to show discrepancies between the types of provided
22512280 // arguments and the types declared in the function
22522281 // signature for its parameters.
2253 const wr = try self.walkRef(file, parent_scope, parent_line, ref, false);
2282 const wr = try self.walkRef(file, parent_scope, parent_src, ref, false);
22542283 args[i] = wr.expr;
22552284 }
22562285
......@@ -2281,7 +2310,7 @@ fn walkInstruction(
22812310 const result = self.analyzeFunction(
22822311 file,
22832312 parent_scope,
2284 parent_line,
2313 parent_src,
22852314 inst_index,
22862315 self_ast_node_index,
22872316 type_slot_index,
......@@ -2297,7 +2326,7 @@ fn walkInstruction(
22972326 const result = self.analyzeFancyFunction(
22982327 file,
22992328 parent_scope,
2300 parent_line,
2329 parent_src,
23012330 inst_index,
23022331 self_ast_node_index,
23032332 type_slot_index,
......@@ -2325,7 +2354,7 @@ fn walkInstruction(
23252354
23262355 var array_type: ?DocData.Expr = null;
23272356 for (args) |arg, idx| {
2328 const wr = try self.walkRef(file, parent_scope, parent_line, arg, idx == 0);
2357 const wr = try self.walkRef(file, parent_scope, parent_src, arg, idx == 0);
23292358 if (idx == 0) {
23302359 array_type = wr.typeRef;
23312360 }
......@@ -2357,12 +2386,15 @@ fn walkInstruction(
23572386 .opaque_decl => {
23582387 const small = @bitCast(Zir.Inst.OpaqueDecl.Small, extended.small);
23592388 var extra_index: usize = extended.operand;
2389
23602390 const src_node: ?i32 = if (small.has_src_node) blk: {
23612391 const src_node = @bitCast(i32, file.zir.extra[extra_index]);
23622392 extra_index += 1;
23632393 break :blk src_node;
23642394 } else null;
2365 _ = src_node;
2395
2396 const src_info = try self.srcLocInfo(file, src_node, parent_src);
2397 _ = src_info;
23662398
23672399 const decls_len = if (small.has_decls_len) blk: {
23682400 const decls_len = file.zir.extra[extra_index];
......@@ -2419,7 +2451,8 @@ fn walkInstruction(
24192451 extra_index += 1;
24202452 break :blk src_node;
24212453 } else null;
2422 _ = src_node;
2454
2455 const src_info = try self.srcLocInfo(file, src_node, parent_src);
24232456
24242457 const tag_type: ?Ref = if (small.has_tag_type) blk: {
24252458 const tag_type = file.zir.extra[extra_index];
......@@ -2470,7 +2503,7 @@ fn walkInstruction(
24702503 extra_index = try self.walkDecls(
24712504 file,
24722505 &scope,
2473 parent_line,
2506 src_info,
24742507 decls_first_index,
24752508 decls_len,
24762509 &decl_indexes,
......@@ -2491,7 +2524,7 @@ fn walkInstruction(
24912524 try self.collectUnionFieldInfo(
24922525 file,
24932526 &scope,
2494 parent_line,
2527 src_info,
24952528 fields_len,
24962529 &field_type_refs,
24972530 &field_name_indexes,
......@@ -2541,7 +2574,8 @@ fn walkInstruction(
25412574 extra_index += 1;
25422575 break :blk src_node;
25432576 } else null;
2544 _ = src_node;
2577
2578 const src_info = try self.srcLocInfo(file, src_node, parent_src);
25452579
25462580 const tag_type: ?Ref = if (small.has_tag_type) blk: {
25472581 const tag_type = file.zir.extra[extra_index];
......@@ -2592,7 +2626,7 @@ fn walkInstruction(
25922626 extra_index = try self.walkDecls(
25932627 file,
25942628 &scope,
2595 parent_line,
2629 src_info,
25962630 decls_first_index,
25972631 decls_len,
25982632 &decl_indexes,
......@@ -2687,7 +2721,8 @@ fn walkInstruction(
26872721 extra_index += 1;
26882722 break :blk src_node;
26892723 } else null;
2690 _ = src_node;
2724
2725 const src_info = try self.srcLocInfo(file, src_node, parent_src);
26912726
26922727 const fields_len = if (small.has_fields_len) blk: {
26932728 const fields_len = file.zir.extra[extra_index];
......@@ -2736,7 +2771,7 @@ fn walkInstruction(
27362771 extra_index = try self.walkDecls(
27372772 file,
27382773 &scope,
2739 parent_line,
2774 src_info,
27402775 decls_first_index,
27412776 decls_len,
27422777 &decl_indexes,
......@@ -2749,7 +2784,7 @@ fn walkInstruction(
27492784 try self.collectStructFieldInfo(
27502785 file,
27512786 &scope,
2752 parent_line,
2787 src_info,
27532788 fields_len,
27542789 &field_type_refs,
27552790 &field_name_indexes,
......@@ -2793,7 +2828,7 @@ fn walkInstruction(
27932828 const extra = file.zir.extraData(Zir.Inst.UnNode, extended.operand).data;
27942829 const bin_index = self.exprs.items.len;
27952830 try self.exprs.append(self.arena, .{ .builtin = .{ .param = 0 } });
2796 const param = try self.walkRef(file, parent_scope, parent_line, extra.operand, false);
2831 const param = try self.walkRef(file, parent_scope, parent_src, extra.operand, false);
27972832
27982833 const param_index = self.exprs.items.len;
27992834 try self.exprs.append(self.arena, param.expr);
......@@ -2821,7 +2856,7 @@ fn walkDecls(
28212856 self: *Autodoc,
28222857 file: *File,
28232858 scope: *Scope,
2824 parent_line: usize,
2859 parent_src: SrcLocInfo,
28252860 decls_first_index: usize,
28262861 decls_len: u32,
28272862 decl_indexes: *std.ArrayListUnmanaged(usize),
......@@ -2854,7 +2889,8 @@ fn walkDecls(
28542889
28552890 // const hash_u32s = file.zir.extra[extra_index..][0..4];
28562891 extra_index += 4;
2857 const line = parent_line + file.zir.extra[extra_index];
2892
2893 //const line = file.zir.extra[extra_index];
28582894 extra_index += 1;
28592895 const decl_name_index = file.zir.extra[extra_index];
28602896 extra_index += 1;
......@@ -2989,12 +3025,17 @@ fn walkDecls(
29893025 else
29903026 null;
29913027
3028 // This is known to work because decl values are always block_inlines
3029 const data = file.zir.instructions.items(.data);
3030 const value_pl_node = data[value_index].pl_node;
3031 const decl_src = try self.srcLocInfo(file, value_pl_node.src_node, parent_src);
3032
29923033 // astnode
29933034 const ast_node_index = idx: {
29943035 const idx = self.ast_nodes.items.len;
29953036 try self.ast_nodes.append(self.arena, .{
2996 .file = self.files.getIndex(file) orelse unreachable,
2997 .line = line,
3037 .file = self.files.getIndex(file).?,
3038 .line = decl_src.line,
29983039 .col = 0,
29993040 .docs = doc_comment,
30003041 .fields = null, // walkInstruction will fill `fields` if necessary
......@@ -3005,7 +3046,7 @@ fn walkDecls(
30053046 const walk_result = if (is_test) // TODO: decide if tests should show up at all
30063047 DocData.WalkResult{ .expr = .{ .void = .{} } }
30073048 else
3008 try self.walkInstruction(file, scope, line, value_index, true);
3049 try self.walkInstruction(file, scope, decl_src, value_index, true);
30093050
30103051 if (is_pub) {
30113052 try decl_indexes.append(self.arena, decls_slot_index);
......@@ -3401,7 +3442,7 @@ fn analyzeFancyFunction(
34013442 self: *Autodoc,
34023443 file: *File,
34033444 scope: *Scope,
3404 parent_line: usize,
3445 parent_src: SrcLocInfo,
34053446 inst_index: usize,
34063447 self_ast_node_index: usize,
34073448 type_slot_index: usize,
......@@ -3466,7 +3507,7 @@ fn analyzeFancyFunction(
34663507
34673508 const break_index = file.zir.extra[extra.end..][extra.data.body_len - 1];
34683509 const break_operand = data[break_index].@"break".operand;
3469 const param_type_ref = try self.walkRef(file, scope, parent_line, break_operand, false);
3510 const param_type_ref = try self.walkRef(file, scope, parent_src, break_operand, false);
34703511
34713512 param_type_refs.appendAssumeCapacity(param_type_ref.expr);
34723513 },
......@@ -3475,8 +3516,8 @@ fn analyzeFancyFunction(
34753516
34763517 self.ast_nodes.items[self_ast_node_index].fields = param_ast_indexes.items;
34773518
3478 const inst_data = data[inst_index].pl_node;
3479 const extra = file.zir.extraData(Zir.Inst.FuncFancy, inst_data.payload_index);
3519 const pl_node = data[inst_index].pl_node;
3520 const extra = file.zir.extraData(Zir.Inst.FuncFancy, pl_node.payload_index);
34803521
34813522 var extra_index: usize = extra.end;
34823523
......@@ -3490,7 +3531,7 @@ fn analyzeFancyFunction(
34903531 if (extra.data.bits.has_align_ref) {
34913532 const align_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
34923533 align_index = self.exprs.items.len;
3493 _ = try self.walkRef(file, scope, parent_line, align_ref, false);
3534 _ = try self.walkRef(file, scope, parent_src, align_ref, false);
34943535 extra_index += 1;
34953536 } else if (extra.data.bits.has_align_body) {
34963537 const align_body_len = file.zir.extra[extra_index];
......@@ -3507,7 +3548,7 @@ fn analyzeFancyFunction(
35073548 if (extra.data.bits.has_addrspace_ref) {
35083549 const addrspace_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
35093550 addrspace_index = self.exprs.items.len;
3510 _ = try self.walkRef(file, scope, parent_line, addrspace_ref, false);
3551 _ = try self.walkRef(file, scope, parent_src, addrspace_ref, false);
35113552 extra_index += 1;
35123553 } else if (extra.data.bits.has_addrspace_body) {
35133554 const addrspace_body_len = file.zir.extra[extra_index];
......@@ -3524,7 +3565,7 @@ fn analyzeFancyFunction(
35243565 if (extra.data.bits.has_section_ref) {
35253566 const section_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
35263567 section_index = self.exprs.items.len;
3527 _ = try self.walkRef(file, scope, parent_line, section_ref, false);
3568 _ = try self.walkRef(file, scope, parent_src, section_ref, false);
35283569 extra_index += 1;
35293570 } else if (extra.data.bits.has_section_body) {
35303571 const section_body_len = file.zir.extra[extra_index];
......@@ -3541,7 +3582,7 @@ fn analyzeFancyFunction(
35413582 if (extra.data.bits.has_cc_ref) {
35423583 const cc_ref = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
35433584 cc_index = self.exprs.items.len;
3544 _ = try self.walkRef(file, scope, parent_line, cc_ref, false);
3585 _ = try self.walkRef(file, scope, parent_src, cc_ref, false);
35453586 extra_index += 1;
35463587 } else if (extra.data.bits.has_cc_body) {
35473588 const cc_body_len = file.zir.extra[extra_index];
......@@ -3560,14 +3601,14 @@ fn analyzeFancyFunction(
35603601 .none => DocData.Expr{ .void = .{} },
35613602 else => blk: {
35623603 const ref = fn_info.ret_ty_ref;
3563 const wr = try self.walkRef(file, scope, parent_line, ref, false);
3604 const wr = try self.walkRef(file, scope, parent_src, ref, false);
35643605 break :blk wr.expr;
35653606 },
35663607 },
35673608 else => blk: {
35683609 const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];
35693610 const break_operand = data[last_instr_index].@"break".operand;
3570 const wr = try self.walkRef(file, scope, parent_line, break_operand, false);
3611 const wr = try self.walkRef(file, scope, parent_src, break_operand, false);
35713612 break :blk wr.expr;
35723613 },
35733614 };
......@@ -3582,7 +3623,7 @@ fn analyzeFancyFunction(
35823623 break :blk try self.getGenericReturnType(
35833624 file,
35843625 scope,
3585 parent_line,
3626 parent_src,
35863627 fn_info.body[fn_info.body.len - 1],
35873628 );
35883629 } else {
......@@ -3619,7 +3660,7 @@ fn analyzeFunction(
36193660 self: *Autodoc,
36203661 file: *File,
36213662 scope: *Scope,
3622 parent_line: usize,
3663 parent_src: SrcLocInfo,
36233664 inst_index: usize,
36243665 self_ast_node_index: usize,
36253666 type_slot_index: usize,
......@@ -3685,7 +3726,7 @@ fn analyzeFunction(
36853726
36863727 const break_index = file.zir.extra[extra.end..][extra.data.body_len - 1];
36873728 const break_operand = data[break_index].@"break".operand;
3688 const param_type_ref = try self.walkRef(file, scope, parent_line, break_operand, false);
3729 const param_type_ref = try self.walkRef(file, scope, parent_src, break_operand, false);
36893730
36903731 param_type_refs.appendAssumeCapacity(param_type_ref.expr);
36913732 },
......@@ -3698,14 +3739,14 @@ fn analyzeFunction(
36983739 .none => DocData.Expr{ .void = .{} },
36993740 else => blk: {
37003741 const ref = fn_info.ret_ty_ref;
3701 const wr = try self.walkRef(file, scope, parent_line, ref, false);
3742 const wr = try self.walkRef(file, scope, parent_src, ref, false);
37023743 break :blk wr.expr;
37033744 },
37043745 },
37053746 else => blk: {
37063747 const last_instr_index = fn_info.ret_ty_body[fn_info.ret_ty_body.len - 1];
37073748 const break_operand = data[last_instr_index].@"break".operand;
3708 const wr = try self.walkRef(file, scope, parent_line, break_operand, false);
3749 const wr = try self.walkRef(file, scope, parent_src, break_operand, false);
37093750 break :blk wr.expr;
37103751 },
37113752 };
......@@ -3720,7 +3761,7 @@ fn analyzeFunction(
37203761 break :blk try self.getGenericReturnType(
37213762 file,
37223763 scope,
3723 parent_line,
3764 parent_src,
37243765 fn_info.body[fn_info.body.len - 1],
37253766 );
37263767 } else {
......@@ -3761,11 +3802,11 @@ fn getGenericReturnType(
37613802 self: *Autodoc,
37623803 file: *File,
37633804 scope: *Scope,
3764 parent_line: usize, // function decl line
3805 parent_src: SrcLocInfo, // function decl line
37653806 body_end: usize,
37663807) !DocData.Expr {
37673808 // TODO: compute the correct line offset
3768 const wr = try self.walkInstruction(file, scope, parent_line, body_end, false);
3809 const wr = try self.walkInstruction(file, scope, parent_src, body_end, false);
37693810 return wr.expr;
37703811}
37713812
......@@ -3773,7 +3814,7 @@ fn collectUnionFieldInfo(
37733814 self: *Autodoc,
37743815 file: *File,
37753816 scope: *Scope,
3776 parent_line: usize,
3817 parent_src: SrcLocInfo,
37773818 fields_len: usize,
37783819 field_type_refs: *std.ArrayListUnmanaged(DocData.Expr),
37793820 field_name_indexes: *std.ArrayListUnmanaged(usize),
......@@ -3820,7 +3861,7 @@ fn collectUnionFieldInfo(
38203861
38213862 // type
38223863 {
3823 const walk_result = try self.walkRef(file, scope, parent_line, field_type, false);
3864 const walk_result = try self.walkRef(file, scope, parent_src, field_type, false);
38243865 try field_type_refs.append(self.arena, walk_result.expr);
38253866 }
38263867
......@@ -3843,7 +3884,7 @@ fn collectStructFieldInfo(
38433884 self: *Autodoc,
38443885 file: *File,
38453886 scope: *Scope,
3846 parent_line: usize,
3887 parent_src: SrcLocInfo,
38473888 fields_len: usize,
38483889 field_type_refs: *std.ArrayListUnmanaged(DocData.Expr),
38493890 field_name_indexes: *std.ArrayListUnmanaged(usize),
......@@ -3917,7 +3958,7 @@ fn collectStructFieldInfo(
39173958 for (fields) |field| {
39183959 const type_expr = expr: {
39193960 if (field.type_ref != .none) {
3920 const walk_result = try self.walkRef(file, scope, parent_line, field.type_ref, false);
3961 const walk_result = try self.walkRef(file, scope, parent_src, field.type_ref, false);
39213962 break :expr walk_result.expr;
39223963 }
39233964
......@@ -3927,7 +3968,7 @@ fn collectStructFieldInfo(
39273968
39283969 const break_inst = body[body.len - 1];
39293970 const operand = data[break_inst].@"break".operand;
3930 const walk_result = try self.walkRef(file, scope, parent_line, operand, false);
3971 const walk_result = try self.walkRef(file, scope, parent_src, operand, false);
39313972 break :expr walk_result.expr;
39323973 };
39333974
......@@ -3957,7 +3998,7 @@ fn walkRef(
39573998 self: *Autodoc,
39583999 file: *File,
39594000 parent_scope: *Scope,
3960 parent_line: usize,
4001 parent_src: SrcLocInfo,
39614002 ref: Ref,
39624003 need_type: bool, // true when the caller needs also a typeRef for the return value
39634004) AutodocErrors!DocData.WalkResult {
......@@ -4069,7 +4110,7 @@ fn walkRef(
40694110 }
40704111 } else {
40714112 const zir_index = enum_value - Ref.typed_value_map.len;
4072 return self.walkInstruction(file, parent_scope, parent_line, zir_index, need_type);
4113 return self.walkInstruction(file, parent_scope, parent_src, zir_index, need_type);
40734114 }
40744115}
40754116
......@@ -4122,3 +4163,28 @@ fn writePackageTableToJson(
41224163 }
41234164 try jsw.endObject();
41244165}
4166
4167fn srcLocInfo(
4168 self: Autodoc,
4169 file: *File,
4170 src_node: ?i32,
4171 parent_src: SrcLocInfo,
4172) !SrcLocInfo {
4173 if (src_node) |unwrapped_src_node| {
4174 const sn = parent_src.src_node + unwrapped_src_node;
4175 const tree = try file.getTree(self.module.gpa);
4176 const node_idx = @bitCast(Ast.Node.Index, sn);
4177 const tokens = tree.nodes.items(.main_token);
4178
4179 const tok_idx = tokens[node_idx];
4180 const start = tree.tokens.items(.start)[tok_idx];
4181 const loc = tree.tokenLocation(parent_src.bytes, tok_idx);
4182 return .{
4183 .line = parent_src.line + loc.line,
4184 .bytes = start,
4185 .src_node = sn,
4186 };
4187 } else {
4188 return parent_src;
4189 }
4190}