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;...@@ -358,6 +358,11 @@ var zigAnalysis;
358 }358 }
359 }359 }
360 }, false);360 }, false);
361
362 if (location.hash == "") {
363 location.hash = "#root";
364 }
365
361 window.addEventListener('hashchange', onHashChange, false);366 window.addEventListener('hashchange', onHashChange, false);
362 window.addEventListener('keydown', onWindowKeyDown, false);367 window.addEventListener('keydown', onWindowKeyDown, false);
363 onHashChange();368 onHashChange();
...@@ -891,8 +896,10 @@ var zigAnalysis;...@@ -891,8 +896,10 @@ var zigAnalysis;
891 let hrefDeclNames = /** @type {string[]} */([]);896 let hrefDeclNames = /** @type {string[]} */([]);
892 for (let i = 0; i < curNav.pkgNames.length; i += 1) {897 for (let i = 0; i < curNav.pkgNames.length; i += 1) {
893 hrefPkgNames.push(curNav.pkgNames[i]);898 hrefPkgNames.push(curNav.pkgNames[i]);
899 let name = curNav.pkgNames[i];
900 if (name == "root") name = zigAnalysis.rootPkgName;
894 list.push({901 list.push({
895 name: curNav.pkgNames[i],902 name: name,
896 link: navLink(hrefPkgNames, hrefDeclNames),903 link: navLink(hrefPkgNames, hrefDeclNames),
897 });904 });
898 }905 }
...@@ -946,7 +953,7 @@ var zigAnalysis;...@@ -946,7 +953,7 @@ var zigAnalysis;
946953
947 {954 {
948 let aDom = domSectMainPkg.children[1].children[0].children[0];955 let aDom = domSectMainPkg.children[1].children[0].children[0];
949 aDom.textContent = zigAnalysis.params.rootName;956 aDom.textContent = zigAnalysis.rootPkgName;
950 aDom.setAttribute('href', navLinkPkg(zigAnalysis.rootPkg));957 aDom.setAttribute('href', navLinkPkg(zigAnalysis.rootPkg));
951 if (zigAnalysis.params.rootName === curNav.pkgNames[0]) {958 if (zigAnalysis.params.rootName === curNav.pkgNames[0]) {
952 aDom.classList.add("active");959 aDom.classList.add("active");
...@@ -1003,6 +1010,7 @@ var zigAnalysis;...@@ -1003,6 +1010,7 @@ var zigAnalysis;
10031010
1004 /** @param {number} pkgIndex */1011 /** @param {number} pkgIndex */
1005 function navLinkPkg(pkgIndex) {1012 function navLinkPkg(pkgIndex) {
1013 console.log(canonPkgPaths);
1006 return navLink(canonPkgPaths[pkgIndex], []);1014 return navLink(canonPkgPaths[pkgIndex], []);
1007 }1015 }
10081016
...@@ -2674,10 +2682,6 @@ var zigAnalysis;...@@ -2674,10 +2682,6 @@ var zigAnalysis;
2674 curNav.declNames = decodeURIComponent(parts[1]).split(".");2682 curNav.declNames = decodeURIComponent(parts[1]).split(".");
2675 }2683 }
2676 }2684 }
2677
2678 if (curNav.pkgNames.length === 0 && rootIsStd) {
2679 curNav.pkgNames = ["std"];
2680 }
2681 }2685 }
26822686
2683 function onHashChange() {2687 function onHashChange() {
...@@ -2739,12 +2743,12 @@ var zigAnalysis;...@@ -2739,12 +2743,12 @@ var zigAnalysis;
2739 function computeCanonicalPackagePaths() {2743 function computeCanonicalPackagePaths() {
2740 let list = new Array(zigAnalysis.packages.length);2744 let list = new Array(zigAnalysis.packages.length);
2741 // Now we try to find all the packages from root.2745 // Now we try to find all the packages from root.
2742 let rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg];2746 let rootPkg = zigAnalysis.packages[zigAnalysis.rootPkg];
2743 // Breadth-first to keep the path shortest possible.2747 // Breadth-first to keep the path shortest possible.
2744 let stack = [{2748 let stack = [{
2745 path: /** @type {string[]} */([]),2749 path: /** @type {string[]} */([]),
2746 pkg: rootPkg,2750 pkg: rootPkg,
2747 }];2751 }];
2748 while (stack.length !== 0) {2752 while (stack.length !== 0) {
2749 let item = /** @type {{path: string[], pkg: Package}} */(stack.shift());2753 let item = /** @type {{path: string[], pkg: Package}} */(stack.shift());
2750 for (let key in item.pkg.table) {2754 for (let key in item.pkg.table) {
src/Autodoc.zig+113-77
...@@ -4,6 +4,7 @@ const Autodoc = @This();...@@ -4,6 +4,7 @@ const Autodoc = @This();
4const Compilation = @import("Compilation.zig");4const Compilation = @import("Compilation.zig");
5const Module = @import("Module.zig");5const Module = @import("Module.zig");
6const File = Module.File;6const File = Module.File;
7const Package = @import("Package.zig");
7const Zir = @import("Zir.zig");8const Zir = @import("Zir.zig");
8const Ref = Zir.Inst.Ref;9const Ref = Zir.Inst.Ref;
910
...@@ -14,8 +15,8 @@ arena: std.mem.Allocator,...@@ -14,8 +15,8 @@ arena: std.mem.Allocator,
14// The goal of autodoc is to fill up these arrays15// The goal of autodoc is to fill up these arrays
15// that will then be serialized as JSON and consumed16// that will then be serialized as JSON and consumed
16// by the JS frontend.17// by the JS frontend.
17pkgs: std.ArrayListUnmanaged(DocData.Package) = .{},18packages: std.AutoArrayHashMapUnmanaged(*Package, DocData.DocPackage) = .{},
18files: std.AutoHashMapUnmanaged(*File, usize) = .{},19files: std.AutoArrayHashMapUnmanaged(*File, usize) = .{},
19calls: std.ArrayListUnmanaged(DocData.Call) = .{},20calls: std.ArrayListUnmanaged(DocData.Call) = .{},
20types: std.ArrayListUnmanaged(DocData.Type) = .{},21types: std.ArrayListUnmanaged(DocData.Type) = .{},
21decls: std.ArrayListUnmanaged(DocData.Decl) = .{},22decls: std.ArrayListUnmanaged(DocData.Decl) = .{},
...@@ -171,28 +172,17 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -171,28 +172,17 @@ pub fn generateZirData(self: *Autodoc) !void {
171 );172 );
172 }173 }
173 }174 }
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;
189 {177 {
190 const rootPkg: *DocData.Package = &self.pkgs.items[0];178 try self.packages.put(self.arena, self.module.main_pkg, .{
191 try rootPkg.table.data.put(self.arena, rootName, 0);179 .name = "root",
192180 .main = main_type_index,
193 rootPkg.main = main_type_index;181 .table = .{ .data = std.StringHashMapUnmanaged(usize){} },
194 rootPkg.name = rootName; 182 });
183 try self.packages.entries.items(.value)[0].table.data.put(self.arena, "root", 0);
195 }184 }
185
196 var root_scope = Scope{ .parent = null, .enclosing_type = main_type_index };186 var root_scope = Scope{ .parent = null, .enclosing_type = main_type_index };
197 try self.ast_nodes.append(self.arena, .{ .name = "(root)" });187 try self.ast_nodes.append(self.arena, .{ .name = "(root)" });
198 try self.files.put(self.arena, file, main_type_index);188 try self.files.put(self.arena, file, main_type_index);
...@@ -209,12 +199,15 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -209,12 +199,15 @@ pub fn generateZirData(self: *Autodoc) !void {
209 if (self.pending_ref_paths.count() > 0) {199 if (self.pending_ref_paths.count() > 0) {
210 @panic("some decl paths were never fully analized");200 @panic("some decl paths were never fully analized");
211 }201 }
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 };
215 var data = DocData{207 var data = DocData{
216 .params = .{ .rootName = rootName },208 .rootPkgName = rootName,
217 .packages = self.pkgs.items,209 .params = .{ .rootName = "root" },
210 .packages = self.packages.values(),
218 .files = .{ .data = self.files },211 .files = .{ .data = self.files },
219 .calls = self.calls.items,212 .calls = self.calls.items,
220 .types = self.types.items,213 .types = self.types.items,
...@@ -224,8 +217,6 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -224,8 +217,6 @@ pub fn generateZirData(self: *Autodoc) !void {
224 .comptimeExprs = self.comptime_exprs.items,217 .comptimeExprs = self.comptime_exprs.items,
225 };218 };
226219
227
228
229 if (self.doc_location.directory) |d| {220 if (self.doc_location.directory) |d| {
230 d.handle.makeDir(221 d.handle.makeDir(
231 self.doc_location.basename,222 self.doc_location.basename,
...@@ -306,6 +297,7 @@ const Scope = struct {...@@ -306,6 +297,7 @@ const Scope = struct {
306const DocData = struct {297const DocData = struct {
307 typeKinds: []const []const u8 = std.meta.fieldNames(DocTypeKinds),298 typeKinds: []const []const u8 = std.meta.fieldNames(DocTypeKinds),
308 rootPkg: u32 = 0,299 rootPkg: u32 = 0,
300 rootPkgName: []const u8,
309 params: struct {301 params: struct {
310 zigId: []const u8 = "arst",302 zigId: []const u8 = "arst",
311 zigVersion: []const u8 = build_options.version,303 zigVersion: []const u8 = build_options.version,
...@@ -315,7 +307,7 @@ const DocData = struct {...@@ -315,7 +307,7 @@ const DocData = struct {
315 .{ .target = "arst" },307 .{ .target = "arst" },
316 },308 },
317 },309 },
318 packages: []const Package,310 packages: []const DocPackage,
319 errors: []struct {} = &.{},311 errors: []struct {} = &.{},
320312
321 // non-hardcoded stuff313 // non-hardcoded stuff
...@@ -323,7 +315,7 @@ const DocData = struct {...@@ -323,7 +315,7 @@ const DocData = struct {
323 calls: []Call,315 calls: []Call,
324 files: struct {316 files: struct {
325 // this struct is a temporary hack to support json serialization317 // this struct is a temporary hack to support json serialization
326 data: std.AutoHashMapUnmanaged(*File, usize),318 data: std.AutoArrayHashMapUnmanaged(*File, usize),
327 pub fn jsonStringify(319 pub fn jsonStringify(
328 self: @This(),320 self: @This(),
329 opt: std.json.StringifyOptions,321 opt: std.json.StringifyOptions,
...@@ -403,53 +395,53 @@ const DocData = struct {...@@ -403,53 +395,53 @@ const DocData = struct {
403 const ComptimeExpr = struct {395 const ComptimeExpr = struct {
404 code: []const u8,396 code: []const u8,
405 };397 };
406 const Package = struct {398 const DocPackage = struct {
407 name: []const u8 = "(root)",399 name: []const u8 = "(root)",
408 file: usize = 0, // index into `files`400 file: usize = 0, // index into `files`
409 main: usize = 0, // index into `decls`401 main: usize = 0, // index into `types`
410 table: struct {402 table: struct {
411 // this struct is a temporary hack to support json serialization403 // this struct is a temporary hack to support json serialization
412 data: std.StringHashMapUnmanaged(usize),404 data: std.StringHashMapUnmanaged(usize),
413 pub fn jsonStringify(405 pub fn jsonStringify(
414 self: @This(),406 self: @This(),
415 opt: std.json.StringifyOptions,407 opt: std.json.StringifyOptions,
416 w: anytype,408 w: anytype,
417 ) !void {409 ) !void {
418 var idx: usize = 0;410 var idx: usize = 0;
419 var it = self.data.iterator();411 var it = self.data.iterator();
420 try w.writeAll("{\n");412 try w.writeAll("{\n");
421413
422 var options = opt;414 var options = opt;
423 if (options.whitespace) |*ws| ws.indent_level += 1;415 if (options.whitespace) |*ws| ws.indent_level += 1;
424 while (it.next()) |kv| : (idx += 1) {416 while (it.next()) |kv| : (idx += 1) {
425 if (options.whitespace) |ws| try ws.outputIndent(w);417 if (options.whitespace) |ws| try ws.outputIndent(w);
426 const builtin = @import("builtin");418 const builtin = @import("builtin");
427 if (builtin.target.os.tag == .windows) {419 if (builtin.target.os.tag == .windows) {
428 try w.print("\"", .{});420 try w.print("\"", .{});
429 for (kv.key_ptr.*) |c| {421 for (kv.key_ptr.*) |c| {
430 if (c == '\\') {422 if (c == '\\') {
431 try w.print("\\\\", .{});423 try w.print("\\\\", .{});
432 } else {424 } else {
433 try w.print("{c}", .{c});425 try w.print("{c}", .{c});
426 }
434 }427 }
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 });
435 }437 }
436 try w.print("\"", .{});438 if (idx != self.data.count() - 1) try w.writeByte(',');
437 try w.print(": {d}", .{439 try w.writeByte('\n');
438 kv.value_ptr.*,
439 });
440 } else {
441 try w.print("\"{s}\": {d}", .{
442 kv.key_ptr.*,
443 kv.value_ptr.*,
444 });
445 }440 }
446 if (idx != self.data.count() - 1) try w.writeByte(',');441 if (opt.whitespace) |ws| try ws.outputIndent(w);
447 try w.writeByte('\n');442 try w.writeAll("}");
448 }443 }
449 if (opt.whitespace) |ws| try ws.outputIndent(w);444 },
450 try w.writeAll("}");
451 }
452 },
453 };445 };
454446
455 const Decl = struct {447 const Decl = struct {
...@@ -1035,15 +1027,59 @@ fn walkInstruction(...@@ -1035,15 +1027,59 @@ fn walkInstruction(
1035 const path = str_tok.get(file.zir);1027 const path = str_tok.get(file.zir);
1036 // importFile cannot error out since all files1028 // importFile cannot error out since all files
1037 // are already loaded at this point1029 // are already loaded at this point
1038 if (file.pkg.table.get(path) != null) {1030 if (file.pkg.table.get(path)) |other_package| {
1039 const cte_slot_index = self.comptime_exprs.items.len;1031 const result = try self.packages.getOrPut(self.arena, other_package);
1040 try self.comptime_exprs.append(self.arena, .{1032
1041 .code = path,1033 // Immediately add this package to the import table of our
1042 });1034 // current package, regardless of wether it's new or not.
1043 return DocData.WalkResult{1035 const current_package = self.packages.getPtr(file.pkg).?;
1044 .typeRef = .{ .type = @enumToInt(Ref.type_type) },1036 _ = try current_package.table.data.getOrPutValue(
1045 .expr = .{ .comptimeExpr = cte_slot_index },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 },
1046 };1057 };
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 );
1047 }1083 }
10481084
1049 const new_file = self.module.importFile(file, path) catch unreachable;1085 const new_file = self.module.importFile(file, path) catch unreachable;