authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-02-08 07:44:16+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:10-07:00
log5a31126d897e58b87fea1c709696b44959cf1021
tree8b099101fb8f113ca1268848d27b862bc9f884f2
parentef5a2e8d6f9467ea689af93c8400646cdacd6ee8

autodocs: output data support for more types


1 files changed, 262 insertions(+), 63 deletions(-)

src/Autodoc.zig+262-63
......@@ -47,8 +47,6 @@ pub fn generateZirData(self: *Autodoc) !void {
4747 defer self.arena.free(abs_root_path);
4848 const zir = self.module.import_table.get(abs_root_path).?.zir;
4949
50 // var decl_map = std.AutoHashMap(Zir.Inst.Index, usize); // values are positions in the `decls` array
51
5250 // append all the types in Zir.Inst.Ref
5351 {
5452
......@@ -57,14 +55,16 @@ pub fn generateZirData(self: *Autodoc) !void {
5755 while (i <= @enumToInt(Ref.anyerror_void_error_union_type)) : (i += 1) {
5856 var tmpbuf = std.ArrayList(u8).init(self.arena);
5957 try Ref.typed_value_map[i].val.format("", .{}, tmpbuf.writer());
60 try self.types.append(self.arena, .{
61 .name = tmpbuf.toOwnedSlice(),
62 .kind = switch (@intToEnum(Ref, i)) {
58 try self.types.append(
59 self.arena,
60 switch (@intToEnum(Ref, i)) {
6361 else => blk: {
6462 //std.debug.print("TODO: categorize `{s}` in typeKinds\n", .{
6563 // @tagName(t),
6664 //});
67 break :blk 7;
65 break :blk .{
66 .Array = .{ .name = tmpbuf.toOwnedSlice() },
67 };
6868 },
6969 .u1_type,
7070 .u8_type,
......@@ -88,19 +88,35 @@ pub fn generateZirData(self: *Autodoc) !void {
8888 .c_longlong_type,
8989 .c_ulonglong_type,
9090 .c_longdouble_type,
91 => @enumToInt(std.builtin.TypeId.Int),
91 => .{
92 .Int = .{ .name = tmpbuf.toOwnedSlice() },
93 },
9294 .f16_type,
9395 .f32_type,
9496 .f64_type,
9597 .f128_type,
96 => @enumToInt(std.builtin.TypeId.Float),
97 .comptime_int_type => @enumToInt(std.builtin.TypeId.ComptimeInt),
98 .comptime_float_type => @enumToInt(std.builtin.TypeId.ComptimeFloat),
99 .bool_type => @enumToInt(std.builtin.TypeId.Bool),
100 .void_type => @enumToInt(std.builtin.TypeId.Void),
101 .type_type => @enumToInt(std.builtin.TypeId.Type),
98 => .{
99 .Float = .{ .name = tmpbuf.toOwnedSlice() },
100 },
101 .comptime_int_type => .{
102 .ComptimeInt = .{ .name = tmpbuf.toOwnedSlice() },
103 },
104 .comptime_float_type => .{
105 .ComptimeFloat = .{ .name = tmpbuf.toOwnedSlice() },
106 },
107
108 .bool_type => .{
109 .Bool = .{ .name = tmpbuf.toOwnedSlice() },
110 },
111
112 .void_type => .{
113 .Void = .{ .name = tmpbuf.toOwnedSlice() },
114 },
115 .type_type => .{
116 .Type = .{ .name = tmpbuf.toOwnedSlice() },
117 },
102118 },
103 });
119 );
104120 }
105121 }
106122
......@@ -117,16 +133,21 @@ pub fn generateZirData(self: *Autodoc) !void {
117133
118134 data.packages[0].main = main_type_index.type;
119135
120 if (self.doc_location.directory) |d|
121 (d.handle.makeDir(self.doc_location.basename) catch |e| switch (e) {
136 if (self.doc_location.directory) |d| {
137 d.handle.makeDir(
138 self.doc_location.basename,
139 ) catch |e| switch (e) {
122140 error.PathAlreadyExists => {},
123141 else => unreachable,
124 })
125 else
126 (self.module.zig_cache_artifact_directory.handle.makeDir(self.doc_location.basename) catch |e| switch (e) {
142 };
143 } else {
144 self.module.zig_cache_artifact_directory.handle.makeDir(
145 self.doc_location.basename,
146 ) catch |e| switch (e) {
127147 error.PathAlreadyExists => {},
128148 else => unreachable,
129 });
149 };
150 }
130151 const output_dir = if (self.doc_location.directory) |d|
131152 (d.handle.openDir(self.doc_location.basename, .{}) catch unreachable)
132153 else
......@@ -224,18 +245,126 @@ const DocData = struct {
224245 fields: ?[]usize = null, // index into astNodes
225246 };
226247
227 const Type = struct {
228 kind: u32, // index into typeKinds
229 name: []const u8,
230 src: ?usize = null, // index into astNodes
231 privDecls: ?[]usize = null, // index into decls
232 pubDecls: ?[]usize = null, // index into decls
233 fields: ?[]WalkResult = null, // (use src->fields to find names)
248 const Type = union(std.builtin.TypeId) {
249 Type: struct { name: []const u8 },
250 Void: struct { name: []const u8 },
251 Bool: struct { name: []const u8 },
252 NoReturn: struct { name: []const u8 },
253 Int: struct { name: []const u8 },
254 Float: struct { name: []const u8 },
255 Pointer: struct { name: []const u8 },
256 Array: struct { name: []const u8 },
257 Struct: struct {
258 name: []const u8,
259 src: ?usize = null, // index into astNodes
260 privDecls: ?[]usize = null, // index into decls
261 pubDecls: ?[]usize = null, // index into decls
262 fields: ?[]TypeRef = null, // (use src->fields to find names)
263 },
264 ComptimeFloat: struct { name: []const u8 },
265 ComptimeInt: struct { name: []const u8 },
266 Undefined: struct { name: []const u8 },
267 Null: struct { name: []const u8 },
268 Optional: struct { name: []const u8 },
269 ErrorUnion: struct { name: []const u8 },
270 ErrorSet: struct { name: []const u8 },
271 Enum: struct {
272 name: []const u8,
273 src: ?usize = null, // index into astNodes
274 privDecls: ?[]usize = null, // index into decls
275 pubDecls: ?[]usize = null, // index into decls
276 // (use src->fields to find field names)
277 },
278 Union: struct {
279 name: []const u8,
280 src: ?usize = null, // index into astNodes
281 privDecls: ?[]usize = null, // index into decls
282 pubDecls: ?[]usize = null, // index into decls
283 fields: ?[]TypeRef = null, // (use src->fields to find names)
284 },
285 Fn: struct {
286 name: []const u8,
287 src: ?usize = null, // index into astNodes
288 ret: TypeRef,
289 params: ?[]TypeRef = null, // (use src->fields to find names)
290 },
291 BoundFn: struct { name: []const u8 },
292 Opaque: struct { name: []const u8 },
293 Frame: struct { name: []const u8 },
294 AnyFrame: struct { name: []const u8 },
295 Vector: struct { name: []const u8 },
296 EnumLiteral: struct { name: []const u8 },
297
298 pub fn jsonStringify(
299 self: Type,
300 opt: std.json.StringifyOptions,
301 w: anytype,
302 ) !void {
303 try w.print(
304 \\{{ "kind": {},
305 \\
306 , .{@enumToInt(std.meta.activeTag(self))});
307 var options = opt;
308 if (options.whitespace) |*ws| ws.indent_level += 1;
309 switch (self) {
310 .Array => |v| try printTypeBody(v, options, w),
311 .Bool => |v| try printTypeBody(v, options, w),
312 .Void => |v| try printTypeBody(v, options, w),
313 .ComptimeInt => |v| try printTypeBody(v, options, w),
314 .ComptimeFloat => |v| try printTypeBody(v, options, w),
315 .Null => |v| try printTypeBody(v, options, w),
316
317 .Struct => |v| try printTypeBody(v, options, w),
318 .Fn => |v| try printTypeBody(v, options, w),
319 .Union => |v| try printTypeBody(v, options, w),
320 .Enum => |v| try printTypeBody(v, options, w),
321 .Int => |v| try printTypeBody(v, options, w),
322 .Float => |v| try printTypeBody(v, options, w),
323 .Type => |v| try printTypeBody(v, options, w),
324 else => {
325 std.debug.print(
326 "TODO: add {s} to `DocData.Type.jsonStringify`\n",
327 .{@tagName(self)},
328 );
329 },
330 }
331 try w.print("}}", .{});
332 }
333
334 fn printTypeBody(
335 body: anytype,
336 options: std.json.StringifyOptions,
337 w: anytype,
338 ) !void {
339 const fields = std.meta.fields(@TypeOf(body));
340 inline for (fields) |f, idx| {
341 if (options.whitespace) |ws| try ws.outputIndent(w);
342 try w.print("\"{s}\": ", .{f.name});
343 try std.json.stringify(@field(body, f.name), options, w);
344 if (idx != fields.len - 1) try w.writeByte(',');
345 try w.writeByte('\n');
346 }
347 if (options.whitespace) |ws| {
348 var up = ws;
349 up.indent_level -= 1;
350 try up.outputIndent(w);
351 }
352 }
234353 };
354
235355 const TypeRef = union(enum) {
236356 unspecified,
237357 declRef: usize, // index in `decls`
238358 type: usize, // index in `types`
359
360 pub fn fromWalkResult(wr: WalkResult) TypeRef {
361 return switch (wr) {
362 .declRef => |v| .{ .declRef = v },
363 .type => |v| .{ .type = v },
364 else => @panic("Found non-type WalkResult"),
365 };
366 }
367
239368 pub fn jsonStringify(
240369 self: TypeRef,
241370 _: std.json.StringifyOptions,
......@@ -247,6 +376,7 @@ const DocData = struct {
247376 \\{{ "unspecified":{{}} }}
248377 , .{});
249378 },
379
250380 .declRef, .type => |v| {
251381 try w.print(
252382 \\{{ "{s}":{} }}
......@@ -287,9 +417,7 @@ const DocData = struct {
287417 w: anytype,
288418 ) !void {
289419 switch (self) {
290 .void,
291 .@"unreachable",
292 => {
420 .void, .@"unreachable" => {
293421 try w.print(
294422 \\{{ "{s}":{{}} }}
295423 , .{@tagName(self)});
......@@ -360,7 +488,9 @@ fn walkInstruction(
360488 const int = data[inst_index].int;
361489 return DocData.WalkResult{
362490 .int = .{
363 .typeRef = .{ .type = @enumToInt(Ref.comptime_int_type) },
491 .typeRef = .{
492 .type = @enumToInt(Ref.comptime_int_type),
493 },
364494 .value = int,
365495 },
366496 };
......@@ -369,14 +499,20 @@ fn walkInstruction(
369499 const float = data[inst_index].float;
370500 return DocData.WalkResult{
371501 .float = .{
372 .typeRef = .{ .type = @enumToInt(Ref.comptime_float_type) },
502 .typeRef = .{
503 .type = @enumToInt(Ref.comptime_float_type),
504 },
373505 .value = float,
374506 },
375507 };
376508 },
377509 .negate => {
378510 const un_node = data[inst_index].un_node;
379 var operand = try self.walkRef(zir, parent_scope, un_node.operand);
511 var operand: DocData.WalkResult = try self.walkRef(
512 zir,
513 parent_scope,
514 un_node.operand,
515 );
380516 operand.int.negated = true; // only support ints for now
381517 return operand;
382518 },
......@@ -420,8 +556,7 @@ fn walkInstruction(
420556 const name = try std.fmt.allocPrint(self.arena, "{s}{}", .{ sign, bits });
421557
422558 try self.types.append(self.arena, .{
423 .kind = @enumToInt(std.builtin.TypeId.Int),
424 .name = name,
559 .Int = .{ .name = name },
425560 });
426561 return DocData.WalkResult{ .type = self.types.items.len - 1 };
427562 },
......@@ -432,12 +567,57 @@ fn walkInstruction(
432567 const break_operand = data[break_index].@"break".operand;
433568 return self.walkRef(zir, parent_scope, break_operand);
434569 },
570 .func => {
571 const fn_info = zir.getFnInfo(@intCast(u32, inst_index));
572
573 // TODO: change this to a resize and change the appends accordingly
574 try self.ast_nodes.ensureUnusedCapacity(self.arena, fn_info.total_params_len);
575 try self.types.ensureUnusedCapacity(self.arena, fn_info.total_params_len);
576 var param_type_refs = try std.ArrayListUnmanaged(DocData.TypeRef).initCapacity(
577 self.arena,
578 fn_info.total_params_len,
579 );
580 var param_ast_indexes = try std.ArrayListUnmanaged(usize).initCapacity(
581 self.arena,
582 fn_info.total_params_len,
583 );
584 for (fn_info.param_body[0..fn_info.total_params_len]) |param_index| {
585 if (tags[param_index] != .param) unreachable; // TODO: handle more param types
586 const pl_tok = data[param_index].pl_tok;
587 const extra = zir.extraData(Zir.Inst.Param, pl_tok.payload_index);
588
589 param_ast_indexes.appendAssumeCapacity(self.ast_nodes.items.len);
590 try self.ast_nodes.append(self.arena, .{
591 .name = zir.nullTerminatedString(zir.extra[extra.data.name]),
592 .docs = "",
593 });
594
595 const break_index = zir.extra[extra.end..][extra.data.body_len - 1];
596 const break_operand = data[break_index].@"break".operand;
597 const walk_res = try self.walkRef(zir, parent_scope, break_operand);
598
599 param_type_refs.appendAssumeCapacity(
600 DocData.TypeRef.fromWalkResult(walk_res),
601 );
602 }
603
604 self.ast_nodes.items[self_ast_node_index].fields = param_ast_indexes.items;
605 try self.types.append(self.arena, .{
606 .Fn = .{
607 .name = "todo_name func",
608 .src = self_ast_node_index,
609 .params = param_type_refs.items,
610 .ret = .{ .type = @enumToInt(Ref.void_type) },
611 },
612 });
613 return DocData.WalkResult{ .type = self.types.items.len - 1 };
614 },
435615 .extended => {
436616 const extended = data[inst_index].extended;
437617 switch (extended.opcode) {
438618 else => {
439619 std.debug.panic(
440 "TODO: implement `walkInstruction.extended` for {s}\n\n",
620 "TODO: implement `walkinstruction.extended` for {s}\n\n",
441621 .{@tagName(extended.opcode)},
442622 );
443623 },
......@@ -510,13 +690,19 @@ fn walkInstruction(
510690 // const body = zir.extra[extra_index..][0..body_len];
511691 extra_index += body_len;
512692
513 var field_type_indexes: std.ArrayListUnmanaged(DocData.WalkResult) = .{};
514 var field_name_indexes: std.ArrayListUnmanaged(usize) = .{};
693 var field_type_refs = try std.ArrayListUnmanaged(DocData.TypeRef).initCapacity(
694 self.arena,
695 fields_len,
696 );
697 var field_name_indexes = try std.ArrayListUnmanaged(usize).initCapacity(
698 self.arena,
699 fields_len,
700 );
515701 try self.collectUnionFieldInfo(
516702 zir,
517703 &scope,
518704 fields_len,
519 &field_type_indexes,
705 &field_type_refs,
520706 &field_name_indexes,
521707 extra_index,
522708 );
......@@ -524,12 +710,13 @@ fn walkInstruction(
524710 self.ast_nodes.items[self_ast_node_index].fields = field_name_indexes.items;
525711
526712 try self.types.append(self.arena, .{
527 .kind = @enumToInt(std.builtin.TypeId.Union),
528 .name = "todo_name",
529 .src = self_ast_node_index,
530 .privDecls = priv_decl_indexes.items,
531 .pubDecls = decl_indexes.items,
532 .fields = field_type_indexes.items,
713 .Union = .{
714 .name = "todo_name",
715 .src = self_ast_node_index,
716 .privDecls = priv_decl_indexes.items,
717 .pubDecls = decl_indexes.items,
718 .fields = field_type_refs.items,
719 },
533720 });
534721
535722 return DocData.WalkResult{ .type = self.types.items.len - 1 };
......@@ -649,11 +836,12 @@ fn walkInstruction(
649836 self.ast_nodes.items[self_ast_node_index].fields = field_name_indexes.items;
650837
651838 try self.types.append(self.arena, .{
652 .kind = @enumToInt(std.builtin.TypeId.Enum),
653 .name = "todo_name",
654 .src = self_ast_node_index,
655 .privDecls = priv_decl_indexes.items,
656 .pubDecls = decl_indexes.items,
839 .Enum = .{
840 .name = "todo_name",
841 .src = self_ast_node_index,
842 .privDecls = priv_decl_indexes.items,
843 .pubDecls = decl_indexes.items,
844 },
657845 });
658846
659847 return DocData.WalkResult{ .type = self.types.items.len - 1 };
......@@ -720,13 +908,13 @@ fn walkInstruction(
720908 // const body = zir.extra[extra_index..][0..body_len];
721909 extra_index += body_len;
722910
723 var field_type_indexes: std.ArrayListUnmanaged(DocData.WalkResult) = .{};
911 var field_type_refs: std.ArrayListUnmanaged(DocData.TypeRef) = .{};
724912 var field_name_indexes: std.ArrayListUnmanaged(usize) = .{};
725913 try self.collectStructFieldInfo(
726914 zir,
727915 &scope,
728916 fields_len,
729 &field_type_indexes,
917 &field_type_refs,
730918 &field_name_indexes,
731919 extra_index,
732920 );
......@@ -734,12 +922,13 @@ fn walkInstruction(
734922 self.ast_nodes.items[self_ast_node_index].fields = field_name_indexes.items;
735923
736924 try self.types.append(self.arena, .{
737 .kind = @enumToInt(std.builtin.TypeId.Struct),
738 .name = "todo_name",
739 .src = self_ast_node_index,
740 .privDecls = priv_decl_indexes.items,
741 .pubDecls = decl_indexes.items,
742 .fields = field_type_indexes.items,
925 .Struct = .{
926 .name = "todo_name",
927 .src = self_ast_node_index,
928 .privDecls = priv_decl_indexes.items,
929 .pubDecls = decl_indexes.items,
930 .fields = field_type_refs.items,
931 },
743932 });
744933
745934 return DocData.WalkResult{ .type = self.types.items.len - 1 };
......@@ -893,7 +1082,7 @@ fn collectUnionFieldInfo(
8931082 zir: Zir,
8941083 scope: *Scope,
8951084 fields_len: usize,
896 field_type_indexes: *std.ArrayListUnmanaged(DocData.WalkResult),
1085 field_type_refs: *std.ArrayListUnmanaged(DocData.TypeRef),
8971086 field_name_indexes: *std.ArrayListUnmanaged(usize),
8981087 ei: usize,
8991088) !void {
......@@ -939,7 +1128,10 @@ fn collectUnionFieldInfo(
9391128 // type
9401129 {
9411130 const walk_result = try self.walkRef(zir, scope, field_type);
942 try field_type_indexes.append(self.arena, walk_result);
1131 try field_type_refs.append(
1132 self.arena,
1133 walkResultToTypeRef(walk_result),
1134 );
9431135 }
9441136
9451137 // ast node
......@@ -962,7 +1154,7 @@ fn collectStructFieldInfo(
9621154 zir: Zir,
9631155 scope: *Scope,
9641156 fields_len: usize,
965 field_type_indexes: *std.ArrayListUnmanaged(DocData.WalkResult),
1157 field_type_refs: *std.ArrayListUnmanaged(DocData.TypeRef),
9661158 field_name_indexes: *std.ArrayListUnmanaged(usize),
9671159 ei: usize,
9681160) !void {
......@@ -1005,7 +1197,10 @@ fn collectStructFieldInfo(
10051197 // type
10061198 {
10071199 const walk_result = try self.walkRef(zir, scope, field_type);
1008 try field_type_indexes.append(self.arena, walk_result);
1200 try field_type_refs.append(
1201 self.arena,
1202 walkResultToTypeRef(walk_result),
1203 );
10091204 }
10101205
10111206 // ast node
......@@ -1120,7 +1315,7 @@ fn walkRef(
11201315fn walkResultToTypeRef(wr: DocData.WalkResult) DocData.TypeRef {
11211316 return switch (wr) {
11221317 else => std.debug.panic(
1123 "TODO: handle `{s}` in `walkInstruction.as_node.dest_type`\n",
1318 "TODO: handle `{s}` in `walkResultToTypeRef.as_node.dest_type`\n",
11241319 .{@tagName(wr)},
11251320 ),
11261321
......@@ -1128,3 +1323,7 @@ fn walkResultToTypeRef(wr: DocData.WalkResult) DocData.TypeRef {
11281323 .type => |v| .{ .type = v },
11291324 };
11301325}
1326
1327//fn collectParamInfo(self: *Autodoc, zir: Zir, scope: *Scope, inst_idx: Zir.Index) void {
1328
1329//}