| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| | 2 | const build_options = @import("build_options"); |
| 2 | const Autodoc = @This(); | 3 | const Autodoc = @This(); |
| 3 | const Compilation = @import("Compilation.zig"); | 4 | const Compilation = @import("Compilation.zig"); |
| 4 | const Module = @import("Module.zig"); | 5 | const Module = @import("Module.zig"); |
| ... | @@ -13,6 +14,7 @@ arena: std.mem.Allocator, | ... | @@ -13,6 +14,7 @@ arena: std.mem.Allocator, |
| 13 | // The goal of autodoc is to fill up these arrays | 14 | // The goal of autodoc is to fill up these arrays |
| 14 | // that will then be serialized as JSON and consumed | 15 | // that will then be serialized as JSON and consumed |
| 15 | // by the JS frontend. | 16 | // by the JS frontend. |
| | 17 | pkgs: std.ArrayListUnmanaged(DocData.Package) = .{}, |
| 16 | files: std.AutoHashMapUnmanaged(*File, usize) = .{}, | 18 | files: std.AutoHashMapUnmanaged(*File, usize) = .{}, |
| 17 | calls: std.ArrayListUnmanaged(DocData.Call) = .{}, | 19 | calls: std.ArrayListUnmanaged(DocData.Call) = .{}, |
| 18 | types: std.ArrayListUnmanaged(DocData.Type) = .{}, | 20 | types: std.ArrayListUnmanaged(DocData.Type) = .{}, |
| ... | @@ -169,8 +171,28 @@ pub fn generateZirData(self: *Autodoc) !void { | ... | @@ -169,8 +171,28 @@ pub fn generateZirData(self: *Autodoc) !void { |
| 169 | ); | 171 | ); |
| 170 | } | 172 | } |
| 171 | } | 173 | } |
| 172 | | 174 | |
| | 175 | |
| | 176 | |
| 173 | const main_type_index = self.types.items.len; | 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 | |
| | 188 | |
| | 189 | { |
| | 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; |
| | 195 | } |
| 174 | var root_scope = Scope{ .parent = null, .enclosing_type = main_type_index }; | 196 | var root_scope = Scope{ .parent = null, .enclosing_type = main_type_index }; |
| 175 | try self.ast_nodes.append(self.arena, .{ .name = "(root)" }); | 197 | try self.ast_nodes.append(self.arena, .{ .name = "(root)" }); |
| 176 | try self.files.put(self.arena, file, main_type_index); | 198 | try self.files.put(self.arena, file, main_type_index); |
| ... | @@ -187,8 +209,12 @@ pub fn generateZirData(self: *Autodoc) !void { | ... | @@ -187,8 +209,12 @@ pub fn generateZirData(self: *Autodoc) !void { |
| 187 | if (self.pending_ref_paths.count() > 0) { | 209 | if (self.pending_ref_paths.count() > 0) { |
| 188 | @panic("some decl paths were never fully analized"); | 210 | @panic("some decl paths were never fully analized"); |
| 189 | } | 211 | } |
| | 212 | |
| 190 | | 213 | |
| | 214 | |
| 191 | var data = DocData{ | 215 | var data = DocData{ |
| | 216 | .params = .{ .rootName = rootName }, |
| | 217 | .packages = self.pkgs.items, |
| 192 | .files = .{ .data = self.files }, | 218 | .files = .{ .data = self.files }, |
| 193 | .calls = self.calls.items, | 219 | .calls = self.calls.items, |
| 194 | .types = self.types.items, | 220 | .types = self.types.items, |
| ... | @@ -198,7 +224,7 @@ pub fn generateZirData(self: *Autodoc) !void { | ... | @@ -198,7 +224,7 @@ pub fn generateZirData(self: *Autodoc) !void { |
| 198 | .comptimeExprs = self.comptime_exprs.items, | 224 | .comptimeExprs = self.comptime_exprs.items, |
| 199 | }; | 225 | }; |
| 200 | | 226 | |
| 201 | data.packages[0].main = main_type_index; | 227 | |
| 202 | | 228 | |
| 203 | if (self.doc_location.directory) |d| { | 229 | if (self.doc_location.directory) |d| { |
| 204 | d.handle.makeDir( | 230 | d.handle.makeDir( |
| ... | @@ -282,14 +308,14 @@ const DocData = struct { | ... | @@ -282,14 +308,14 @@ const DocData = struct { |
| 282 | rootPkg: u32 = 0, | 308 | rootPkg: u32 = 0, |
| 283 | params: struct { | 309 | params: struct { |
| 284 | zigId: []const u8 = "arst", | 310 | zigId: []const u8 = "arst", |
| 285 | zigVersion: []const u8 = "arst", | 311 | zigVersion: []const u8 = build_options.version, |
| 286 | target: []const u8 = "arst", | 312 | target: []const u8 = "arst", |
| 287 | rootName: []const u8 = "arst", | 313 | rootName: []const u8, |
| 288 | builds: []const struct { target: []const u8 } = &.{ | 314 | builds: []const struct { target: []const u8 } = &.{ |
| 289 | .{ .target = "arst" }, | 315 | .{ .target = "arst" }, |
| 290 | }, | 316 | }, |
| 291 | } = .{}, | 317 | }, |
| 292 | packages: [1]Package = .{.{}}, | 318 | packages: []const Package, |
| 293 | errors: []struct {} = &.{}, | 319 | errors: []struct {} = &.{}, |
| 294 | | 320 | |
| 295 | // non-hardcoded stuff | 321 | // non-hardcoded stuff |
| ... | @@ -378,12 +404,52 @@ const DocData = struct { | ... | @@ -378,12 +404,52 @@ const DocData = struct { |
| 378 | code: []const u8, | 404 | code: []const u8, |
| 379 | }; | 405 | }; |
| 380 | const Package = struct { | 406 | const Package = struct { |
| 381 | name: []const u8 = "root", | 407 | name: []const u8 = "(root)", |
| 382 | file: usize = 0, // index into `files` | 408 | file: usize = 0, // index into `files` |
| 383 | main: usize = 0, // index into `decls` | 409 | main: usize = 0, // index into `decls` |
| 384 | table: struct { root: usize } = .{ | 410 | table: struct { |
| 385 | .root = 0, | 411 | // this struct is a temporary hack to support json serialization |
| 386 | }, | 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}); |
| | 434 | } |
| | 435 | } |
| | 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 | }); |
| | 445 | } |
| | 446 | if (idx != self.data.count() - 1) try w.writeByte(','); |
| | 447 | try w.writeByte('\n'); |
| | 448 | } |
| | 449 | if (opt.whitespace) |ws| try ws.outputIndent(w); |
| | 450 | try w.writeAll("}"); |
| | 451 | } |
| | 452 | }, |
| 387 | }; | 453 | }; |
| 388 | | 454 | |
| 389 | const Decl = struct { | 455 | const Decl = struct { |