authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-03-03 19:15:04+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:11-07:00
log195231b212492cda5e75bcdb347765e7ca035f1c
treed80ebd90bad5af0e90795d624cd3be96ab0c1ccf
parent028c8a3c91286fe42d915cfe35976e3392895447

autodoc: add support for non-generic function calls


2 files changed, 58 insertions(+), 21 deletions(-)

lib/docs/main.js+12-1
...@@ -82,7 +82,7 @@...@@ -82,7 +82,7 @@
82 // map of decl index to list of non-generic fn indexes82 // map of decl index to list of non-generic fn indexes
83 // var nodesToFnsMap = indexNodesToFns();83 // var nodesToFnsMap = indexNodesToFns();
84 // map of decl index to list of comptime fn calls84 // map of decl index to list of comptime fn calls
85 var nodesToCallsMap = indexNodesToCalls();85 // var nodesToCallsMap = indexNodesToCalls();
8686
87 domSearch.addEventListener('keydown', onSearchKeyDown, false);87 domSearch.addEventListener('keydown', onSearchKeyDown, false);
88 window.addEventListener('hashchange', onHashChange, false);88 window.addEventListener('hashchange', onHashChange, false);
...@@ -193,6 +193,17 @@...@@ -193,6 +193,17 @@
193 return resolveTypeRefToTypeId(cte.typeRef);193 return resolveTypeRefToTypeId(cte.typeRef);
194 }194 }
195195
196 if ("call" in decl.value) {
197 const fn_call = zigAnalysis.calls[decl.value.call];
198 console.assert("declPath" in fn_call.func);
199 const fn_decl = zigAnalysis.decls[fn_call.func.declPath[0]];
200 const fn_decl_value = resolveValue(fn_decl.value);
201 console.assert("type" in fn_decl_value); //TODO handle comptimeExpr
202 const fn_type = zigAnalysis.types[fn_decl_value.type];
203 console.assert(fn_type.kind === typeKinds.Fn);
204 return resolveTypeRefToTypeId(fn_type.ret);
205 }
206
196 console.log("TODO: handle in `typeOfDecl` more cases: ", decl);207 console.log("TODO: handle in `typeOfDecl` more cases: ", decl);
197 console.assert(false);208 console.assert(false);
198 throw {};209 throw {};
src/Autodoc.zig+46-20
...@@ -10,6 +10,7 @@ module: *Module,...@@ -10,6 +10,7 @@ module: *Module,
10doc_location: Compilation.EmitLoc,10doc_location: Compilation.EmitLoc,
11arena: std.mem.Allocator,11arena: std.mem.Allocator,
12files: std.AutoHashMapUnmanaged(*File, usize) = .{},12files: std.AutoHashMapUnmanaged(*File, usize) = .{},
13calls: std.ArrayListUnmanaged(DocData.Call) = .{},
13types: std.ArrayListUnmanaged(DocData.Type) = .{},14types: std.ArrayListUnmanaged(DocData.Type) = .{},
14decls: std.ArrayListUnmanaged(DocData.Decl) = .{},15decls: std.ArrayListUnmanaged(DocData.Decl) = .{},
15ast_nodes: std.ArrayListUnmanaged(DocData.AstNode) = .{},16ast_nodes: std.ArrayListUnmanaged(DocData.AstNode) = .{},
...@@ -155,6 +156,7 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -155,6 +156,7 @@ pub fn generateZirData(self: *Autodoc) !void {
155156
156 var data = DocData{157 var data = DocData{
157 .files = .{ .data = self.files },158 .files = .{ .data = self.files },
159 .calls = self.calls.items,
158 .types = self.types.items,160 .types = self.types.items,
159 .decls = self.decls.items,161 .decls = self.decls.items,
160 .astNodes = self.ast_nodes.items,162 .astNodes = self.ast_nodes.items,
...@@ -240,10 +242,10 @@ const DocData = struct {...@@ -240,10 +242,10 @@ const DocData = struct {
240 } = .{},242 } = .{},
241 packages: [1]Package = .{.{}},243 packages: [1]Package = .{.{}},
242 errors: []struct {} = &.{},244 errors: []struct {} = &.{},
243 calls: []struct {} = &.{},
244245
245 // non-hardcoded stuff246 // non-hardcoded stuff
246 astNodes: []AstNode,247 astNodes: []AstNode,
248 calls: []Call,
247 files: struct {249 files: struct {
248 // this struct is a temporary hack to support json serialization250 // this struct is a temporary hack to support json serialization
249 data: std.AutoHashMapUnmanaged(*File, usize),251 data: std.AutoHashMapUnmanaged(*File, usize),
...@@ -274,7 +276,11 @@ const DocData = struct {...@@ -274,7 +276,11 @@ const DocData = struct {
274 types: []Type,276 types: []Type,
275 decls: []Decl,277 decls: []Decl,
276 comptimeExprs: []ComptimeExpr,278 comptimeExprs: []ComptimeExpr,
277279 const Call = struct {
280 func: TypeRef,
281 args: []WalkResult,
282 ret: WalkResult,
283 };
278 const DocTypeKinds = blk: {284 const DocTypeKinds = blk: {
279 var info = @typeInfo(std.builtin.TypeId);285 var info = @typeInfo(std.builtin.TypeId);
280 const original_len = info.Enum.fields.len;286 const original_len = info.Enum.fields.len;
...@@ -344,8 +350,8 @@ const DocData = struct {...@@ -344,8 +350,8 @@ const DocData = struct {
344 Struct: struct {350 Struct: struct {
345 name: []const u8,351 name: []const u8,
346 src: ?usize = null, // index into astNodes352 src: ?usize = null, // index into astNodes
347 privDecls: ?[]usize = null, // index into decls353 privDecls: []usize = &.{}, // index into decls
348 pubDecls: []usize, // index into decls354 pubDecls: []usize = &.{}, // index into decls
349 fields: ?[]TypeRef = null, // (use src->fields to find names)355 fields: ?[]TypeRef = null, // (use src->fields to find names)
350 },356 },
351 ComptimeExpr: struct { name: []const u8 },357 ComptimeExpr: struct { name: []const u8 },
...@@ -507,6 +513,7 @@ const DocData = struct {...@@ -507,6 +513,7 @@ const DocData = struct {
507 value: f64, // direct value513 value: f64, // direct value
508 negated: bool = false,514 negated: bool = false,
509 },515 },
516 call: usize, // index in `calls`
510517
511 const Struct = struct {518 const Struct = struct {
512 typeRef: TypeRef,519 typeRef: TypeRef,
...@@ -526,7 +533,7 @@ const DocData = struct {...@@ -526,7 +533,7 @@ const DocData = struct {
526 \\{{ "{s}":{{}} }}533 \\{{ "{s}":{{}} }}
527 , .{@tagName(self)});534 , .{@tagName(self)});
528 },535 },
529 .type, .comptimeExpr => |v| {536 .type, .comptimeExpr, .call => |v| {
530 try w.print(537 try w.print(
531 \\{{ "{s}":{} }}538 \\{{ "{s}":{} }}
532 , .{ @tagName(self), v });539 , .{ @tagName(self), v });
...@@ -616,14 +623,7 @@ fn walkInstruction(...@@ -616,14 +623,7 @@ fn walkInstruction(
616623
617 return new_file_walk_result;624 return new_file_walk_result;
618 },625 },
619 .block => {626
620 const res = DocData.WalkResult{ .comptimeExpr = self.comptime_exprs.items.len };
621 try self.comptime_exprs.append(self.arena, .{
622 .code = "if(banana) 1 else 0",
623 .typeRef = .{ .type = 0 },
624 });
625 return res;
626 },
627 .int => {627 .int => {
628 const int = data[inst_index].int;628 const int = data[inst_index].int;
629 return DocData.WalkResult{629 return DocData.WalkResult{
...@@ -755,16 +755,42 @@ fn walkInstruction(...@@ -755,16 +755,42 @@ fn walkInstruction(
755 });755 });
756 return DocData.WalkResult{ .type = self.types.items.len - 1 };756 return DocData.WalkResult{ .type = self.types.items.len - 1 };
757 },757 },
758 //.block => {758 .block => {
759 //const pl_node = data[inst_index].pl_node;759 const res = DocData.WalkResult{ .comptimeExpr = self.comptime_exprs.items.len };
760 //const extra = file.zir.extraData(Zir.Inst.Block, pl_node.payload_index);760 try self.comptime_exprs.append(self.arena, .{
761 //const last_instr_index = file.zir.extra[extra.end..][extra.data.body_len - 1];761 .code = "if(banana) 1 else 0",
762 //const break_operand = data[break_index].@"break".operand;762 .typeRef = .{ .type = 0 },
763 //return self.walkRef(file, parent_scope, break_operand);763 });
764 //},764 return res;
765 },
765 .block_inline => {766 .block_inline => {
766 return self.walkRef(file, parent_scope, getBlockInlineBreak(file.zir, inst_index));767 return self.walkRef(file, parent_scope, getBlockInlineBreak(file.zir, inst_index));
767 },768 },
769 .call => {
770 const pl_node = data[inst_index].pl_node;
771 const extra = file.zir.extraData(Zir.Inst.Call, pl_node.payload_index);
772
773 // TODO: handle the way scoping works with fn args
774 const callee = DocData.TypeRef.fromWalkResult(
775 try self.walkRef(file, parent_scope, extra.data.callee),
776 );
777
778 const args_len = extra.data.flags.args_len;
779 var args = try self.arena.alloc(DocData.WalkResult, args_len);
780 const arg_refs = file.zir.refSlice(extra.end, args_len);
781 for (arg_refs) |ref, idx| {
782 args[idx] = try self.walkRef(file, parent_scope, ref);
783 }
784
785 const call_slot_index = self.calls.items.len;
786 try self.calls.append(self.arena, .{
787 .func = callee,
788 .args = args,
789 .ret = .{ .void = {} }, // TODO: handle returns!
790 });
791
792 return DocData.WalkResult{ .call = call_slot_index };
793 },
768 .func => {794 .func => {
769 const fn_info = file.zir.getFnInfo(@intCast(u32, inst_index));795 const fn_info = file.zir.getFnInfo(@intCast(u32, inst_index));
770796