autodoc: Implement a[b], a.?, and a.* (#16863)

* autodoc: Implement elem_val_node and basic optional_payload_*

* autodoc: Add `.*` loads
This commit is contained in:
Krzysztof Wolicki 2023-09-03 17:18:16 +02:00 committed by GitHub
parent 0516a4d629
commit 80c1d48ccb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 136 additions and 2 deletions

View File

@ -1352,6 +1352,14 @@ Happy writing!
yield* ex(zigAnalysis.exprs[expr["&"]], opts); yield* ex(zigAnalysis.exprs[expr["&"]], opts);
return; return;
} }
case "load": {
yield* ex(zigAnalysis.exprs[expr.load], opts);
yield Tok.period;
yield Tok.asterisk;
return;
}
case "call": { case "call": {
let call = zigAnalysis.calls[expr.call]; let call = zigAnalysis.calls[expr.call];
@ -1453,6 +1461,24 @@ Happy writing!
return; return;
} }
case "optionalPayload": {
const opt = zigAnalysis.exprs[expr.optionalPayload];
yield* ex(opt, opts);
yield Tok.period;
yield Tok.question_mark;
return;
}
case "elemVal": {
const lhs = zigAnalysis.exprs[expr.elemVal.lhs];
const rhs = zigAnalysis.exprs[expr.elemVal.rhs];
yield* ex(lhs);
yield Tok.l_bracket;
yield* ex(rhs);
yield Tok.r_bracket;
return;
}
case "string": { case "string": {
yield { src: '"' + expr.string + '"', tag: Tag.string_literal }; yield { src: '"' + expr.string + '"', tag: Tag.string_literal };
return; return;
@ -1882,7 +1908,7 @@ Happy writing!
return; return;
} }
case typeKinds.Optional: { case typeKinds.Optional: {
yield { src: "?", tag: Tag.question_mark }; yield Tok.question_mark;
yield* ex(typeObj.child, opts); yield* ex(typeObj.child, opts);
return; return;
} }

View File

@ -144,6 +144,8 @@ const Tok = {
r_paren: { src: ")", tag: Tag.r_paren }, r_paren: { src: ")", tag: Tag.r_paren },
period: { src: ".", tag: Tag.period }, period: { src: ".", tag: Tag.period },
comma: { src: ",", tag: Tag.comma }, comma: { src: ",", tag: Tag.comma },
question_mark: { src: "?", tag: Tag.question_mark },
asterisk: { src: "*", tag: Tag.asterisk },
identifier: (name) => { return { src: name, tag: Tag.identifier } }, identifier: (name) => { return { src: name, tag: Tag.identifier } },
}; };

View File

@ -775,7 +775,9 @@ const DocData = struct {
sizeOf: usize, // index in `exprs` sizeOf: usize, // index in `exprs`
bitSizeOf: usize, // index in `exprs` bitSizeOf: usize, // index in `exprs`
intFromEnum: usize, // index in `exprs` intFromEnum: usize, // index in `exprs`
compileError: usize, //index in `exprs` compileError: usize, // index in `exprs`
optionalPayload: usize, // index in `exprs`
elemVal: ElemVal,
errorSets: usize, errorSets: usize,
string: []const u8, // direct value string: []const u8, // direct value
sliceIndex: usize, sliceIndex: usize,
@ -791,6 +793,7 @@ const DocData = struct {
switchOp: SwitchOp, switchOp: SwitchOp,
binOp: BinOp, binOp: BinOp,
binOpIndex: usize, binOpIndex: usize,
load: usize, // index in `exprs`
const BinOp = struct { const BinOp = struct {
lhs: usize, // index in `exprs` lhs: usize, // index in `exprs`
rhs: usize, // index in `exprs` rhs: usize, // index in `exprs`
@ -846,6 +849,11 @@ const DocData = struct {
val: WalkResult, val: WalkResult,
}; };
const ElemVal = struct {
lhs: usize, // index in `exprs`
rhs: usize, // index in `exprs`
};
pub fn jsonStringify(self: Expr, jsw: anytype) !void { pub fn jsonStringify(self: Expr, jsw: anytype) !void {
const active_tag = std.meta.activeTag(self); const active_tag = std.meta.activeTag(self);
try jsw.beginObject(); try jsw.beginObject();
@ -1463,6 +1471,38 @@ fn walkInstruction(
}; };
}, },
.load => {
const un_node = data[inst_index].un_node;
const operand = try self.walkRef(
file,
parent_scope,
parent_src,
un_node.operand,
need_type,
call_ctx,
);
const load_idx = self.exprs.items.len;
try self.exprs.append(self.arena, operand.expr);
var typeRef: ?DocData.Expr = null;
if (operand.typeRef) |ref| {
switch (ref) {
.type => |t_index| {
switch (self.types.items[t_index]) {
.Pointer => |p| typeRef = p.child,
else => {},
}
},
else => {},
}
}
return DocData.WalkResult{
.typeRef = typeRef,
.expr = .{ .load = load_idx },
};
},
// @check array_cat and array_mul // @check array_cat and array_mul
.add, .add,
.addwrap, .addwrap,
@ -2862,6 +2902,72 @@ fn walkInstruction(
return result; return result;
}, },
.optional_payload_safe, .optional_payload_unsafe => {
const un_node = data[inst_index].un_node;
const operand = try self.walkRef(
file,
parent_scope,
parent_src,
un_node.operand,
need_type,
call_ctx,
);
const optional_idx = self.exprs.items.len;
try self.exprs.append(self.arena, operand.expr);
var typeRef: ?DocData.Expr = null;
if (operand.typeRef) |ref| {
switch (ref) {
.type => |t_index| {
const t = self.types.items[t_index];
switch (t) {
.Optional => |opt| typeRef = opt.child,
else => {
printWithContext(file, inst_index, "Invalid type for optional_payload_*: {}\n", .{t});
},
}
},
else => {},
}
}
return DocData.WalkResult{
.typeRef = typeRef,
.expr = .{ .optionalPayload = optional_idx },
};
},
.elem_val_node => {
const pl_node = data[inst_index].pl_node;
const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index);
const lhs = try self.walkRef(
file,
parent_scope,
parent_src,
extra.data.lhs,
need_type,
call_ctx,
);
const rhs = try self.walkRef(
file,
parent_scope,
parent_src,
extra.data.rhs,
need_type,
call_ctx,
);
const lhs_idx = self.exprs.items.len;
try self.exprs.append(self.arena, lhs.expr);
const rhs_idx = self.exprs.items.len;
try self.exprs.append(self.arena, rhs.expr);
return DocData.WalkResult{
.expr = .{
.elemVal = .{
.lhs = lhs_idx,
.rhs = rhs_idx,
},
},
};
},
.extended => { .extended => {
const extended = data[inst_index].extended; const extended = data[inst_index].extended;
switch (extended.opcode) { switch (extended.opcode) {