authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-03-22 18:07:10+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:11-07:00
logdf3074aa985da82a01f94ba6b9a43535c7d438a9
tree8dd108022b69fe083ed58822f339572b1abf4be5
parent5f0ab34cc5b5d4d59bf4665964b36ae8c218df76

autodoc: fix offset math for decls and change TODOs from panics to just

prints

1 files changed, 248 insertions(+), 90 deletions(-)

src/Autodoc.zig+248-90
...@@ -411,17 +411,17 @@ const DocData = struct {...@@ -411,17 +411,17 @@ const DocData = struct {
411 },411 },
412 Enum: struct {412 Enum: struct {
413 name: []const u8,413 name: []const u8,
414 src: ?usize = null, // index into astNodes414 src: usize, // index into astNodes
415 privDecls: ?[]usize = null, // index into decls415 privDecls: []usize = &.{}, // index into decls
416 pubDecls: ?[]usize = null, // index into decls416 pubDecls: []usize = &.{}, // index into decls
417 // (use src->fields to find field names)417 // (use src->fields to find field names)
418 },418 },
419 Union: struct {419 Union: struct {
420 name: []const u8,420 name: []const u8,
421 src: ?usize = null, // index into astNodes421 src: usize, // index into astNodes
422 privDecls: ?[]usize = null, // index into decls422 privDecls: []usize = &.{}, // index into decls
423 pubDecls: ?[]usize = null, // index into decls423 pubDecls: []usize = &.{}, // index into decls
424 fields: ?[]WalkResult = null, // (use src->fields to find names)424 fields: []WalkResult = &.{}, // (use src->fields to find names)
425 },425 },
426 Fn: struct {426 Fn: struct {
427 name: []const u8,427 name: []const u8,
...@@ -465,6 +465,7 @@ const DocData = struct {...@@ -465,6 +465,7 @@ const DocData = struct {
465 .Struct => |v| try printTypeBody(v, options, w),465 .Struct => |v| try printTypeBody(v, options, w),
466 .Fn => |v| try printTypeBody(v, options, w),466 .Fn => |v| try printTypeBody(v, options, w),
467 .Union => |v| try printTypeBody(v, options, w),467 .Union => |v| try printTypeBody(v, options, w),
468 .ErrorSet => |v| try printTypeBody(v, options, w),
468 .Enum => |v| try printTypeBody(v, options, w),469 .Enum => |v| try printTypeBody(v, options, w),
469 .Int => |v| try printTypeBody(v, options, w),470 .Int => |v| try printTypeBody(v, options, w),
470 .Float => |v| try printTypeBody(v, options, w),471 .Float => |v| try printTypeBody(v, options, w),
...@@ -604,8 +605,12 @@ const DocData = struct {...@@ -604,8 +605,12 @@ const DocData = struct {
604 , .{});605 , .{});
605 try v.typeRef.jsonStringify(options, w);606 try v.typeRef.jsonStringify(options, w);
606 try w.print(607 try w.print(
607 \\, "value": {s}{} }} }}608 \\, "value": {s}1 }} }}
608 , .{ neg, v.value });609 , .{neg});
610 // TODO: uncomment once float panic is fixed in stdlib
611 // try w.print(
612 // \\, "value": {s}{e} }} }}
613 // , .{ neg, v.value });
609 },614 },
610 .bool => |v| {615 .bool => |v| {
611 try w.print(616 try w.print(
...@@ -685,12 +690,13 @@ fn walkInstruction(...@@ -685,12 +690,13 @@ fn walkInstruction(
685690
686 switch (tags[inst_index]) {691 switch (tags[inst_index]) {
687 else => {692 else => {
688 panicWithContext(693 printWithContext(
689 file,694 file,
690 inst_index,695 inst_index,
691 "TODO: implement `{s}` for walkInstruction\n\n",696 "TODO: implement `{s}` for walkInstruction\n\n",
692 .{@tagName(tags[inst_index])},697 .{@tagName(tags[inst_index])},
693 );698 );
699 return self.cteTodo(@tagName(tags[inst_index]));
694 },700 },
695 .closure_get => {701 .closure_get => {
696 const inst_node = data[inst_index].inst_node;702 const inst_node = data[inst_index].inst_node;
...@@ -752,17 +758,11 @@ fn walkInstruction(...@@ -752,17 +758,11 @@ fn walkInstruction(
752758
753 return DocData.WalkResult{ .compileError = operand.string };759 return DocData.WalkResult{ .compileError = operand.string };
754 },760 },
755 .switch_block => return self.cteTodo("[switch]"),
756 .enum_literal => {761 .enum_literal => {
757 const str_tok = data[inst_index].str_tok;762 const str_tok = data[inst_index].str_tok;
758 const literal = file.zir.nullTerminatedString(str_tok.start);763 const literal = file.zir.nullTerminatedString(str_tok.start);
759 return DocData.WalkResult{ .enumLiteral = literal };764 return DocData.WalkResult{ .enumLiteral = literal };
760 },765 },
761 .div_exact, .div => return self.cteTodo("@div(...)"),
762 .mul => return self.cteTodo("@mul(...)"),
763 .array_mul => return self.cteTodo("a ** b"),
764 .bool_br_and, .bool_br_or => return self.cteTodo("bool op"),
765 .cmp_eq => return self.cteTodo("bool op"),
766 .int => {766 .int => {
767 const int = data[inst_index].int;767 const int = data[inst_index].int;
768 const t = try self.arena.create(DocData.WalkResult);768 const t = try self.arena.create(DocData.WalkResult);
...@@ -849,7 +849,7 @@ fn walkInstruction(...@@ -849,7 +849,7 @@ fn walkInstruction(
849 .negated = false,849 .negated = false,
850 },850 },
851 },851 },
852 .child = typeOfWalkResult(array_data[0]),852 .child = try self.typeOfWalkResult(array_data[0]),
853 },853 },
854 });854 });
855855
...@@ -880,7 +880,17 @@ fn walkInstruction(...@@ -880,7 +880,17 @@ fn walkInstruction(
880 parent_scope,880 parent_scope,
881 un_node.operand,881 un_node.operand,
882 );882 );
883 operand.int.negated = true; // only support ints for now883 switch (operand) {
884 .int => |*int| int.negated = true,
885 else => {
886 printWithContext(
887 file,
888 inst_index,
889 "TODO: support negation for more types",
890 .{},
891 );
892 },
893 }
884 return operand;894 return operand;
885 },895 },
886 .size_of => {896 .size_of => {
...@@ -913,21 +923,19 @@ fn walkInstruction(...@@ -913,21 +923,19 @@ fn walkInstruction(
913 var operand = try self.walkRef(file, parent_scope, extra.data.operand);923 var operand = try self.walkRef(file, parent_scope, extra.data.operand);
914924
915 switch (operand) {925 switch (operand) {
916 else => panicWithContext(926 else => printWithContext(
917 file,927 file,
918 inst_index,928 inst_index,
919 "TODO: handle {s} in `walkInstruction.as_node`\n",929 "TODO: handle {s} in `walkInstruction.as_node`",
920 .{@tagName(operand)},930 .{@tagName(operand)},
921 ),931 ),
922 .refPath, .type, .string, .call, .enumLiteral => {},932 .declRef, .refPath, .type, .string, .call, .enumLiteral => {},
923 // we don't do anything because up until now,933 // we don't do anything because up until now,
924 // I've only seen this used as such:934 // I've only seen this used as such:
925 // @as(@as(type, Baz), .{})935 // @as(@as(type, Baz), .{})
926 // and we don't want to toss away the936 // and we don't want to toss away the
927 // decl_val information (eg by replacing it with937 // decl_val information (eg by replacing it with
928 // a WalkResult.type).938 // a WalkResult.type).
929 // TODO: Actually, this is a good moment to check if
930 // the result is indeed a type!!
931 .comptimeExpr => {939 .comptimeExpr => {
932 self.comptime_exprs.items[operand.comptimeExpr].typeRef = dest_type_ref;940 self.comptime_exprs.items[operand.comptimeExpr].typeRef = dest_type_ref;
933 },941 },
...@@ -1043,7 +1051,7 @@ fn walkInstruction(...@@ -1043,7 +1051,7 @@ fn walkInstruction(
1043 var idx = extra.end;1051 var idx = extra.end;
1044 for (field_vals) |*fv| {1052 for (field_vals) |*fv| {
1045 const init_extra = file.zir.extraData(Zir.Inst.StructInit.Item, idx);1053 const init_extra = file.zir.extraData(Zir.Inst.StructInit.Item, idx);
1046 idx = init_extra.end;1054 defer idx = init_extra.end;
10471055
1048 const field_name = blk: {1056 const field_name = blk: {
1049 const field_inst_index = init_extra.data.field_type;1057 const field_inst_index = init_extra.data.field_type;
...@@ -1176,53 +1184,45 @@ fn walkInstruction(...@@ -1176,53 +1184,45 @@ fn walkInstruction(
1176 );1184 );
1177 },1185 },
1178 .extended => {1186 .extended => {
1179 // NOTE: this code + the subsequent defer block are working towards
1180 // solving pending decl paths that depend on completing the analysis of a type.
1181 // When we don't find a type, the defer will run anyway but shouldn't
1182 // ever be able to find a match inside `decl_paths_pending_on_types`
1183 // TODO: extract this logic into a function and only call it when appropriate.
1184 const type_slot_index = self.types.items.len;
1185 try self.types.append(self.arena, .{ .Unanalyzed = {} });
1186
1187 defer {
1188 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
1189 for (paths.items) |resume_info| {
1190 self.tryResolveRefPath(
1191 resume_info.file,
1192 inst_index,
1193 resume_info.ref_path,
1194 ) catch {
1195 @panic("Out of memory");
1196 };
1197 }
1198
1199 _ = self.ref_paths_pending_on_types.remove(type_slot_index);
1200 // TODO: we should deallocate the arraylist that holds all the
1201 // decl paths. not doing it now since it's arena-allocated
1202 // anyway, but maybe we should put it elsewhere.
1203 }
1204 }
1205
1206 const extended = data[inst_index].extended;1187 const extended = data[inst_index].extended;
1207 switch (extended.opcode) {1188 switch (extended.opcode) {
1208 else => {1189 else => {
1209 panicWithContext(1190 printWithContext(
1210 file,1191 file,
1211 inst_index,1192 inst_index,
1212 "TODO: implement `walkInstruction.extended` for {s}\n\n",1193 "TODO: implement `walkInstruction.extended` for {s}",
1213 .{@tagName(extended.opcode)},1194 .{@tagName(extended.opcode)},
1214 );1195 );
1196 return self.cteTodo(@tagName(extended.opcode));
1215 },1197 },
12161198
1217 .opaque_decl => return self.cteTodo("opaque {...}"),1199 .opaque_decl => return self.cteTodo("opaque {...}"),
1218 .func => {1200 .func => {
1219 return try self.analyzeFunction(1201 const type_slot_index = self.types.items.len;
1202 try self.types.append(self.arena, .{ .Unanalyzed = {} });
1203
1204 const result = try self.analyzeFunction(
1220 file,1205 file,
1221 parent_scope,1206 parent_scope,
1222 inst_index,1207 inst_index,
1223 self_ast_node_index,1208 self_ast_node_index,
1224 type_slot_index,1209 type_slot_index,
1225 );1210 );
1211 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
1212 for (paths.items) |resume_info| {
1213 try self.tryResolveRefPath(
1214 resume_info.file,
1215 inst_index,
1216 resume_info.ref_path,
1217 );
1218 }
1219
1220 _ = self.ref_paths_pending_on_types.remove(type_slot_index);
1221 // TODO: we should deallocate the arraylist that holds all the
1222 // decl paths. not doing it now since it's arena-allocated
1223 // anyway, but maybe we should put it elsewhere.
1224 }
1225 return result;
1226 },1226 },
1227 .variable => {1227 .variable => {
1228 const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);1228 const small = @bitCast(Zir.Inst.ExtendedVar.Small, extended.small);
...@@ -1237,6 +1237,9 @@ fn walkInstruction(...@@ -1237,6 +1237,9 @@ fn walkInstruction(
1237 return value;1237 return value;
1238 },1238 },
1239 .union_decl => {1239 .union_decl => {
1240 const type_slot_index = self.types.items.len;
1241 try self.types.append(self.arena, .{ .Unanalyzed = {} });
1242
1240 var scope: Scope = .{1243 var scope: Scope = .{
1241 .parent = parent_scope,1244 .parent = parent_scope,
1242 .enclosing_type = type_slot_index,1245 .enclosing_type = type_slot_index,
...@@ -1340,9 +1343,27 @@ fn walkInstruction(...@@ -1340,9 +1343,27 @@ fn walkInstruction(
1340 },1343 },
1341 };1344 };
13421345
1346 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
1347 for (paths.items) |resume_info| {
1348 try self.tryResolveRefPath(
1349 resume_info.file,
1350 inst_index,
1351 resume_info.ref_path,
1352 );
1353 }
1354
1355 _ = self.ref_paths_pending_on_types.remove(type_slot_index);
1356 // TODO: we should deallocate the arraylist that holds all the
1357 // decl paths. not doing it now since it's arena-allocated
1358 // anyway, but maybe we should put it elsewhere.
1359 }
1360
1343 return DocData.WalkResult{ .type = type_slot_index };1361 return DocData.WalkResult{ .type = type_slot_index };
1344 },1362 },
1345 .enum_decl => {1363 .enum_decl => {
1364 const type_slot_index = self.types.items.len;
1365 try self.types.append(self.arena, .{ .Unanalyzed = {} });
1366
1346 var scope: Scope = .{1367 var scope: Scope = .{
1347 .parent = parent_scope,1368 .parent = parent_scope,
1348 .enclosing_type = type_slot_index,1369 .enclosing_type = type_slot_index,
...@@ -1470,10 +1491,27 @@ fn walkInstruction(...@@ -1470,10 +1491,27 @@ fn walkInstruction(
1470 .pubDecls = decl_indexes.items,1491 .pubDecls = decl_indexes.items,
1471 },1492 },
1472 };1493 };
1494 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
1495 for (paths.items) |resume_info| {
1496 try self.tryResolveRefPath(
1497 resume_info.file,
1498 inst_index,
1499 resume_info.ref_path,
1500 );
1501 }
1502
1503 _ = self.ref_paths_pending_on_types.remove(type_slot_index);
1504 // TODO: we should deallocate the arraylist that holds all the
1505 // decl paths. not doing it now since it's arena-allocated
1506 // anyway, but maybe we should put it elsewhere.
1507 }
14731508
1474 return DocData.WalkResult{ .type = type_slot_index };1509 return DocData.WalkResult{ .type = type_slot_index };
1475 },1510 },
1476 .struct_decl => {1511 .struct_decl => {
1512 const type_slot_index = self.types.items.len;
1513 try self.types.append(self.arena, .{ .Unanalyzed = {} });
1514
1477 var scope: Scope = .{1515 var scope: Scope = .{
1478 .parent = parent_scope,1516 .parent = parent_scope,
1479 .enclosing_type = type_slot_index,1517 .enclosing_type = type_slot_index,
...@@ -1563,6 +1601,20 @@ fn walkInstruction(...@@ -1563,6 +1601,20 @@ fn walkInstruction(
1563 .fields = field_type_refs.items,1601 .fields = field_type_refs.items,
1564 },1602 },
1565 };1603 };
1604 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
1605 for (paths.items) |resume_info| {
1606 try self.tryResolveRefPath(
1607 resume_info.file,
1608 inst_index,
1609 resume_info.ref_path,
1610 );
1611 }
1612
1613 _ = self.ref_paths_pending_on_types.remove(type_slot_index);
1614 // TODO: we should deallocate the arraylist that holds all the
1615 // decl paths. not doing it now since it's arena-allocated
1616 // anyway, but maybe we should put it elsewhere.
1617 }
15661618
1567 return DocData.WalkResult{ .type = type_slot_index };1619 return DocData.WalkResult{ .type = type_slot_index };
1568 },1620 },
...@@ -1608,9 +1660,9 @@ fn walkDecls(...@@ -1608,9 +1660,9 @@ fn walkDecls(
1608 cur_bit_bag >>= 1;1660 cur_bit_bag >>= 1;
1609 const is_exported = @truncate(u1, cur_bit_bag) != 0;1661 const is_exported = @truncate(u1, cur_bit_bag) != 0;
1610 cur_bit_bag >>= 1;1662 cur_bit_bag >>= 1;
1611 // const has_align = @truncate(u1, cur_bit_bag) != 0;1663 const has_align = @truncate(u1, cur_bit_bag) != 0;
1612 cur_bit_bag >>= 1;1664 cur_bit_bag >>= 1;
1613 // const has_section_or_addrspace = @truncate(u1, cur_bit_bag) != 0;1665 const has_section_or_addrspace = @truncate(u1, cur_bit_bag) != 0;
1614 cur_bit_bag >>= 1;1666 cur_bit_bag >>= 1;
16151667
1616 // const sub_index = extra_index;1668 // const sub_index = extra_index;
...@@ -1626,21 +1678,26 @@ fn walkDecls(...@@ -1626,21 +1678,26 @@ fn walkDecls(
1626 const doc_comment_index = file.zir.extra[extra_index];1678 const doc_comment_index = file.zir.extra[extra_index];
1627 extra_index += 1;1679 extra_index += 1;
16281680
1629 // const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: {1681 const align_inst: Zir.Inst.Ref = if (!has_align) .none else inst: {
1630 // const inst = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);1682 const inst = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
1631 // extra_index += 1;1683 extra_index += 1;
1632 // break :inst inst;1684 break :inst inst;
1633 // };1685 };
1634 // const section_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: {1686 _ = align_inst;
1635 // const inst = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);1687
1636 // extra_index += 1;1688 const section_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: {
1637 // break :inst inst;1689 const inst = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
1638 // };1690 extra_index += 1;
1639 // const addrspace_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: {1691 break :inst inst;
1640 // const inst = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);1692 };
1641 // extra_index += 1;1693 _ = section_inst;
1642 // break :inst inst;1694
1643 // };1695 const addrspace_inst: Zir.Inst.Ref = if (!has_section_or_addrspace) .none else inst: {
1696 const inst = @intToEnum(Zir.Inst.Ref, file.zir.extra[extra_index]);
1697 extra_index += 1;
1698 break :inst inst;
1699 };
1700 _ = addrspace_inst;
16441701
1645 // const pub_str = if (is_pub) "pub " else "";1702 // const pub_str = if (is_pub) "pub " else "";
1646 // const hash_bytes = @bitCast([16]u8, hash_u32s.*);1703 // const hash_bytes = @bitCast([16]u8, hash_u32s.*);
...@@ -1848,6 +1905,7 @@ fn tryResolveRefPath(...@@ -1848,6 +1905,7 @@ fn tryResolveRefPath(
1848 while (j < 10_000) : (j += 1) {1905 while (j < 10_000) : (j += 1) {
1849 switch (resolved_parent) {1906 switch (resolved_parent) {
1850 else => break,1907 else => break,
1908 .this => |t| resolved_parent = .{ .type = t },
1851 .declRef => |decl_index| {1909 .declRef => |decl_index| {
1852 const decl = self.decls.items[decl_index];1910 const decl = self.decls.items[decl_index];
1853 if (decl._analyzed) {1911 if (decl._analyzed) {
...@@ -1927,12 +1985,14 @@ fn tryResolveRefPath(...@@ -1927,12 +1985,14 @@ fn tryResolveRefPath(
1927 else => {1985 else => {
1928 // NOTE: indirect references to types / decls should be handled1986 // NOTE: indirect references to types / decls should be handled
1929 // in the switch above this one!1987 // in the switch above this one!
1930 panicWithContext(1988 printWithContext(
1931 file,1989 file,
1932 inst_index,1990 inst_index,
1933 "TODO: handle `{s}`in tryResolveRefPath\nInfo: {}",1991 "TODO: handle `{s}`in tryResolveRefPath\nInfo: {}",
1934 .{ @tagName(resolved_parent), resolved_parent },1992 .{ @tagName(resolved_parent), resolved_parent },
1935 );1993 );
1994 path[i + 1] = try self.cteTodo("match failure");
1995 continue :outer;
1936 },1996 },
1937 .comptimeExpr, .call => {1997 .comptimeExpr, .call => {
1938 // Since we hit a cte, we leave the remaining strings unresolved1998 // Since we hit a cte, we leave the remaining strings unresolved
...@@ -1971,15 +2031,106 @@ fn tryResolveRefPath(...@@ -1971,15 +2031,106 @@ fn tryResolveRefPath(
19712031
1972 return;2032 return;
1973 },2033 },
2034 .Enum => |t_enum| {
2035 for (t_enum.pubDecls) |d| {
2036 // TODO: this could be improved a lot
2037 // by having our own string table!
2038 const decl = self.decls.items[d];
2039 if (std.mem.eql(u8, decl.name, child_string)) {
2040 path[i + 1] = .{ .declRef = d };
2041 continue :outer;
2042 }
2043 }
2044 for (t_enum.privDecls) |d| {
2045 // TODO: this could be improved a lot
2046 // by having our own string table!
2047 const decl = self.decls.items[d];
2048 if (std.mem.eql(u8, decl.name, child_string)) {
2049 path[i + 1] = .{ .declRef = d };
2050 continue :outer;
2051 }
2052 }
2053
2054 for (self.ast_nodes.items[t_enum.src].fields.?) |ast_node, idx| {
2055 const name = self.ast_nodes.items[ast_node].name.?;
2056 if (std.mem.eql(u8, name, child_string)) {
2057 // TODO: should we really create an artificial
2058 // decl for this type? Probably not.
2059
2060 path[i + 1] = .{
2061 .fieldRef = .{
2062 .type = t_index,
2063 .index = idx,
2064 },
2065 };
2066 continue :outer;
2067 }
2068 }
2069
2070 // if we got here, our search failed
2071 printWithContext(
2072 file,
2073 inst_index,
2074 "failed to match `{s}` in enum",
2075 .{child_string},
2076 );
2077
2078 path[i + 1] = try self.cteTodo("match failure");
2079 continue :outer;
2080 },
2081 .Union => |t_union| {
2082 for (t_union.pubDecls) |d| {
2083 // TODO: this could be improved a lot
2084 // by having our own string table!
2085 const decl = self.decls.items[d];
2086 if (std.mem.eql(u8, decl.name, child_string)) {
2087 path[i + 1] = .{ .declRef = d };
2088 continue :outer;
2089 }
2090 }
2091 for (t_union.privDecls) |d| {
2092 // TODO: this could be improved a lot
2093 // by having our own string table!
2094 const decl = self.decls.items[d];
2095 if (std.mem.eql(u8, decl.name, child_string)) {
2096 path[i + 1] = .{ .declRef = d };
2097 continue :outer;
2098 }
2099 }
2100
2101 for (self.ast_nodes.items[t_union.src].fields.?) |ast_node, idx| {
2102 const name = self.ast_nodes.items[ast_node].name.?;
2103 if (std.mem.eql(u8, name, child_string)) {
2104 // TODO: should we really create an artificial
2105 // decl for this type? Probably not.
2106
2107 path[i + 1] = .{
2108 .fieldRef = .{
2109 .type = t_index,
2110 .index = idx,
2111 },
2112 };
2113 continue :outer;
2114 }
2115 }
2116
2117 // if we got here, our search failed
2118 printWithContext(
2119 file,
2120 inst_index,
2121 "failed to match `{s}` in union",
2122 .{child_string},
2123 );
2124 path[i + 1] = try self.cteTodo("match failure");
2125 continue :outer;
2126 },
2127
1974 .Struct => |t_struct| {2128 .Struct => |t_struct| {
1975 std.debug.print("search: {s}\n", .{child_string});
1976 for (t_struct.pubDecls) |d| {2129 for (t_struct.pubDecls) |d| {
1977 // TODO: this could be improved a lot2130 // TODO: this could be improved a lot
1978 // by having our own string table!2131 // by having our own string table!
1979 const decl = self.decls.items[d];2132 const decl = self.decls.items[d];
1980 std.debug.print("pub decl `{s}`\n", .{decl.name});
1981 if (std.mem.eql(u8, decl.name, child_string)) {2133 if (std.mem.eql(u8, decl.name, child_string)) {
1982 std.debug.print("match!\n", .{});
1983 path[i + 1] = .{ .declRef = d };2134 path[i + 1] = .{ .declRef = d };
1984 continue :outer;2135 continue :outer;
1985 }2136 }
...@@ -1988,9 +2139,7 @@ fn tryResolveRefPath(...@@ -1988,9 +2139,7 @@ fn tryResolveRefPath(
1988 // TODO: this could be improved a lot2139 // TODO: this could be improved a lot
1989 // by having our own string table!2140 // by having our own string table!
1990 const decl = self.decls.items[d];2141 const decl = self.decls.items[d];
1991 std.debug.print("priv decl `{s}`\n", .{decl.name});
1992 if (std.mem.eql(u8, decl.name, child_string)) {2142 if (std.mem.eql(u8, decl.name, child_string)) {
1993 std.debug.print("match!\n", .{});
1994 path[i + 1] = .{ .declRef = d };2143 path[i + 1] = .{ .declRef = d };
1995 continue :outer;2144 continue :outer;
1996 }2145 }
...@@ -1998,9 +2147,7 @@ fn tryResolveRefPath(...@@ -1998,9 +2147,7 @@ fn tryResolveRefPath(
19982147
1999 for (self.ast_nodes.items[t_struct.src].fields.?) |ast_node, idx| {2148 for (self.ast_nodes.items[t_struct.src].fields.?) |ast_node, idx| {
2000 const name = self.ast_nodes.items[ast_node].name.?;2149 const name = self.ast_nodes.items[ast_node].name.?;
2001 std.debug.print("field `{s}`\n", .{name});
2002 if (std.mem.eql(u8, name, child_string)) {2150 if (std.mem.eql(u8, name, child_string)) {
2003 std.debug.print("match!\n", .{});
2004 // TODO: should we really create an artificial2151 // TODO: should we really create an artificial
2005 // decl for this type? Probably not.2152 // decl for this type? Probably not.
20062153
...@@ -2015,12 +2162,14 @@ fn tryResolveRefPath(...@@ -2015,12 +2162,14 @@ fn tryResolveRefPath(
2015 }2162 }
20162163
2017 // if we got here, our search failed2164 // if we got here, our search failed
2018 panicWithContext(2165 printWithContext(
2019 file,2166 file,
2020 inst_index,2167 inst_index,
2021 "failed to match `{s}`",2168 "failed to match `{s}` in struct",
2022 .{child_string},2169 .{child_string},
2023 );2170 );
2171 path[i + 1] = try self.cteTodo("match failure");
2172 continue :outer;
2024 },2173 },
2025 },2174 },
2026 }2175 }
...@@ -2070,7 +2219,7 @@ fn analyzeFunction(...@@ -2070,7 +2219,7 @@ fn analyzeFunction(
2070 "TODO: handle `{s}` in walkInstruction.func\n",2219 "TODO: handle `{s}` in walkInstruction.func\n",
2071 .{@tagName(tags[param_index])},2220 .{@tagName(tags[param_index])},
2072 ),2221 ),
2073 .param_anytype => {2222 .param_anytype, .param_anytype_comptime => {
2074 // TODO: where are the doc comments?2223 // TODO: where are the doc comments?
2075 const str_tok = data[param_index].str_tok;2224 const str_tok = data[param_index].str_tok;
20762225
...@@ -2097,7 +2246,7 @@ fn analyzeFunction(...@@ -2097,7 +2246,7 @@ fn analyzeFunction(
2097 const name = file.zir.nullTerminatedString(extra.data.name);2246 const name = file.zir.nullTerminatedString(extra.data.name);
20982247
2099 param_ast_indexes.appendAssumeCapacity(self.ast_nodes.items.len);2248 param_ast_indexes.appendAssumeCapacity(self.ast_nodes.items.len);
2100 self.ast_nodes.appendAssumeCapacity(.{2249 try self.ast_nodes.append(self.arena, .{
2101 .name = name,2250 .name = name,
2102 .docs = doc_comment,2251 .docs = doc_comment,
2103 .@"comptime" = tags[param_index] == .param_comptime,2252 .@"comptime" = tags[param_index] == .param_comptime,
...@@ -2382,12 +2531,15 @@ fn walkRef(...@@ -2382,12 +2531,15 @@ fn walkRef(
2382/// Given a WalkResult, tries to find its type.2531/// Given a WalkResult, tries to find its type.
2383/// Used to analyze instructions like `array_init`, which require us to2532/// Used to analyze instructions like `array_init`, which require us to
2384/// inspect its first element to find out the array type.2533/// inspect its first element to find out the array type.
2385fn typeOfWalkResult(wr: DocData.WalkResult) DocData.WalkResult {2534fn typeOfWalkResult(self: *Autodoc, wr: DocData.WalkResult) !DocData.WalkResult {
2386 return switch (wr) {2535 return switch (wr) {
2387 else => std.debug.panic(2536 else => {
2388 "TODO: handle `{s}` in typeOfWalkResult\n",2537 std.debug.print(
2389 .{@tagName(wr)},2538 "TODO: handle `{s}` in typeOfWalkResult\n",
2390 ),2539 .{@tagName(wr)},
2540 );
2541 return self.cteTodo(@tagName(wr));
2542 },
2391 .type => .{ .type = @enumToInt(DocData.DocTypeKinds.Type) },2543 .type => .{ .type = @enumToInt(DocData.DocTypeKinds.Type) },
2392 .int => |v| v.typeRef.*,2544 .int => |v| v.typeRef.*,
2393 .float => |v| v.typeRef.*,2545 .float => |v| v.typeRef.*,
...@@ -2403,9 +2555,15 @@ fn getBlockInlineBreak(zir: Zir, inst_index: usize) Zir.Inst.Ref {...@@ -2403,9 +2555,15 @@ fn getBlockInlineBreak(zir: Zir, inst_index: usize) Zir.Inst.Ref {
2403 return data[break_index].@"break".operand;2555 return data[break_index].@"break".operand;
2404}2556}
24052557
2406fn panicWithContext(file: *File, inst: usize, comptime fmt: []const u8, args: anytype) noreturn {2558fn printWithContext(file: *File, inst: usize, comptime fmt: []const u8, args: anytype) void {
2407 std.debug.print("Context [{s}] % {}\n", .{ file.sub_file_path, inst });2559 std.debug.print("Context [{s}] % {}\n", .{ file.sub_file_path, inst });
2408 std.debug.panic(fmt, args);2560 std.debug.print(fmt, args);
2561 std.debug.print("\n", .{});
2562}
2563
2564fn panicWithContext(file: *File, inst: usize, comptime fmt: []const u8, args: anytype) noreturn {
2565 printWithContext(file, inst, fmt, args);
2566 unreachable;
2409}2567}
24102568
2411fn cteTodo(self: *Autodoc, msg: []const u8) error{OutOfMemory}!DocData.WalkResult {2569fn cteTodo(self: *Autodoc, msg: []const u8) error{OutOfMemory}!DocData.WalkResult {