authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2023-04-17 20:12:43+02:00
committergravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2023-04-17 20:13:08+02:00
log3d33a09069533e40f22095472eab15b1ef8798c9
tree4dc0e2782df566e9af50baf6794673e44a8edd3d
parent2d41dac57d3afdd5fe3d03be08ff0a24833f61dd

autodoc: more support for linking decls in docs & guides


2 files changed, 63 insertions(+), 13 deletions(-)

lib/docs/main.js+42-6
......@@ -759,7 +759,7 @@ const NAV_MODES = {
759759 docsSource = protoSrcNode.docs;
760760 }
761761 if (docsSource != null) {
762 domTldDocs.innerHTML = markdown(docsSource);
762 domTldDocs.innerHTML = markdown(docsSource, fnDecl);
763763 domTldDocs.classList.remove("hidden");
764764 }
765765 domFnProto.classList.remove("hidden");
......@@ -2537,7 +2537,10 @@ const NAV_MODES = {
25372537
25382538 let docs = getAstNode(decl.src).docs;
25392539 if (docs != null) {
2540 domTldDocs.innerHTML = markdown(docs);
2540 // TODO: it shouldn't just be decl.parent_container, but rather
2541 // the type that the decl holds (if the value is a type)
2542 domTldDocs.innerHTML = markdown(docs, getType(decl.parent_container));
2543
25412544 domTldDocs.classList.remove("hidden");
25422545 }
25432546
......@@ -3190,6 +3193,7 @@ const NAV_MODES = {
31903193 let declIndex = parentType.pubDecls[i];
31913194 let childDecl = getDecl(declIndex);
31923195 if (childDecl.name === childName) {
3196 childDecl.find_subdecl_idx = declIndex;
31933197 return childDecl;
31943198 } else if (childDecl.is_uns) {
31953199 let declValue = resolveValue(childDecl.value);
......@@ -3206,6 +3210,7 @@ const NAV_MODES = {
32063210 let declIndex = parentType.privDecls[i];
32073211 let childDecl = getDecl(declIndex);
32083212 if (childDecl.name === childName) {
3213 childDecl.find_subdecl_idx = declIndex;
32093214 return childDecl;
32103215 } else if (childDecl.is_uns) {
32113216 let declValue = resolveValue(childDecl.value);
......@@ -3622,12 +3627,39 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
36223627 const components = text.split(".");
36233628 let curDeclOrType = undefined;
36243629
3625 if (context) {
3626 curDeclOrType = findSubDecl(context, components[0]);
3627 if (curDeclOrType) {
3630 let curContext = context;
3631 let limit = 10000;
3632 while (curContext) {
3633 limit -= 1;
3634
3635 if (limit == 0) {
3636 throw "too many iterations";
3637 }
3638
3639 curDeclOrType = findSubDecl(curContext, components[0]);
3640
3641 if (!curDeclOrType) {
3642 if (curContext.parent_container == null) break;
3643 curContext = getType(curContext.parent_container);
3644 continue;
3645 }
3646
3647 if (curContext == context) {
36283648 separator = '.';
36293649 result = location.hash + separator + components[0];
3650 } else {
3651 // We had to go up, which means we need a new path!
3652 const canonPath = getCanonDeclPath(curDeclOrType.find_subdecl_idx);
3653 if (!canonPath) return;
3654
3655 let lastPkgName = canonPath.pkgNames[canonPath.pkgNames.length - 1];
3656 let fullPath = lastPkgName + ":" + canonPath.declNames.join(".");
3657
3658 separator = '.';
3659 result = "#A;" + fullPath;
36303660 }
3661
3662 break;
36313663 }
36323664
36333665 if (!curDeclOrType) {
......@@ -4077,6 +4109,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
40774109 value: decl[3],
40784110 decltest: decl[4],
40794111 is_uns: decl[5],
4112 parent_container: decl[6],
40804113 };
40814114 }
40824115
......@@ -4145,7 +4178,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
41454178 field_defaults: ty[6],
41464179 is_tuple: ty[7],
41474180 line_number: ty[8],
4148 outer_decl: ty[9],
4181 parent_container: ty[9],
41494182 };
41504183 case 10: // ComptimeExpr
41514184 case 11: // ComptimeFloat
......@@ -4186,6 +4219,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
41864219 tag: ty[5],
41874220 values: ty[6],
41884221 nonexhaustive: ty[7],
4222 parent_container: ty[8],
41894223 };
41904224 case 20: // Union
41914225 return {
......@@ -4197,6 +4231,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
41974231 field_types: ty[5],
41984232 tag: ty[6],
41994233 auto_tag: ty[7],
4234 parent_container: ty[8],
42004235 };
42014236 case 21: // Fn
42024237 return {
......@@ -4226,6 +4261,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
42264261 src: ty[2],
42274262 privDecls: ty[3],
42284263 pubDecls: ty[4],
4264 parent_container: ty[5],
42294265 };
42304266 case 24: // Frame
42314267 case 25: // AnyFrame
src/Autodoc.zig+21-7
......@@ -228,7 +228,7 @@ pub fn generateZirData(self: *Autodoc) !void {
228228
229229 var root_scope = Scope{
230230 .parent = null,
231 .enclosing_type = main_type_index,
231 .enclosing_type = null,
232232 };
233233
234234 const tldoc_comment = try self.getTLDocComment(file);
......@@ -363,7 +363,7 @@ const Scope = struct {
363363 *DeclStatus,
364364 ) = .{},
365365
366 enclosing_type: usize, // index into `types`
366 enclosing_type: ?usize, // index into `types`, null = file top-level struct
367367
368368 pub const DeclStatus = union(enum) {
369369 Analyzed: usize, // index into `decls`
......@@ -516,6 +516,7 @@ const DocData = struct {
516516 // The index in astNodes of the `test declname { }` node
517517 decltest: ?usize = null,
518518 is_uns: bool = false, // usingnamespace
519 parent_container: ?usize, // index into `types`
519520
520521 pub fn jsonStringify(
521522 self: Decl,
......@@ -600,7 +601,7 @@ const DocData = struct {
600601 field_defaults: []?Expr = &.{}, // default values is specified
601602 is_tuple: bool,
602603 line_number: usize,
603 outer_decl: usize,
604 parent_container: ?usize, // index into `types`
604605 },
605606 ComptimeExpr: struct { name: []const u8 },
606607 ComptimeFloat: struct { name: []const u8 },
......@@ -627,6 +628,7 @@ const DocData = struct {
627628 tag: ?Expr = null, // tag type if specified
628629 values: []?Expr = &.{}, // tag values if specified
629630 nonexhaustive: bool,
631 parent_container: ?usize, // index into `types`
630632 },
631633 Union: struct {
632634 name: []const u8,
......@@ -636,6 +638,7 @@ const DocData = struct {
636638 fields: []Expr = &.{}, // (use src->fields to find names)
637639 tag: ?Expr, // tag type if specified
638640 auto_enum: bool, // tag is an auto enum
641 parent_container: ?usize, // index into `types`
639642 },
640643 Fn: struct {
641644 name: []const u8,
......@@ -659,6 +662,7 @@ const DocData = struct {
659662 src: usize, // index into astNodes
660663 privDecls: []usize = &.{}, // index into decls
661664 pubDecls: []usize = &.{}, // index into decls
665 parent_container: ?usize, // index into `types`
662666 },
663667 Frame: struct { name: []const u8 },
664668 AnyFrame: struct { name: []const u8 },
......@@ -961,7 +965,7 @@ fn walkInstruction(
961965
962966 var root_scope = Scope{
963967 .parent = null,
964 .enclosing_type = main_type_index,
968 .enclosing_type = null,
965969 };
966970 const maybe_tldoc_comment = try self.getTLDocComment(file);
967971 try self.ast_nodes.append(self.arena, .{
......@@ -991,7 +995,7 @@ fn walkInstruction(
991995
992996 var new_scope = Scope{
993997 .parent = null,
994 .enclosing_type = self.types.items.len,
998 .enclosing_type = null,
995999 };
9961000
9971001 return self.walkInstruction(
......@@ -2493,6 +2497,7 @@ fn walkInstruction(
24932497 .src = self_ast_node_index,
24942498 .privDecls = priv_decl_indexes.items,
24952499 .pubDecls = decl_indexes.items,
2500 .parent_container = parent_scope.enclosing_type,
24962501 },
24972502 };
24982503 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
......@@ -2635,6 +2640,7 @@ fn walkInstruction(
26352640 .fields = field_type_refs.items,
26362641 .tag = tag_type.expr,
26372642 .auto_enum = small.auto_enum_tag,
2643 .parent_container = parent_scope.enclosing_type,
26382644 },
26392645 };
26402646
......@@ -2772,6 +2778,7 @@ fn walkInstruction(
27722778 .tag = tag_type,
27732779 .values = field_values.items,
27742780 .nonexhaustive = small.nonexhaustive,
2781 .parent_container = parent_scope.enclosing_type,
27752782 },
27762783 };
27772784 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
......@@ -2872,7 +2879,7 @@ fn walkInstruction(
28722879 .field_defaults = field_default_refs.items,
28732880 .is_tuple = small.is_tuple,
28742881 .line_number = self.ast_nodes.items[self_ast_node_index].line,
2875 .outer_decl = type_slot_index - 1,
2882 .parent_container = parent_scope.enclosing_type,
28762883 },
28772884 };
28782885 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
......@@ -2897,7 +2904,12 @@ fn walkInstruction(
28972904 .this => {
28982905 return DocData.WalkResult{
28992906 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
2900 .expr = .{ .this = parent_scope.enclosing_type },
2907 .expr = .{
2908 .this = parent_scope.enclosing_type.?,
2909 // We know enclosing_type is always present
2910 // because it's only null for the top-level
2911 // struct instruction of a file.
2912 },
29012913 };
29022914 },
29032915 .error_to_int,
......@@ -3224,6 +3236,7 @@ fn analyzeDecl(
32243236 .src = ast_node_index,
32253237 .value = walk_result,
32263238 .kind = kind,
3239 .parent_container = scope.enclosing_type,
32273240 });
32283241
32293242 if (is_pub) {
......@@ -3299,6 +3312,7 @@ fn analyzeUsingnamespaceDecl(
32993312 .src = ast_node_index,
33003313 .value = walk_result,
33013314 .is_uns = true,
3315 .parent_container = scope.enclosing_type,
33023316 });
33033317
33043318 if (is_pub) {