authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-06-08 17:52:43+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:12-07:00
logd2baf404a550ea61402e2cba131168c6001e8dab
tree98fba3eac48707c684239bedb113720044e4eb6c
parenta5e7b0e4dbc49bfd57d974296862cc19e9c71115

autodoc: enabled packages


2 files changed, 128 insertions(+), 88 deletions(-)

lib/docs/main.js+15-11
......@@ -358,6 +358,11 @@ var zigAnalysis;
358358 }
359359 }
360360 }, false);
361
362 if (location.hash == "") {
363 location.hash = "#root";
364 }
365
361366 window.addEventListener('hashchange', onHashChange, false);
362367 window.addEventListener('keydown', onWindowKeyDown, false);
363368 onHashChange();
......@@ -891,8 +896,10 @@ var zigAnalysis;
891896 let hrefDeclNames = /** @type {string[]} */([]);
892897 for (let i = 0; i < curNav.pkgNames.length; i += 1) {
893898 hrefPkgNames.push(curNav.pkgNames[i]);
899 let name = curNav.pkgNames[i];
900 if (name == "root") name = zigAnalysis.rootPkgName;
894901 list.push({
895 name: curNav.pkgNames[i],
902 name: name,
896903 link: navLink(hrefPkgNames, hrefDeclNames),
897904 });
898905 }
......@@ -946,7 +953,7 @@ var zigAnalysis;
946953
947954 {
948955 let aDom = domSectMainPkg.children[1].children[0].children[0];
949 aDom.textContent = zigAnalysis.params.rootName;
956 aDom.textContent = zigAnalysis.rootPkgName;
950957 aDom.setAttribute('href', navLinkPkg(zigAnalysis.rootPkg));
951958 if (zigAnalysis.params.rootName === curNav.pkgNames[0]) {
952959 aDom.classList.add("active");
......@@ -1003,6 +1010,7 @@ var zigAnalysis;
10031010
10041011 /** @param {number} pkgIndex */
10051012 function navLinkPkg(pkgIndex) {
1013 console.log(canonPkgPaths);
10061014 return navLink(canonPkgPaths[pkgIndex], []);
10071015 }
10081016
......@@ -2674,10 +2682,6 @@ var zigAnalysis;
26742682 curNav.declNames = decodeURIComponent(parts[1]).split(".");
26752683 }
26762684 }
2677
2678 if (curNav.pkgNames.length === 0 && rootIsStd) {
2679 curNav.pkgNames = ["std"];
2680 }
26812685 }
26822686
26832687 function onHashChange() {
......@@ -2739,12 +2743,12 @@ var zigAnalysis;
27392743 function computeCanonicalPackagePaths() {
27402744 let list = new Array(zigAnalysis.packages.length);
27412745 // Now we try to find all the packages from root.
2742 let rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg];
2746 let rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg];
27432747 // Breadth-first to keep the path shortest possible.
2744 let stack = [{
2745 path: /** @type {string[]} */([]),
2746 pkg: rootPkg,
2747 }];
2748 let stack = [{
2749 path: /** @type {string[]} */([]),
2750 pkg: rootPkg,
2751 }];
27482752 while (stack.length !== 0) {
27492753 let item = /** @type {{path: string[], pkg: Package}} */(stack.shift());
27502754 for (let key in item.pkg.table) {
src/Autodoc.zig+113-77
......@@ -4,6 +4,7 @@ const Autodoc = @This();
44const Compilation = @import("Compilation.zig");
55const Module = @import("Module.zig");
66const File = Module.File;
7const Package = @import("Package.zig");
78const Zir = @import("Zir.zig");
89const Ref = Zir.Inst.Ref;
910
......@@ -14,8 +15,8 @@ arena: std.mem.Allocator,
1415// The goal of autodoc is to fill up these arrays
1516// that will then be serialized as JSON and consumed
1617// by the JS frontend.
17pkgs: std.ArrayListUnmanaged(DocData.Package) = .{},
18files: std.AutoHashMapUnmanaged(*File, usize) = .{},
18packages: std.AutoArrayHashMapUnmanaged(*Package, DocData.DocPackage) = .{},
19files: std.AutoArrayHashMapUnmanaged(*File, usize) = .{},
1920calls: std.ArrayListUnmanaged(DocData.Call) = .{},
2021types: std.ArrayListUnmanaged(DocData.Type) = .{},
2122decls: std.ArrayListUnmanaged(DocData.Decl) = .{},
......@@ -171,28 +172,17 @@ pub fn generateZirData(self: *Autodoc) !void {
171172 );
172173 }
173174 }
174
175
176
177 const main_type_index = self.types.items.len;
178 const rootName = blk: {
179 const rootName = std.fs.path.basename(self.module.main_pkg.root_src_path);
180 break :blk rootName[0..rootName.len - 4];
181 };
182
183 try self.pkgs.append(self.arena, .{
184 .name = rootName,
185 .table = .{.data = std.StringHashMapUnmanaged(usize){}},
186 });
187
188175
176 const main_type_index = self.types.items.len;
189177 {
190 const rootPkg: *DocData.Package = &self.pkgs.items[0];
191 try rootPkg.table.data.put(self.arena, rootName, 0);
192
193 rootPkg.main = main_type_index;
194 rootPkg.name = rootName;
178 try self.packages.put(self.arena, self.module.main_pkg, .{
179 .name = "root",
180 .main = main_type_index,
181 .table = .{ .data = std.StringHashMapUnmanaged(usize){} },
182 });
183 try self.packages.entries.items(.value)[0].table.data.put(self.arena, "root", 0);
195184 }
185
196186 var root_scope = Scope{ .parent = null, .enclosing_type = main_type_index };
197187 try self.ast_nodes.append(self.arena, .{ .name = "(root)" });
198188 try self.files.put(self.arena, file, main_type_index);
......@@ -209,12 +199,15 @@ pub fn generateZirData(self: *Autodoc) !void {
209199 if (self.pending_ref_paths.count() > 0) {
210200 @panic("some decl paths were never fully analized");
211201 }
212
213202
214
203 const rootName = blk: {
204 const rootName = std.fs.path.basename(self.module.main_pkg.root_src_path);
205 break :blk rootName[0 .. rootName.len - 4];
206 };
215207 var data = DocData{
216 .params = .{ .rootName = rootName },
217 .packages = self.pkgs.items,
208 .rootPkgName = rootName,
209 .params = .{ .rootName = "root" },
210 .packages = self.packages.values(),
218211 .files = .{ .data = self.files },
219212 .calls = self.calls.items,
220213 .types = self.types.items,
......@@ -224,8 +217,6 @@ pub fn generateZirData(self: *Autodoc) !void {
224217 .comptimeExprs = self.comptime_exprs.items,
225218 };
226219
227
228
229220 if (self.doc_location.directory) |d| {
230221 d.handle.makeDir(
231222 self.doc_location.basename,
......@@ -306,6 +297,7 @@ const Scope = struct {
306297const DocData = struct {
307298 typeKinds: []const []const u8 = std.meta.fieldNames(DocTypeKinds),
308299 rootPkg: u32 = 0,
300 rootPkgName: []const u8,
309301 params: struct {
310302 zigId: []const u8 = "arst",
311303 zigVersion: []const u8 = build_options.version,
......@@ -315,7 +307,7 @@ const DocData = struct {
315307 .{ .target = "arst" },
316308 },
317309 },
318 packages: []const Package,
310 packages: []const DocPackage,
319311 errors: []struct {} = &.{},
320312
321313 // non-hardcoded stuff
......@@ -323,7 +315,7 @@ const DocData = struct {
323315 calls: []Call,
324316 files: struct {
325317 // this struct is a temporary hack to support json serialization
326 data: std.AutoHashMapUnmanaged(*File, usize),
318 data: std.AutoArrayHashMapUnmanaged(*File, usize),
327319 pub fn jsonStringify(
328320 self: @This(),
329321 opt: std.json.StringifyOptions,
......@@ -403,53 +395,53 @@ const DocData = struct {
403395 const ComptimeExpr = struct {
404396 code: []const u8,
405397 };
406 const Package = struct {
398 const DocPackage = struct {
407399 name: []const u8 = "(root)",
408400 file: usize = 0, // index into `files`
409 main: usize = 0, // index into `decls`
401 main: usize = 0, // index into `types`
410402 table: struct {
411 // this struct is a temporary hack to support json serialization
412 data: std.StringHashMapUnmanaged(usize),
413 pub fn jsonStringify(
414 self: @This(),
415 opt: std.json.StringifyOptions,
416 w: anytype,
417 ) !void {
418 var idx: usize = 0;
419 var it = self.data.iterator();
420 try w.writeAll("{\n");
421
422 var options = opt;
423 if (options.whitespace) |*ws| ws.indent_level += 1;
424 while (it.next()) |kv| : (idx += 1) {
425 if (options.whitespace) |ws| try ws.outputIndent(w);
426 const builtin = @import("builtin");
427 if (builtin.target.os.tag == .windows) {
428 try w.print("\"", .{});
429 for (kv.key_ptr.*) |c| {
430 if (c == '\\') {
431 try w.print("\\\\", .{});
432 } else {
433 try w.print("{c}", .{c});
403 // this struct is a temporary hack to support json serialization
404 data: std.StringHashMapUnmanaged(usize),
405 pub fn jsonStringify(
406 self: @This(),
407 opt: std.json.StringifyOptions,
408 w: anytype,
409 ) !void {
410 var idx: usize = 0;
411 var it = self.data.iterator();
412 try w.writeAll("{\n");
413
414 var options = opt;
415 if (options.whitespace) |*ws| ws.indent_level += 1;
416 while (it.next()) |kv| : (idx += 1) {
417 if (options.whitespace) |ws| try ws.outputIndent(w);
418 const builtin = @import("builtin");
419 if (builtin.target.os.tag == .windows) {
420 try w.print("\"", .{});
421 for (kv.key_ptr.*) |c| {
422 if (c == '\\') {
423 try w.print("\\\\", .{});
424 } else {
425 try w.print("{c}", .{c});
426 }
434427 }
428 try w.print("\"", .{});
429 try w.print(": {d}", .{
430 kv.value_ptr.*,
431 });
432 } else {
433 try w.print("\"{s}\": {d}", .{
434 kv.key_ptr.*,
435 kv.value_ptr.*,
436 });
435437 }
436 try w.print("\"", .{});
437 try w.print(": {d}", .{
438 kv.value_ptr.*,
439 });
440 } else {
441 try w.print("\"{s}\": {d}", .{
442 kv.key_ptr.*,
443 kv.value_ptr.*,
444 });
438 if (idx != self.data.count() - 1) try w.writeByte(',');
439 try w.writeByte('\n');
445440 }
446 if (idx != self.data.count() - 1) try w.writeByte(',');
447 try w.writeByte('\n');
441 if (opt.whitespace) |ws| try ws.outputIndent(w);
442 try w.writeAll("}");
448443 }
449 if (opt.whitespace) |ws| try ws.outputIndent(w);
450 try w.writeAll("}");
451 }
452 },
444 },
453445 };
454446
455447 const Decl = struct {
......@@ -1035,15 +1027,59 @@ fn walkInstruction(
10351027 const path = str_tok.get(file.zir);
10361028 // importFile cannot error out since all files
10371029 // are already loaded at this point
1038 if (file.pkg.table.get(path) != null) {
1039 const cte_slot_index = self.comptime_exprs.items.len;
1040 try self.comptime_exprs.append(self.arena, .{
1041 .code = path,
1042 });
1043 return DocData.WalkResult{
1044 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
1045 .expr = .{ .comptimeExpr = cte_slot_index },
1030 if (file.pkg.table.get(path)) |other_package| {
1031 const result = try self.packages.getOrPut(self.arena, other_package);
1032
1033 // Immediately add this package to the import table of our
1034 // current package, regardless of wether it's new or not.
1035 const current_package = self.packages.getPtr(file.pkg).?;
1036 _ = try current_package.table.data.getOrPutValue(
1037 self.arena,
1038 path,
1039 self.packages.getIndex(other_package).?,
1040 );
1041
1042 if (result.found_existing) {
1043 return DocData.WalkResult{
1044 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
1045 .expr = .{ .type = result.value_ptr.main },
1046 };
1047 }
1048
1049 // create a new package entry
1050 const main_type_index = self.types.items.len;
1051 result.value_ptr.* = .{
1052 .name = path,
1053 .main = main_type_index,
1054 .table = .{
1055 .data = std.StringHashMapUnmanaged(usize){},
1056 },
10461057 };
1058
1059
1060 // TODO: Add this package as a dependency to the current pakcage
1061 // TODO: this seems something that could be done in bulk
1062 // at the beginning or the end, or something.
1063 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
1064 const dir =
1065 if (other_package.root_src_directory.path) |rp|
1066 std.os.realpath(rp, &buf) catch unreachable
1067 else
1068 std.os.getcwd(&buf) catch unreachable;
1069 const root_file_path = other_package.root_src_path;
1070 const abs_root_path = try std.fs.path.join(self.arena, &.{ dir, root_file_path });
1071 defer self.arena.free(abs_root_path);
1072 const new_file = self.module.import_table.get(abs_root_path).?;
1073
1074 var root_scope = Scope{ .parent = null, .enclosing_type = main_type_index };
1075 try self.ast_nodes.append(self.arena, .{ .name = "(root)" });
1076 try self.files.put(self.arena, new_file, main_type_index);
1077 return self.walkInstruction(
1078 new_file,
1079 &root_scope,
1080 Zir.main_struct_inst,
1081 false,
1082 );
10471083 }
10481084
10491085 const new_file = self.module.importFile(file, path) catch unreachable;