Commit 428f745270

Krzysztof Wolicki <der.teufel.mail@gmail.com>
2023-04-17 03:01:55
autodoc: Change html file destination dirs Each file is now saved with its package index in data.json
1 parent 4374ce5
Changed files (2)
lib
docs
src
lib/docs/main.js
@@ -66,7 +66,7 @@ const NAV_MODES = {
   const domHdrName = document.getElementById("hdrName");
   const domHelpModal = document.getElementById("helpModal");
   const domSearchPlaceholder = document.getElementById("searchPlaceholder");
-  const sourceFileUrlTemplate = "src/{{file}}.html#L{{line}}"
+  const sourceFileUrlTemplate = "src/{{pkg}}/{{file}}.html#L{{line}}"
   const domLangRefLink = document.getElementById("langRefLink");
 
   let searchTimer = null;
@@ -446,7 +446,7 @@ const NAV_MODES = {
     
     if (activeGuide == undefined) {
       const root_file_idx = zigAnalysis.packages[zigAnalysis.rootPkg].file;
-      const root_file_name = zigAnalysis.files[root_file_idx];
+      const root_file_name = getFile(root_file_idx).name;
       domGuides.innerHTML = markdown(`
           # Zig Guides
           These autodocs don't contain any guide.
@@ -2685,8 +2685,10 @@ const NAV_MODES = {
 
   function sourceFileLink(decl) {
     const srcNode = getAstNode(decl.src);
+    const srcFile = getFile(srcNode.file);
     return sourceFileUrlTemplate.
-      replace("{{file}}", zigAnalysis.files[srcNode.file]).
+      replace("{{pkg}}", zigAnalysis.packages[srcFile.pkgIndex].name).
+      replace("{{file}}", srcFile.name).
       replace("{{line}}", srcNode.line + 1);
   }
 
@@ -4135,6 +4137,14 @@ function addDeclToSearchResults(decl, declIndex, pkgNames, item, list, stack) {
     };
   }
 
+  function getFile(idx) {
+    const file = zigAnalysis.files[idx];
+    return {
+      name: file[0],
+      pkgIndex: file[1],
+    };
+  }
+
   function getType(idx) {
     const ty = zigAnalysis.types[idx];
     switch (ty[0]) {
src/Autodoc.zig
@@ -255,7 +255,7 @@ pub fn generateZirData(self: *Autodoc) !void {
 
     var data = DocData{
         .params = .{},
-        .packages = self.packages.values(),
+        .packages = self.packages,
         .files = self.files,
         .calls = self.calls.items,
         .types = self.types.items,
@@ -313,9 +313,26 @@ pub fn generateZirData(self: *Autodoc) !void {
         var files_iterator = self.files.iterator();
 
         while (files_iterator.next()) |entry| {
-            const new_html_path = try std.mem.concat(self.arena, u8, &.{ entry.key_ptr.*.sub_file_path, ".html" });
+            const sub_file_path = entry.key_ptr.*.sub_file_path;
+            const file_package = entry.key_ptr.*.pkg;
+            const package_name = (self.packages.get(file_package) orelse continue).name;
 
-            const html_file = try createFromPath(html_dir, new_html_path);
+            const file_path = std.fs.path.dirname(sub_file_path) orelse "";
+            const file_name = if (file_path.len > 0) sub_file_path[file_path.len + 1 ..] else sub_file_path;
+
+            const html_file_name = try std.mem.concat(self.arena, u8, &.{ file_name, ".html" });
+            defer self.arena.free(html_file_name);
+
+            const dir_name = try std.fs.path.join(self.arena, &.{ package_name, file_path });
+            defer self.arena.free(dir_name);
+
+            var dir = try html_dir.makeOpenPath(dir_name, .{});
+            defer dir.close();
+
+            const html_file = dir.createFile(html_file_name, .{}) catch |err| switch (err) {
+                error.PathAlreadyExists => try dir.openFile(html_file_name, .{}),
+                else => return err,
+            };
             defer html_file.close();
             var buffer = std.io.bufferedWriter(html_file.writer());
 
@@ -333,26 +350,6 @@ pub fn generateZirData(self: *Autodoc) !void {
     try docs_dir.copyFile("index.html", output_dir, "index.html", .{});
 }
 
-fn createFromPath(base_dir: std.fs.Dir, path: []const u8) !std.fs.File {
-    var path_tokens = std.mem.tokenize(u8, path, std.fs.path.sep_str);
-    var dir = base_dir;
-    while (path_tokens.next()) |toc| {
-        if (path_tokens.peek() != null) {
-            dir.makeDir(toc) catch |e| switch (e) {
-                error.PathAlreadyExists => {},
-                else => |err| return err,
-            };
-            dir = try dir.openDir(toc, .{});
-        } else {
-            return dir.createFile(toc, .{}) catch |e| switch (e) {
-                error.PathAlreadyExists => try dir.openFile(toc, .{}),
-                else => |err| return err,
-            };
-        }
-    }
-    return error.EmptyPath;
-}
-
 /// Represents a chain of scopes, used to resolve decl references to the
 /// corresponding entry in `self.decls`. It also keeps track of whether
 /// a given decl has been analyzed or not.
@@ -417,7 +414,7 @@ const DocData = struct {
             .{ .target = "arst" },
         },
     },
-    packages: []const DocPackage,
+    packages: std.AutoArrayHashMapUnmanaged(*Package, DocPackage),
     errors: []struct {} = &.{},
 
     // non-hardcoded stuff
@@ -449,8 +446,12 @@ const DocData = struct {
             const f_name = @tagName(f);
             try jsw.objectField(f_name);
             switch (f) {
-                .files => try writeFileTableToJson(self.files, &jsw),
+                .files => try writeFileTableToJson(self.files, self.packages, &jsw),
                 .guide_sections => try writeGuidesToJson(self.guide_sections, &jsw),
+                .packages => {
+                    try std.json.stringify(self.packages.values(), opts, w);
+                    jsw.state_index -= 1;
+                },
                 else => {
                     try std.json.stringify(@field(self, f_name), opts, w);
                     jsw.state_index -= 1;
@@ -950,7 +951,7 @@ fn walkInstruction(
                     .table = .{},
                 };
 
-                // TODO: Add this package as a dependency to the current pakcage
+                // TODO: Add this package as a dependency to the current package
                 // TODO: this seems something that could be done in bulk
                 //       at the beginning or the end, or something.
                 const root_src_dir = other_package.root_src_directory;
@@ -4627,12 +4628,21 @@ fn cteTodo(self: *Autodoc, msg: []const u8) error{OutOfMemory}!DocData.WalkResul
     return DocData.WalkResult{ .expr = .{ .comptimeExpr = cte_slot_index } };
 }
 
-fn writeFileTableToJson(map: std.AutoArrayHashMapUnmanaged(*File, usize), jsw: anytype) !void {
+fn writeFileTableToJson(
+    map: std.AutoArrayHashMapUnmanaged(*File, usize),
+    pkgs: std.AutoArrayHashMapUnmanaged(*Package, DocData.DocPackage),
+    jsw: anytype,
+) !void {
     try jsw.beginArray();
     var it = map.iterator();
     while (it.next()) |entry| {
+        try jsw.arrayElem();
+        try jsw.beginArray();
         try jsw.arrayElem();
         try jsw.emitString(entry.key_ptr.*.sub_file_path);
+        try jsw.arrayElem();
+        try jsw.emitNumber(pkgs.getIndex(entry.key_ptr.*.pkg) orelse 0);
+        try jsw.endArray();
     }
     try jsw.endArray();
 }