authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-01-30 19:12:56+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:10-07:00
log0135d2271600db92d1ae727b2a5935d0fc711c13
tree762b41dafac87eb5f581ab48cbc3d56347149c0b
parent38281c8ed421b8febadb2d4e05291fcf4a871ccc

autodocs: add support for indirect decl references


3 files changed, 97 insertions(+), 37 deletions(-)

lib/docs/main.js+48-26
...@@ -147,10 +147,10 @@...@@ -147,10 +147,10 @@
147 curNav.pkgObjs.push(pkg);147 curNav.pkgObjs.push(pkg);
148 }148 }
149149
150 var decl = zigAnalysis.types[pkg.main];150 var currentType = zigAnalysis.types[pkg.main];
151 curNav.declObjs = [decl];151 curNav.declObjs = [currentType];
152 for (var i = 0; i < curNav.declNames.length; i += 1) {152 for (var i = 0; i < curNav.declNames.length; i += 1) {
153 var childDecl = findSubDecl(decl, curNav.declNames[i]);153 var childDecl = findSubDecl(currentType, curNav.declNames[i]);
154 if (childDecl == null) {154 if (childDecl == null) {
155 return render404();155 return render404();
156 }156 }
...@@ -163,29 +163,29 @@...@@ -163,29 +163,29 @@
163 return render404();163 return render404();
164 }164 }
165 }165 }
166 decl = container;166 currentType = container;
167 curNav.declObjs.push(decl);167 curNav.declObjs.push(currentType);
168 }168 }
169169
170 renderNav();170 renderNav();
171171
172 var lastDecl = curNav.declObjs[curNav.declObjs.length - 1];172 var lastDeclType = curNav.declObjs[curNav.declObjs.length - 1];
173 if (lastDecl.pubDecls != null) {173 if (lastDeclType.pubDecls != null) {
174 renderContainer(lastDecl);174 renderContainer(lastDeclType);
175 }175 }
176 if (lastDecl.kind == null) {176 if (lastDeclType.kind == null) {
177 return renderUnknownDecl(lastDecl);177 return renderUnknownDecl(lastDeclType);
178 } else if (lastDecl.kind === 'var') {178 } else if (lastDeclType.kind === 'var') {
179 return renderVar(lastDecl);179 return renderVar(lastDeclType);
180 } else if (lastDecl.kind === 'const' && lastDecl.type != null) {180 } else if (lastDeclType.kind === 'const' && lastDeclType.type != null) {
181 var typeObj = zigAnalysis.types[lastDecl.type];181 var typeObj = zigAnalysis.types[lastDeclType.type];
182 if (typeObj.kind === typeKinds.Fn) {182 if (typeObj.kind === typeKinds.Fn) {
183 return renderFn(lastDecl);183 return renderFn(lastDeclType);
184 } else {184 } else {
185 return renderValue(lastDecl);185 return renderValue(lastDeclType);
186 }186 }
187 } else {187 } else {
188 renderType(lastDecl);188 renderType(lastDeclType);
189 }189 }
190 }190 }
191191
...@@ -994,15 +994,18 @@...@@ -994,15 +994,18 @@
994994
995 for (var i = 0; i < container.pubDecls.length; i += 1) {995 for (var i = 0; i < container.pubDecls.length; i += 1) {
996 var decl = zigAnalysis.decls[container.pubDecls[i]];996 var decl = zigAnalysis.decls[container.pubDecls[i]];
997 var declValTypeId = getDeclValTypeId(decl);
997998
998 if (decl.kind === 'var') {999 if (decl.kind === 'var') {
999 varsList.push(decl);1000 varsList.push(decl);
1000 continue;1001 continue;
1001 } else if (decl.kind === 'const' && decl.type != null) {1002 } else if (decl.kind === 'const' && decl.type != null) {
1002 if (decl.type === typeTypeId) {1003 if (decl.type === typeTypeId) {
1003 if (typeIsErrSet(decl.value)) {1004 // todo: this actually makes sense for decl_vals too
1005 // the problem is, how should we get to the final type though?
1006 if (typeIsErrSet(declValTypeId)) {
1004 errSetsList.push(decl);1007 errSetsList.push(decl);
1005 } else if (typeIsStructWithNoFields(decl.value)) {1008 } else if (typeIsStructWithNoFields(declValTypeId)) {
1006 namespacesList.push(decl);1009 namespacesList.push(decl);
1007 } else {1010 } else {
1008 typesList.push(decl);1011 typesList.push(decl);
...@@ -1010,7 +1013,7 @@...@@ -1010,7 +1013,7 @@
1010 } else {1013 } else {
1011 var typeKind = zigAnalysis.types[decl.type].kind;1014 var typeKind = zigAnalysis.types[decl.type].kind;
1012 if (typeKind === typeKinds.Fn) {1015 if (typeKind === typeKinds.Fn) {
1013 if (allCompTimeFnCallsHaveTypeResult(decl.type, decl.value)) {1016 if (allCompTimeFnCallsHaveTypeResult(decl.type, declValTypeId)) {
1014 typesList.push(decl);1017 typesList.push(decl);
1015 } else {1018 } else {
1016 fnsList.push(decl);1019 fnsList.push(decl);
...@@ -1111,10 +1114,20 @@...@@ -1111,10 +1114,20 @@
1111 if (field.failure === true) {1114 if (field.failure === true) {
1112 html += '<span class="tok-kw" style="color:red;">#FAILURE#</span>';1115 html += '<span class="tok-kw" style="color:red;">#FAILURE#</span>';
1113 } else if ("decl_ref" in field) {1116 } else if ("decl_ref" in field) {
1114 var name = zigAnalysis.decls[field.decl_ref].name;1117 var decl = zigAnalysis.decls[field.decl_ref];
1115 html += '<a href="'+navLinkDecl(name)+'">';1118 var valType = zigAnalysis.types[getDeclValTypeId(decl)];
1116 html += '<span class="tok-kw" style="color:lightblue;">'+ name +'</span>';1119 var valTypeName = valType.name;
1120 if (valType.kind === typeKinds.Struct) {
1121 valTypeName = "struct";
1122 }
1123
1124 html += '<a href="'+navLinkDecl(decl.name)+'">';
1125 html += '<span class="tok-kw" style="color:lightblue;">' + decl.name + '</span>';
1117 html += '</a>';1126 html += '</a>';
1127 html += ' ('+ valTypeName +')';
1128 } else if ("type" in field) {
1129 var name = zigAnalysis.types[field.type].name;
1130 html += '<span class="tok-kw">' + name + '</span>';
1118 } else {1131 } else {
1119 html += '<span class="tok-kw">var</span>';1132 html += '<span class="tok-kw">var</span>';
1120 }1133 }
...@@ -1291,7 +1304,7 @@...@@ -1291,7 +1304,7 @@
12911304
1292 function getDeclContainerType(decl) {1305 function getDeclContainerType(decl) {
1293 if (decl.type === typeTypeId) {1306 if (decl.type === typeTypeId) {
1294 return zigAnalysis.types[decl.value];1307 return zigAnalysis.types[getDeclValTypeId(decl)];
1295 }1308 }
1296 return null;1309 return null;
1297 }1310 }
...@@ -1334,6 +1347,14 @@...@@ -1334,6 +1347,14 @@
1334 return typeKind === typeKinds.ErrorSet || typeKindIsContainer(typeKind);1347 return typeKind === typeKinds.ErrorSet || typeKindIsContainer(typeKind);
1335 }1348 }
13361349
1350 function getDeclValTypeId(decl) {
1351 while ( "decl_ref" in decl.value) {
1352 decl = zigAnalysis.decls[decl.value.decl_ref];
1353 }
1354 console.assert("type" in decl.value);
1355 return decl.value.type;
1356 }
1357
1337 function computeCanonDeclPaths() {1358 function computeCanonDeclPaths() {
1338 var list = new Array(zigAnalysis.decls.length);1359 var list = new Array(zigAnalysis.decls.length);
1339 canonTypeDecls = new Array(zigAnalysis.types.length);1360 canonTypeDecls = new Array(zigAnalysis.types.length);
...@@ -1355,10 +1376,11 @@...@@ -1355,10 +1376,11 @@
1355 if (list[mainDeclIndex] != null) continue;1376 if (list[mainDeclIndex] != null) continue;
13561377
1357 var decl = zigAnalysis.decls[mainDeclIndex];1378 var decl = zigAnalysis.decls[mainDeclIndex];
1379 var declValTypeId = getDeclValTypeId(decl);
1358 if (decl.type === typeTypeId &&1380 if (decl.type === typeTypeId &&
1359 declCanRepresentTypeKind(zigAnalysis.types[decl.value].kind))1381 declCanRepresentTypeKind(zigAnalysis.types[declValTypeId].kind))
1360 {1382 {
1361 canonTypeDecls[decl.value] = mainDeclIndex;1383 canonTypeDecls[declValTypeId] = mainDeclIndex;
1362 }1384 }
1363 var declNames = item.declNames.concat([decl.name]);1385 var declNames = item.declNames.concat([decl.name]);
1364 list[mainDeclIndex] = {1386 list[mainDeclIndex] = {
src/Autodoc.zig+48-11
...@@ -21,6 +21,10 @@ pub fn init(m: *Module, doc_location: ?Compilation.EmitLoc) Autodoc {...@@ -21,6 +21,10 @@ pub fn init(m: *Module, doc_location: ?Compilation.EmitLoc) Autodoc {
21 };21 };
22}22}
2323
24pub fn deinit(_: *Autodoc) void {
25 arena_allocator.deinit();
26}
27
24pub fn generateZirData(self: *Autodoc) !void {28pub fn generateZirData(self: *Autodoc) !void {
25 if (self.doc_location) |loc| {29 if (self.doc_location) |loc| {
26 if (loc.directory) |dir| {30 if (loc.directory) |dir| {
...@@ -48,13 +52,51 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -48,13 +52,51 @@ pub fn generateZirData(self: *Autodoc) !void {
48 {52 {
4953
50 // TODO: we don't want to add .none, but the index math has to check out54 // TODO: we don't want to add .none, but the index math has to check out
51 var i: u32 = 1;55 var i: u32 = 0;
52 while (i <= @enumToInt(Zir.Inst.Ref.anyerror_void_error_union_type)) : (i += 1) {56 while (i <= @enumToInt(Zir.Inst.Ref.anyerror_void_error_union_type)) : (i += 1) {
53 var tmpbuf = std.ArrayList(u8).init(self.arena);57 var tmpbuf = std.ArrayList(u8).init(self.arena);
54 try Zir.Inst.Ref.typed_value_map[i].val.format("", .{}, tmpbuf.writer());58 try Zir.Inst.Ref.typed_value_map[i].val.format("", .{}, tmpbuf.writer());
55 try self.types.append(self.arena, .{59 try self.types.append(self.arena, .{
56 .kind = 0,
57 .name = tmpbuf.toOwnedSlice(),60 .name = tmpbuf.toOwnedSlice(),
61 .kind = switch (@intToEnum(Zir.Inst.Ref, i)) {
62 else => |t| blk: {
63 std.debug.print("TODO: categorize `{s}` in typeKinds\n", .{
64 @tagName(t),
65 });
66 break :blk 7;
67 },
68 .u1_type,
69 .u8_type,
70 .i8_type,
71 .u16_type,
72 .i16_type,
73 .u32_type,
74 .i32_type,
75 .u64_type,
76 .i64_type,
77 .u128_type,
78 .i128_type,
79 .usize_type,
80 .isize_type,
81 .c_short_type,
82 .c_ushort_type,
83 .c_int_type,
84 .c_uint_type,
85 .c_long_type,
86 .c_ulong_type,
87 .c_longlong_type,
88 .c_ulonglong_type,
89 .c_longdouble_type,
90 => @enumToInt(std.builtin.TypeId.Int),
91 .f16_type,
92 .f32_type,
93 .f64_type,
94 .f128_type,
95 => @enumToInt(std.builtin.TypeId.Float),
96 .bool_type => @enumToInt(std.builtin.TypeId.Bool),
97 .void_type => @enumToInt(std.builtin.TypeId.Void),
98 .type_type => @enumToInt(std.builtin.TypeId.Type),
99 },
58 });100 });
59 }101 }
60 }102 }
...@@ -167,7 +209,7 @@ const DocData = struct {...@@ -167,7 +209,7 @@ const DocData = struct {
167 kind: []const u8, // TODO: where do we find this info?209 kind: []const u8, // TODO: where do we find this info?
168 src: usize, // index into astNodes210 src: usize, // index into astNodes
169 type: usize, // index into types211 type: usize, // index into types
170 value: usize,212 value: WalkResult,
171 };213 };
172214
173 const AstNode = struct {215 const AstNode = struct {
...@@ -476,7 +518,6 @@ fn walkDecls(...@@ -476,7 +518,6 @@ fn walkDecls(
476 };518 };
477519
478 const walk_result = try self.walkInstruction(zir, scope, decl_index);520 const walk_result = try self.walkInstruction(zir, scope, decl_index);
479 const type_index = walk_result.type;
480521
481 if (is_pub) {522 if (is_pub) {
482 try decl_indexes.append(self.arena, decls_slot_index);523 try decl_indexes.append(self.arena, decls_slot_index);
...@@ -487,8 +528,8 @@ fn walkDecls(...@@ -487,8 +528,8 @@ fn walkDecls(
487 self.decls.items[decls_slot_index] = .{528 self.decls.items[decls_slot_index] = .{
488 .name = name,529 .name = name,
489 .src = ast_node_index,530 .src = ast_node_index,
490 .type = 0,531 .type = @enumToInt(Zir.Inst.Ref.type_type),
491 .value = type_index,532 .value = walk_result,
492 .kind = "const", // find where this information can be found533 .kind = "const", // find where this information can be found
493 };534 };
494 }535 }
...@@ -561,13 +602,9 @@ fn collectFieldInfo(...@@ -561,13 +602,9 @@ fn collectFieldInfo(
561 else => {602 else => {
562 const enum_value = @enumToInt(field_type);603 const enum_value = @enumToInt(field_type);
563 if (enum_value < Zir.Inst.Ref.typed_value_map.len) {604 if (enum_value < Zir.Inst.Ref.typed_value_map.len) {
564 std.debug.print(
565 "TODO: handle ref type: {s}",
566 .{@tagName(field_type)},
567 );
568 try field_type_indexes.append(605 try field_type_indexes.append(
569 self.arena,606 self.arena,
570 DocData.WalkResult{ .failure = true },607 DocData.WalkResult{ .type = enum_value },
571 );608 );
572 } else {609 } else {
573 const zir_index = enum_value - Zir.Inst.Ref.typed_value_map.len;610 const zir_index = enum_value - Zir.Inst.Ref.typed_value_map.len;
src/Compilation.zig+1
...@@ -2870,6 +2870,7 @@ pub fn performAllTheWork(...@@ -2870,6 +2870,7 @@ pub fn performAllTheWork(
2870 if (comp.emit_docs) |doc_location| {2870 if (comp.emit_docs) |doc_location| {
2871 if (comp.bin_file.options.module) |module| {2871 if (comp.bin_file.options.module) |module| {
2872 var autodoc = Autodoc.init(module, doc_location);2872 var autodoc = Autodoc.init(module, doc_location);
2873 defer autodoc.deinit();
2873 try autodoc.generateZirData();2874 try autodoc.generateZirData();
2874 }2875 }
2875 }2876 }