authorgravatar for der.teufel.mail@gmail.comKrzysztof Wolicki <der.teufel.mail@gmail.com> 2023-09-03 17:18:16+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-09-03 17:18:16+02:00
log80c1d48ccb92f98484ab7ed48bbb2d7e9115349e
tree112621e3715040e75500e27b5c52b71cf2bced20
parent0516a4d62980f3908b056ac8f4605eb65c07675e
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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

* autodoc: Implement elem_val_node and basic optional_payload_* * autodoc: Add `.*` loads

3 files changed, 136 insertions(+), 2 deletions(-)

lib/docs/main.js+27-1
......@@ -1352,6 +1352,14 @@ Happy writing!
13521352 yield* ex(zigAnalysis.exprs[expr["&"]], opts);
13531353 return;
13541354 }
1355
1356 case "load": {
1357 yield* ex(zigAnalysis.exprs[expr.load], opts);
1358 yield Tok.period;
1359 yield Tok.asterisk;
1360 return;
1361 }
1362
13551363 case "call": {
13561364
13571365 let call = zigAnalysis.calls[expr.call];
......@@ -1453,6 +1461,24 @@ Happy writing!
14531461 return;
14541462 }
14551463
1464 case "optionalPayload": {
1465 const opt = zigAnalysis.exprs[expr.optionalPayload];
1466 yield* ex(opt, opts);
1467 yield Tok.period;
1468 yield Tok.question_mark;
1469 return;
1470 }
1471
1472 case "elemVal": {
1473 const lhs = zigAnalysis.exprs[expr.elemVal.lhs];
1474 const rhs = zigAnalysis.exprs[expr.elemVal.rhs];
1475 yield* ex(lhs);
1476 yield Tok.l_bracket;
1477 yield* ex(rhs);
1478 yield Tok.r_bracket;
1479 return;
1480 }
1481
14561482 case "string": {
14571483 yield { src: '"' + expr.string + '"', tag: Tag.string_literal };
14581484 return;
......@@ -1882,7 +1908,7 @@ Happy writing!
18821908 return;
18831909 }
18841910 case typeKinds.Optional: {
1885 yield { src: "?", tag: Tag.question_mark };
1911 yield Tok.question_mark;
18861912 yield* ex(typeObj.child, opts);
18871913 return;
18881914 }
lib/docs/ziglexer.js+2
......@@ -144,6 +144,8 @@ const Tok = {
144144 r_paren: { src: ")", tag: Tag.r_paren },
145145 period: { src: ".", tag: Tag.period },
146146 comma: { src: ",", tag: Tag.comma },
147 question_mark: { src: "?", tag: Tag.question_mark },
148 asterisk: { src: "*", tag: Tag.asterisk },
147149 identifier: (name) => { return { src: name, tag: Tag.identifier } },
148150};
149151
src/Autodoc.zig+107-1
......@@ -775,7 +775,9 @@ const DocData = struct {
775775 sizeOf: usize, // index in `exprs`
776776 bitSizeOf: usize, // index in `exprs`
777777 intFromEnum: usize, // index in `exprs`
778 compileError: usize, //index in `exprs`
778 compileError: usize, // index in `exprs`
779 optionalPayload: usize, // index in `exprs`
780 elemVal: ElemVal,
779781 errorSets: usize,
780782 string: []const u8, // direct value
781783 sliceIndex: usize,
......@@ -791,6 +793,7 @@ const DocData = struct {
791793 switchOp: SwitchOp,
792794 binOp: BinOp,
793795 binOpIndex: usize,
796 load: usize, // index in `exprs`
794797 const BinOp = struct {
795798 lhs: usize, // index in `exprs`
796799 rhs: usize, // index in `exprs`
......@@ -846,6 +849,11 @@ const DocData = struct {
846849 val: WalkResult,
847850 };
848851
852 const ElemVal = struct {
853 lhs: usize, // index in `exprs`
854 rhs: usize, // index in `exprs`
855 };
856
849857 pub fn jsonStringify(self: Expr, jsw: anytype) !void {
850858 const active_tag = std.meta.activeTag(self);
851859 try jsw.beginObject();
......@@ -1463,6 +1471,38 @@ fn walkInstruction(
14631471 };
14641472 },
14651473
1474 .load => {
1475 const un_node = data[inst_index].un_node;
1476 const operand = try self.walkRef(
1477 file,
1478 parent_scope,
1479 parent_src,
1480 un_node.operand,
1481 need_type,
1482 call_ctx,
1483 );
1484 const load_idx = self.exprs.items.len;
1485 try self.exprs.append(self.arena, operand.expr);
1486
1487 var typeRef: ?DocData.Expr = null;
1488 if (operand.typeRef) |ref| {
1489 switch (ref) {
1490 .type => |t_index| {
1491 switch (self.types.items[t_index]) {
1492 .Pointer => |p| typeRef = p.child,
1493 else => {},
1494 }
1495 },
1496 else => {},
1497 }
1498 }
1499
1500 return DocData.WalkResult{
1501 .typeRef = typeRef,
1502 .expr = .{ .load = load_idx },
1503 };
1504 },
1505
14661506 // @check array_cat and array_mul
14671507 .add,
14681508 .addwrap,
......@@ -2862,6 +2902,72 @@ fn walkInstruction(
28622902
28632903 return result;
28642904 },
2905 .optional_payload_safe, .optional_payload_unsafe => {
2906 const un_node = data[inst_index].un_node;
2907 const operand = try self.walkRef(
2908 file,
2909 parent_scope,
2910 parent_src,
2911 un_node.operand,
2912 need_type,
2913 call_ctx,
2914 );
2915 const optional_idx = self.exprs.items.len;
2916 try self.exprs.append(self.arena, operand.expr);
2917
2918 var typeRef: ?DocData.Expr = null;
2919 if (operand.typeRef) |ref| {
2920 switch (ref) {
2921 .type => |t_index| {
2922 const t = self.types.items[t_index];
2923 switch (t) {
2924 .Optional => |opt| typeRef = opt.child,
2925 else => {
2926 printWithContext(file, inst_index, "Invalid type for optional_payload_*: {}\n", .{t});
2927 },
2928 }
2929 },
2930 else => {},
2931 }
2932 }
2933
2934 return DocData.WalkResult{
2935 .typeRef = typeRef,
2936 .expr = .{ .optionalPayload = optional_idx },
2937 };
2938 },
2939 .elem_val_node => {
2940 const pl_node = data[inst_index].pl_node;
2941 const extra = file.zir.extraData(Zir.Inst.Bin, pl_node.payload_index);
2942 const lhs = try self.walkRef(
2943 file,
2944 parent_scope,
2945 parent_src,
2946 extra.data.lhs,
2947 need_type,
2948 call_ctx,
2949 );
2950 const rhs = try self.walkRef(
2951 file,
2952 parent_scope,
2953 parent_src,
2954 extra.data.rhs,
2955 need_type,
2956 call_ctx,
2957 );
2958 const lhs_idx = self.exprs.items.len;
2959 try self.exprs.append(self.arena, lhs.expr);
2960 const rhs_idx = self.exprs.items.len;
2961 try self.exprs.append(self.arena, rhs.expr);
2962 return DocData.WalkResult{
2963 .expr = .{
2964 .elemVal = .{
2965 .lhs = lhs_idx,
2966 .rhs = rhs_idx,
2967 },
2968 },
2969 };
2970 },
28652971 .extended => {
28662972 const extended = data[inst_index].extended;
28672973 switch (extended.opcode) {