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 = {...@@ -759,7 +759,7 @@ const NAV_MODES = {
759 docsSource = protoSrcNode.docs;759 docsSource = protoSrcNode.docs;
760 }760 }
761 if (docsSource != null) {761 if (docsSource != null) {
762 domTldDocs.innerHTML = markdown(docsSource);762 domTldDocs.innerHTML = markdown(docsSource, fnDecl);
763 domTldDocs.classList.remove("hidden");763 domTldDocs.classList.remove("hidden");
764 }764 }
765 domFnProto.classList.remove("hidden");765 domFnProto.classList.remove("hidden");
...@@ -2537,7 +2537,10 @@ const NAV_MODES = {...@@ -2537,7 +2537,10 @@ const NAV_MODES = {
25372537
2538 let docs = getAstNode(decl.src).docs;2538 let docs = getAstNode(decl.src).docs;
2539 if (docs != null) {2539 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
2541 domTldDocs.classList.remove("hidden");2544 domTldDocs.classList.remove("hidden");
2542 }2545 }
25432546
...@@ -3190,6 +3193,7 @@ const NAV_MODES = {...@@ -3190,6 +3193,7 @@ const NAV_MODES = {
3190 let declIndex = parentType.pubDecls[i];3193 let declIndex = parentType.pubDecls[i];
3191 let childDecl = getDecl(declIndex);3194 let childDecl = getDecl(declIndex);
3192 if (childDecl.name === childName) {3195 if (childDecl.name === childName) {
3196 childDecl.find_subdecl_idx = declIndex;
3193 return childDecl;3197 return childDecl;
3194 } else if (childDecl.is_uns) {3198 } else if (childDecl.is_uns) {
3195 let declValue = resolveValue(childDecl.value);3199 let declValue = resolveValue(childDecl.value);
...@@ -3206,6 +3210,7 @@ const NAV_MODES = {...@@ -3206,6 +3210,7 @@ const NAV_MODES = {
3206 let declIndex = parentType.privDecls[i];3210 let declIndex = parentType.privDecls[i];
3207 let childDecl = getDecl(declIndex);3211 let childDecl = getDecl(declIndex);
3208 if (childDecl.name === childName) {3212 if (childDecl.name === childName) {
3213 childDecl.find_subdecl_idx = declIndex;
3209 return childDecl;3214 return childDecl;
3210 } else if (childDecl.is_uns) {3215 } else if (childDecl.is_uns) {
3211 let declValue = resolveValue(childDecl.value);3216 let declValue = resolveValue(childDecl.value);
...@@ -3622,12 +3627,39 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {...@@ -3622,12 +3627,39 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
3622 const components = text.split(".");3627 const components = text.split(".");
3623 let curDeclOrType = undefined;3628 let curDeclOrType = undefined;
3624 3629
3625 if (context) {3630 let curContext = context;
3626 curDeclOrType = findSubDecl(context, components[0]);3631 let limit = 10000;
3627 if (curDeclOrType) {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) {
3628 separator = '.';3648 separator = '.';
3629 result = location.hash + separator + components[0];3649 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;
3630 }3660 }
3661
3662 break;
3631 } 3663 }
36323664
3633 if (!curDeclOrType) {3665 if (!curDeclOrType) {
...@@ -4077,6 +4109,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {...@@ -4077,6 +4109,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
4077 value: decl[3],4109 value: decl[3],
4078 decltest: decl[4],4110 decltest: decl[4],
4079 is_uns: decl[5],4111 is_uns: decl[5],
4112 parent_container: decl[6],
4080 };4113 };
4081 }4114 }
40824115
...@@ -4145,7 +4178,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {...@@ -4145,7 +4178,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
4145 field_defaults: ty[6],4178 field_defaults: ty[6],
4146 is_tuple: ty[7],4179 is_tuple: ty[7],
4147 line_number: ty[8],4180 line_number: ty[8],
4148 outer_decl: ty[9],4181 parent_container: ty[9],
4149 };4182 };
4150 case 10: // ComptimeExpr4183 case 10: // ComptimeExpr
4151 case 11: // ComptimeFloat4184 case 11: // ComptimeFloat
...@@ -4186,6 +4219,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {...@@ -4186,6 +4219,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
4186 tag: ty[5],4219 tag: ty[5],
4187 values: ty[6],4220 values: ty[6],
4188 nonexhaustive: ty[7],4221 nonexhaustive: ty[7],
4222 parent_container: ty[8],
4189 };4223 };
4190 case 20: // Union4224 case 20: // Union
4191 return {4225 return {
...@@ -4197,6 +4231,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {...@@ -4197,6 +4231,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
4197 field_types: ty[5],4231 field_types: ty[5],
4198 tag: ty[6],4232 tag: ty[6],
4199 auto_tag: ty[7],4233 auto_tag: ty[7],
4234 parent_container: ty[8],
4200 };4235 };
4201 case 21: // Fn4236 case 21: // Fn
4202 return {4237 return {
...@@ -4226,6 +4261,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {...@@ -4226,6 +4261,7 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
4226 src: ty[2],4261 src: ty[2],
4227 privDecls: ty[3],4262 privDecls: ty[3],
4228 pubDecls: ty[4],4263 pubDecls: ty[4],
4264 parent_container: ty[5],
4229 };4265 };
4230 case 24: // Frame4266 case 24: // Frame
4231 case 25: // AnyFrame4267 case 25: // AnyFrame
src/Autodoc.zig+21-7
...@@ -228,7 +228,7 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -228,7 +228,7 @@ pub fn generateZirData(self: *Autodoc) !void {
228228
229 var root_scope = Scope{229 var root_scope = Scope{
230 .parent = null,230 .parent = null,
231 .enclosing_type = main_type_index,231 .enclosing_type = null,
232 };232 };
233233
234 const tldoc_comment = try self.getTLDocComment(file);234 const tldoc_comment = try self.getTLDocComment(file);
...@@ -363,7 +363,7 @@ const Scope = struct {...@@ -363,7 +363,7 @@ const Scope = struct {
363 *DeclStatus,363 *DeclStatus,
364 ) = .{},364 ) = .{},
365365
366 enclosing_type: usize, // index into `types`366 enclosing_type: ?usize, // index into `types`, null = file top-level struct
367367
368 pub const DeclStatus = union(enum) {368 pub const DeclStatus = union(enum) {
369 Analyzed: usize, // index into `decls`369 Analyzed: usize, // index into `decls`
...@@ -516,6 +516,7 @@ const DocData = struct {...@@ -516,6 +516,7 @@ const DocData = struct {
516 // The index in astNodes of the `test declname { }` node516 // The index in astNodes of the `test declname { }` node
517 decltest: ?usize = null,517 decltest: ?usize = null,
518 is_uns: bool = false, // usingnamespace518 is_uns: bool = false, // usingnamespace
519 parent_container: ?usize, // index into `types`
519520
520 pub fn jsonStringify(521 pub fn jsonStringify(
521 self: Decl,522 self: Decl,
...@@ -600,7 +601,7 @@ const DocData = struct {...@@ -600,7 +601,7 @@ const DocData = struct {
600 field_defaults: []?Expr = &.{}, // default values is specified601 field_defaults: []?Expr = &.{}, // default values is specified
601 is_tuple: bool,602 is_tuple: bool,
602 line_number: usize,603 line_number: usize,
603 outer_decl: usize,604 parent_container: ?usize, // index into `types`
604 },605 },
605 ComptimeExpr: struct { name: []const u8 },606 ComptimeExpr: struct { name: []const u8 },
606 ComptimeFloat: struct { name: []const u8 },607 ComptimeFloat: struct { name: []const u8 },
...@@ -627,6 +628,7 @@ const DocData = struct {...@@ -627,6 +628,7 @@ const DocData = struct {
627 tag: ?Expr = null, // tag type if specified628 tag: ?Expr = null, // tag type if specified
628 values: []?Expr = &.{}, // tag values if specified629 values: []?Expr = &.{}, // tag values if specified
629 nonexhaustive: bool,630 nonexhaustive: bool,
631 parent_container: ?usize, // index into `types`
630 },632 },
631 Union: struct {633 Union: struct {
632 name: []const u8,634 name: []const u8,
...@@ -636,6 +638,7 @@ const DocData = struct {...@@ -636,6 +638,7 @@ const DocData = struct {
636 fields: []Expr = &.{}, // (use src->fields to find names)638 fields: []Expr = &.{}, // (use src->fields to find names)
637 tag: ?Expr, // tag type if specified639 tag: ?Expr, // tag type if specified
638 auto_enum: bool, // tag is an auto enum640 auto_enum: bool, // tag is an auto enum
641 parent_container: ?usize, // index into `types`
639 },642 },
640 Fn: struct {643 Fn: struct {
641 name: []const u8,644 name: []const u8,
...@@ -659,6 +662,7 @@ const DocData = struct {...@@ -659,6 +662,7 @@ const DocData = struct {
659 src: usize, // index into astNodes662 src: usize, // index into astNodes
660 privDecls: []usize = &.{}, // index into decls663 privDecls: []usize = &.{}, // index into decls
661 pubDecls: []usize = &.{}, // index into decls664 pubDecls: []usize = &.{}, // index into decls
665 parent_container: ?usize, // index into `types`
662 },666 },
663 Frame: struct { name: []const u8 },667 Frame: struct { name: []const u8 },
664 AnyFrame: struct { name: []const u8 },668 AnyFrame: struct { name: []const u8 },
...@@ -961,7 +965,7 @@ fn walkInstruction(...@@ -961,7 +965,7 @@ fn walkInstruction(
961965
962 var root_scope = Scope{966 var root_scope = Scope{
963 .parent = null,967 .parent = null,
964 .enclosing_type = main_type_index,968 .enclosing_type = null,
965 };969 };
966 const maybe_tldoc_comment = try self.getTLDocComment(file);970 const maybe_tldoc_comment = try self.getTLDocComment(file);
967 try self.ast_nodes.append(self.arena, .{971 try self.ast_nodes.append(self.arena, .{
...@@ -991,7 +995,7 @@ fn walkInstruction(...@@ -991,7 +995,7 @@ fn walkInstruction(
991995
992 var new_scope = Scope{996 var new_scope = Scope{
993 .parent = null,997 .parent = null,
994 .enclosing_type = self.types.items.len,998 .enclosing_type = null,
995 };999 };
9961000
997 return self.walkInstruction(1001 return self.walkInstruction(
...@@ -2493,6 +2497,7 @@ fn walkInstruction(...@@ -2493,6 +2497,7 @@ fn walkInstruction(
2493 .src = self_ast_node_index,2497 .src = self_ast_node_index,
2494 .privDecls = priv_decl_indexes.items,2498 .privDecls = priv_decl_indexes.items,
2495 .pubDecls = decl_indexes.items,2499 .pubDecls = decl_indexes.items,
2500 .parent_container = parent_scope.enclosing_type,
2496 },2501 },
2497 };2502 };
2498 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {2503 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
...@@ -2635,6 +2640,7 @@ fn walkInstruction(...@@ -2635,6 +2640,7 @@ fn walkInstruction(
2635 .fields = field_type_refs.items,2640 .fields = field_type_refs.items,
2636 .tag = tag_type.expr,2641 .tag = tag_type.expr,
2637 .auto_enum = small.auto_enum_tag,2642 .auto_enum = small.auto_enum_tag,
2643 .parent_container = parent_scope.enclosing_type,
2638 },2644 },
2639 };2645 };
26402646
...@@ -2772,6 +2778,7 @@ fn walkInstruction(...@@ -2772,6 +2778,7 @@ fn walkInstruction(
2772 .tag = tag_type,2778 .tag = tag_type,
2773 .values = field_values.items,2779 .values = field_values.items,
2774 .nonexhaustive = small.nonexhaustive,2780 .nonexhaustive = small.nonexhaustive,
2781 .parent_container = parent_scope.enclosing_type,
2775 },2782 },
2776 };2783 };
2777 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {2784 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
...@@ -2872,7 +2879,7 @@ fn walkInstruction(...@@ -2872,7 +2879,7 @@ fn walkInstruction(
2872 .field_defaults = field_default_refs.items,2879 .field_defaults = field_default_refs.items,
2873 .is_tuple = small.is_tuple,2880 .is_tuple = small.is_tuple,
2874 .line_number = self.ast_nodes.items[self_ast_node_index].line,2881 .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,
2876 },2883 },
2877 };2884 };
2878 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {2885 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
...@@ -2897,7 +2904,12 @@ fn walkInstruction(...@@ -2897,7 +2904,12 @@ fn walkInstruction(
2897 .this => {2904 .this => {
2898 return DocData.WalkResult{2905 return DocData.WalkResult{
2899 .typeRef = .{ .type = @enumToInt(Ref.type_type) },2906 .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 },
2901 };2913 };
2902 },2914 },
2903 .error_to_int,2915 .error_to_int,
...@@ -3224,6 +3236,7 @@ fn analyzeDecl(...@@ -3224,6 +3236,7 @@ fn analyzeDecl(
3224 .src = ast_node_index,3236 .src = ast_node_index,
3225 .value = walk_result,3237 .value = walk_result,
3226 .kind = kind,3238 .kind = kind,
3239 .parent_container = scope.enclosing_type,
3227 });3240 });
32283241
3229 if (is_pub) {3242 if (is_pub) {
...@@ -3299,6 +3312,7 @@ fn analyzeUsingnamespaceDecl(...@@ -3299,6 +3312,7 @@ fn analyzeUsingnamespaceDecl(
3299 .src = ast_node_index,3312 .src = ast_node_index,
3300 .value = walk_result,3313 .value = walk_result,
3301 .is_uns = true,3314 .is_uns = true,
3315 .parent_container = scope.enclosing_type,
3302 });3316 });
33033317
3304 if (is_pub) {3318 if (is_pub) {