authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-08-23 17:37:06+02:00
committergravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-08-23 18:45:22+02:00
logb32e5a14ce20ae2943576de76d1af4c8bcc9dd72
tree6f979ca279de8d96951c55975978e92c1008e048
parent0482e8ba9d63ea009a9e0c2d497371261764d3e1

autodoc: handle self-referential call+field_type instructions


2 files changed, 37 insertions(+), 25 deletions(-)

lib/docs/main.js+1-2
......@@ -1438,8 +1438,7 @@ var zigAnalysis;
14381438 for (let i = 0; i < expr.struct.length; i++) {
14391439 const fv = expr.struct[i];
14401440 const field_name = fv.name;
1441 const exprArg = zigAnalysis.exprs[fv.val.expr.as.exprArg];
1442 let field_value = exprName(exprArg, opts);
1441 const field_value = exprName(fv.val.expr, opts);
14431442 // TODO: commented out because it seems not needed. if it deals
14441443 // with a corner case, please add a comment when re-enabling it.
14451444 // let field_value = exprArg[Object.keys(exprArg)[0]];
src/Autodoc.zig+36-23
......@@ -162,7 +162,7 @@ pub fn generateZirData(self: *Autodoc) !void {
162162 .Void = .{ .name = tmpbuf.toOwnedSlice() },
163163 },
164164 .type_info_type => .{
165 .Unanalyzed = .{},
165 .ComptimeExpr = .{ .name = tmpbuf.toOwnedSlice() },
166166 },
167167 .type_type => .{
168168 .Type = .{ .name = tmpbuf.toOwnedSlice() },
......@@ -1947,8 +1947,30 @@ fn walkInstruction(
19471947 }
19481948 };
19491949
1950 // If the lhs is a `call` instruction, it means that we're inside
1951 // a function call and we're referring to one of its arguments.
1952 // We can't just blindly analyze the instruction or we will
1953 // start recursing forever.
1954 // TODO: add proper resolution of the container type for `calls`
1955 // TODO: we're like testing lhs as an instruction twice
1956 // (above and below) this todo, maybe a cleaer solution woul
1957 // avoid that.
19501958 // TODO: double check that we really don't need type info here
1951 const wr = try self.walkRef(file, parent_scope, lhs_ref, false);
1959
1960 const wr = blk: {
1961 if (@enumToInt(lhs_ref) >= Ref.typed_value_map.len) {
1962 const lhs_inst = @enumToInt(lhs_ref) - Ref.typed_value_map.len;
1963 if (tags[lhs_inst] == .call) {
1964 break :blk DocData.WalkResult{
1965 .expr = .{
1966 .comptimeExpr = 0,
1967 },
1968 };
1969 }
1970 }
1971
1972 break :blk try self.walkRef(file, parent_scope, lhs_ref, false);
1973 };
19521974 try path.append(self.arena, wr.expr);
19531975
19541976 // This way the data in `path` has the same ordering that the ref
......@@ -2081,31 +2103,18 @@ fn walkInstruction(
20812103 extra.data.fields_len,
20822104 );
20832105
2084 log.debug("number of fields: {}", .{extra.data.fields_len});
20852106 var idx = extra.end;
20862107 for (field_vals) |*fv| {
20872108 const init_extra = file.zir.extraData(Zir.Inst.StructInitAnon.Item, idx);
20882109 const field_name = file.zir.nullTerminatedString(init_extra.data.field_name);
2089 fv.* = .{
2090 .name = field_name,
2091 .val = DocData.WalkResult{
2092 .expr = .{ .comptimeExpr = 0 },
2093 },
2094 };
2095 // printWithContext(
2096 // file,
2097 // inst_index,
2098 // "analyzing field [{}] %{} `{s}`",
2099 // .{ i, init_extra.data.init, field_name },
2100 // );
2101 // const value = try self.walkRef(
2102 // file,
2103 // parent_scope,
2104 // init_extra.data.init,
2105 // need_type,
2106 // );
2107 // fv.* = .{ .name = field_name, .val = value };
2108 // idx = init_extra.end;
2110 const value = try self.walkRef(
2111 file,
2112 parent_scope,
2113 init_extra.data.init,
2114 need_type,
2115 );
2116 fv.* = .{ .name = field_name, .val = value };
2117 idx = init_extra.end;
21092118 }
21102119
21112120 return DocData.WalkResult{
......@@ -3131,6 +3140,10 @@ fn tryResolveRefPath(
31313140 .{ @tagName(self.types.items[t_index]), resolved_parent },
31323141 );
31333142 },
3143 .ComptimeExpr => {
3144 // Same as the comptimeExpr branch above
3145 break :outer;
3146 },
31343147 .Unanalyzed => {
31353148 // This decl path is pending completion
31363149 {