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;...@@ -1438,8 +1438,7 @@ var zigAnalysis;
1438 for (let i = 0; i < expr.struct.length; i++) {1438 for (let i = 0; i < expr.struct.length; i++) {
1439 const fv = expr.struct[i];1439 const fv = expr.struct[i];
1440 const field_name = fv.name;1440 const field_name = fv.name;
1441 const exprArg = zigAnalysis.exprs[fv.val.expr.as.exprArg];1441 const field_value = exprName(fv.val.expr, opts);
1442 let field_value = exprName(exprArg, opts);
1443 // TODO: commented out because it seems not needed. if it deals1442 // TODO: commented out because it seems not needed. if it deals
1444 // with a corner case, please add a comment when re-enabling it.1443 // with a corner case, please add a comment when re-enabling it.
1445 // let field_value = exprArg[Object.keys(exprArg)[0]];1444 // let field_value = exprArg[Object.keys(exprArg)[0]];
src/Autodoc.zig+36-23
...@@ -162,7 +162,7 @@ pub fn generateZirData(self: *Autodoc) !void {...@@ -162,7 +162,7 @@ pub fn generateZirData(self: *Autodoc) !void {
162 .Void = .{ .name = tmpbuf.toOwnedSlice() },162 .Void = .{ .name = tmpbuf.toOwnedSlice() },
163 },163 },
164 .type_info_type => .{164 .type_info_type => .{
165 .Unanalyzed = .{},165 .ComptimeExpr = .{ .name = tmpbuf.toOwnedSlice() },
166 },166 },
167 .type_type => .{167 .type_type => .{
168 .Type = .{ .name = tmpbuf.toOwnedSlice() },168 .Type = .{ .name = tmpbuf.toOwnedSlice() },
...@@ -1947,8 +1947,30 @@ fn walkInstruction(...@@ -1947,8 +1947,30 @@ fn walkInstruction(
1947 }1947 }
1948 };1948 };
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.
1950 // TODO: double check that we really don't need type info here1958 // 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 };
1952 try path.append(self.arena, wr.expr);1974 try path.append(self.arena, wr.expr);
19531975
1954 // This way the data in `path` has the same ordering that the ref1976 // This way the data in `path` has the same ordering that the ref
...@@ -2081,31 +2103,18 @@ fn walkInstruction(...@@ -2081,31 +2103,18 @@ fn walkInstruction(
2081 extra.data.fields_len,2103 extra.data.fields_len,
2082 );2104 );
20832105
2084 log.debug("number of fields: {}", .{extra.data.fields_len});
2085 var idx = extra.end;2106 var idx = extra.end;
2086 for (field_vals) |*fv| {2107 for (field_vals) |*fv| {
2087 const init_extra = file.zir.extraData(Zir.Inst.StructInitAnon.Item, idx);2108 const init_extra = file.zir.extraData(Zir.Inst.StructInitAnon.Item, idx);
2088 const field_name = file.zir.nullTerminatedString(init_extra.data.field_name);2109 const field_name = file.zir.nullTerminatedString(init_extra.data.field_name);
2089 fv.* = .{2110 const value = try self.walkRef(
2090 .name = field_name,2111 file,
2091 .val = DocData.WalkResult{2112 parent_scope,
2092 .expr = .{ .comptimeExpr = 0 },2113 init_extra.data.init,
2093 },2114 need_type,
2094 };2115 );
2095 // printWithContext(2116 fv.* = .{ .name = field_name, .val = value };
2096 // file,2117 idx = init_extra.end;
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;
2109 }2118 }
21102119
2111 return DocData.WalkResult{2120 return DocData.WalkResult{
...@@ -3131,6 +3140,10 @@ fn tryResolveRefPath(...@@ -3131,6 +3140,10 @@ fn tryResolveRefPath(
3131 .{ @tagName(self.types.items[t_index]), resolved_parent },3140 .{ @tagName(self.types.items[t_index]), resolved_parent },
3132 );3141 );
3133 },3142 },
3143 .ComptimeExpr => {
3144 // Same as the comptimeExpr branch above
3145 break :outer;
3146 },
3134 .Unanalyzed => {3147 .Unanalyzed => {
3135 // This decl path is pending completion3148 // This decl path is pending completion
3136 {3149 {