authorgravatar for vallahor91@gmail.comVallahor <vallahor91@gmail.com> 2022-05-24 22:14:05-03:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:11-07:00
log2a3fb341aa4e4603774289627c8eb397fdc854d1
tree0278bf1323b246b0711a0cf4ad5cd97b18120609
parentd707cd6e6df0aca14a9faaf2b411b3c4a3f08d10

fix: handling more types of sentinels. now can be structs too


2 files changed, 86 insertions(+), 40 deletions(-)

lib/docs/main.js+26-2
......@@ -1062,6 +1062,30 @@ var zigAnalysis;
10621062 function exprName(expr, opts) {
10631063 switch (Object.keys(expr)[0]) {
10641064 default: throw "oh no";
1065 case "struct": {
1066 const struct_name = zigAnalysis.decls[expr.struct[0].val.typeRef.refPath[0].declRef].name;
1067 let struct_body = "";
1068 struct_body += struct_name + "{ ";
1069 for (let i = 0; i < expr.struct.length; i++) {
1070 const val = expr.struct[i].name
1071 const exprArg = zigAnalysis.exprs[expr.struct[i].val.expr.as.exprArg];
1072 let value_field = exprArg[Object.keys(exprArg)[0]];
1073 if (value_field instanceof Object) {
1074 value_field = zigAnalysis.decls[value_field[0].val.typeRef.refPath[0].declRef].name;
1075 };
1076 struct_body += "." + val + " = " + value_field;
1077 if (i !== expr.struct.length - 1) {
1078 struct_body += ", ";
1079 } else {
1080 struct_body += " ";
1081 }
1082 }
1083 struct_body += "}";
1084 return struct_body;
1085 }
1086 case "null": {
1087 return "null";
1088 }
10651089 case "array": {
10661090 let payloadHtml = ".{";
10671091 for (let i = 0; i < expr.array.length; i++) {
......@@ -1141,7 +1165,7 @@ var zigAnalysis;
11411165 let arrayObj = /** @type {ArrayType} */ (typeObj);
11421166 let name = "[";
11431167 let lenName = exprName(arrayObj.len, opts);
1144 let sentinel = arrayObj.sentinel ? ":0" : "";
1168 let sentinel = arrayObj.sentinel ? ":"+exprName(arrayObj.sentinel, opts) : "";
11451169 let is_mutable = arrayObj.is_multable ? "const " : "";
11461170
11471171 if (opts.wantHtml) {
......@@ -1160,7 +1184,7 @@ var zigAnalysis;
11601184 case typeKinds.Pointer:
11611185 {
11621186 let ptrObj = /** @type {PointerType} */(typeObj);
1163 let sentinel = ptrObj.sentinel ? ":0" : "";
1187 let sentinel = ptrObj.sentinel ? ":"+exprName(ptrObj.sentinel, opts) : "";
11641188 let is_mutable = !ptrObj.is_mutable ? "const " : "";
11651189 let name = "";
11661190 switch (ptrObj.size) {
src/Autodoc.zig+60-38
......@@ -383,13 +383,13 @@ const DocData = struct {
383383 Pointer: struct {
384384 size: std.builtin.TypeInfo.Pointer.Size,
385385 child: Expr,
386 sentinel: bool = false,
386 sentinel: ?Expr = null,
387387 is_mutable: bool = true,
388388 },
389389 Array: struct {
390390 len: Expr,
391391 child: Expr,
392 sentinel: bool = false,
392 sentinel: ?Expr = null,
393393 },
394394 Struct: struct {
395395 name: []const u8,
......@@ -482,11 +482,14 @@ const DocData = struct {
482482 \\
483483 , .{@enumToInt(v.size)});
484484 if (options.whitespace) |ws| try ws.outputIndent(w);
485 try w.print(
486 \\"sentinel": {},
487 \\
488 , .{v.sentinel});
489 if (options.whitespace) |ws| try ws.outputIndent(w);
485 if (v.sentinel) |sentinel| {
486 try w.print(
487 \\"sentinel":
488 , .{});
489 if (options.whitespace) |*ws| ws.indent_level += 1;
490 try sentinel.jsonStringify(options, w);
491 try w.print(",", .{});
492 }
490493 try w.print(
491494 \\"is_mutable": {},
492495 \\
......@@ -766,7 +769,10 @@ fn walkInstruction(
766769 .Array = .{
767770 .len = .{ .int = .{ .value = str.len } },
768771 .child = .{ .type = @enumToInt(Ref.u8_type) },
769 .sentinel = true,
772 .sentinel = .{ .int = .{
773 .value = 0,
774 .negated = false,
775 } },
770776 },
771777 });
772778 // const sentinel: ?usize = if (ptr.flags.has_sentinel) 0 else null;
......@@ -775,7 +781,10 @@ fn walkInstruction(
775781 .Pointer = .{
776782 .size = .One,
777783 .child = .{ .type = arrTypeId },
778 .sentinel = true,
784 .sentinel = .{ .int = .{
785 .value = 0,
786 .negated = false,
787 } },
779788 .is_mutable = false,
780789 },
781790 });
......@@ -842,10 +851,7 @@ fn walkInstruction(
842851 false,
843852 );
844853
845 return DocData.WalkResult{
846 .typeRef = .{ .type = operand.typeRef.?.type },
847 .expr = .{ .type = operand.expr.type },
848 };
854 return operand;
849855 },
850856 .ptr_type_simple => {
851857 const ptr = data[inst_index].ptr_type_simple;
......@@ -868,8 +874,6 @@ fn walkInstruction(
868874 const ptr = data[inst_index].ptr_type;
869875 const extra = file.zir.extraData(Zir.Inst.PtrType, ptr.payload_index);
870876
871 const sentinel: bool = if (ptr.flags.has_sentinel) true else false;
872
873877 const type_slot_index = self.types.items.len;
874878 const elem_type_ref = try self.walkRef(
875879 file,
......@@ -877,8 +881,9 @@ fn walkInstruction(
877881 extra.data.elem_type,
878882 false,
879883 );
884
880885 try self.types.append(self.arena, .{
881 .Pointer = .{ .size = ptr.size, .child = elem_type_ref.expr, .sentinel = sentinel, .is_mutable = ptr.flags.is_mutable },
886 .Pointer = .{ .size = ptr.size, .child = elem_type_ref.expr, .sentinel = .{ .int = .{ .value = 0, .negated = false } }, .is_mutable = ptr.flags.is_mutable },
882887 });
883888 return DocData.WalkResult{
884889 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
......@@ -907,7 +912,7 @@ fn walkInstruction(
907912 const pl_node = data[inst_index].pl_node;
908913 const extra = file.zir.extraData(Zir.Inst.ArrayTypeSentinel, pl_node.payload_index);
909914 const len = try self.walkRef(file, parent_scope, extra.data.len, false);
910 // const sentinel = try self.walkRef(file, parent_scope, extra.data.sentinel, false);
915 const sentinel = try self.walkRef(file, parent_scope, extra.data.sentinel, false);
911916 const elem_type = try self.walkRef(file, parent_scope, extra.data.elem_type, false);
912917
913918 const type_slot_index = self.types.items.len;
......@@ -915,7 +920,7 @@ fn walkInstruction(
915920 .Array = .{
916921 .len = len.expr,
917922 .child = elem_type.expr,
918 .sentinel = true,
923 .sentinel = sentinel.expr,
919924 },
920925 });
921926 return DocData.WalkResult{
......@@ -966,12 +971,12 @@ fn walkInstruction(
966971 .array_init_sent => {
967972 const pl_node = data[inst_index].pl_node;
968973 const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index);
969 const operands = file.zir.refSlice(extra.end, extra.data.operands_len - 1);
970 const array_data = try self.arena.alloc(usize, operands.len);
974 const operands = file.zir.refSlice(extra.end, extra.data.operands_len);
975 const array_data = try self.arena.alloc(usize, operands.len - 1);
971976
972977 // TODO: make sure that you want the array to be fully normalized for real
973978 // then update this code to conform to your choice.
974
979 var sentinel: ?DocData.Expr = null;
975980 var array_type: ?DocData.Expr = null;
976981 for (operands) |op, idx| {
977982 // we only ask to figure out type info for the first element
......@@ -981,20 +986,21 @@ fn walkInstruction(
981986 array_type = wr.typeRef;
982987 }
983988
984 // We know that Zir wraps every operand in an @as expression
985 // so we want to peel it away and only save the target type
986 // once, since we need it later to define the array type.
987 array_data[idx] = wr.expr.as.exprArg;
989 if (idx == extra.data.operands_len - 1) {
990 sentinel = self.exprs.items[wr.expr.as.exprArg];
991 } else {
992 array_data[idx] = wr.expr.as.exprArg;
993 }
988994 }
989995
990996 const type_slot_index = self.types.items.len;
991997 try self.types.append(self.arena, .{
992998 .Array = .{ .len = .{
993999 .int = .{
994 .value = operands.len,
1000 .value = operands.len - 1,
9951001 .negated = false,
9961002 },
997 }, .child = array_type.?, .sentinel = true },
1003 }, .child = array_type.?, .sentinel = sentinel },
9981004 });
9991005
10001006 return DocData.WalkResult{
......@@ -1084,28 +1090,36 @@ fn walkInstruction(
10841090 .array_init_sent_ref => {
10851091 const pl_node = data[inst_index].pl_node;
10861092 const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index);
1087 // the sentinel terminator are calculated at compile time
1088 // (extra.data.operands_len - 1) is to not account for that
1089 const operands = file.zir.refSlice(extra.end, extra.data.operands_len - 1);
1090 const array_data = try self.arena.alloc(usize, operands.len);
1093 const operands = file.zir.refSlice(extra.end, extra.data.operands_len);
1094 const array_data = try self.arena.alloc(usize, operands.len - 1);
1095
1096 // TODO: This should output:
1097 // const array: *[value:sentinel]type = &.{};
1098 // but right now it's printing:
1099 // const array: [value:sentinel]u8 = .{};
10911100
1101 var sentinel: ?DocData.Expr = null;
10921102 var array_type: ?DocData.Expr = null;
10931103 for (operands) |op, idx| {
10941104 const wr = try self.walkRef(file, parent_scope, op, idx == 0);
10951105 if (idx == 0) {
10961106 array_type = wr.typeRef;
10971107 }
1098 array_data[idx] = wr.expr.as.exprArg;
1108 if (idx == extra.data.operands_len - 1) {
1109 sentinel = self.exprs.items[wr.expr.as.exprArg];
1110 } else {
1111 array_data[idx] = wr.expr.as.exprArg;
1112 }
10991113 }
11001114
11011115 const type_slot_index = self.types.items.len;
11021116 try self.types.append(self.arena, .{
11031117 .Array = .{ .len = .{
11041118 .int = .{
1105 .value = operands.len,
1119 .value = operands.len - 1,
11061120 .negated = false,
11071121 },
1108 }, .child = array_type.?, .sentinel = true },
1122 }, .child = array_type.?, .sentinel = sentinel },
11091123 });
11101124
11111125 return DocData.WalkResult{
......@@ -1117,7 +1131,9 @@ fn walkInstruction(
11171131 const pl_node = data[inst_index].pl_node;
11181132 const extra = file.zir.extraData(Zir.Inst.MultiOp, pl_node.payload_index);
11191133 const operands = file.zir.refSlice(extra.end, extra.data.operands_len);
1120 const array_data = try self.arena.alloc(usize, operands.len);
1134 const array_data = try self.arena.alloc(usize, operands.len - 1);
1135
1136 var sentinel: ?DocData.Expr = null;
11211137
11221138 var array_type: ?DocData.Expr = null;
11231139 for (operands) |op, idx| {
......@@ -1125,17 +1141,23 @@ fn walkInstruction(
11251141 if (idx == 0) {
11261142 array_type = wr.typeRef;
11271143 }
1128 array_data[idx] = wr.expr.int.value;
1144
1145 if (idx == extra.data.operands_len - 1) {
1146 sentinel = wr.expr;
1147 const expr_index = self.exprs.items.len;
1148 try self.exprs.append(self.arena, wr.expr);
1149 array_data[idx] = expr_index;
1150 }
11291151 }
11301152
11311153 const type_slot_index = self.types.items.len;
11321154 try self.types.append(self.arena, .{
11331155 .Array = .{ .len = .{
11341156 .int = .{
1135 .value = operands.len,
1157 .value = operands.len - 1,
11361158 .negated = false,
11371159 },
1138 }, .child = array_type.? },
1160 }, .child = array_type.?, .sentinel = sentinel },
11391161 });
11401162
11411163 return DocData.WalkResult{