authorgravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-02-22 20:15:39+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 19:10:11-07:00
logfbf0d0bee9c37c24b0b54962eaf05a535e814bc9
tree5bd13168a625fadef9e54ced147fbe5893daf3e4
parenta0ff7c80781f37f6d53a63f298f0f40229c26aa0

autodoc: fix decltest offset errors

while it would be preferable to not save decltests as first-class decls (and just embed their information inside the decl they refer), adding logic to skip them complicates the code too much so we should consider this an optimization for the future.

1 files changed, 93 insertions(+), 31 deletions(-)

src/Autodoc.zig+93-31
......@@ -65,7 +65,11 @@ pub fn generateZirData(self: *Autodoc) !void {
6565 // @tagName(t),
6666 //});
6767 break :blk .{
68 .Array = .{ .name = tmpbuf.toOwnedSlice() },
68 .Array = .{
69 .len = 1,
70 .name = tmpbuf.toOwnedSlice(),
71 .child = .{ .type = 0 },
72 },
6973 };
7074 },
7175 .u1_type,
......@@ -248,7 +252,7 @@ const DocData = struct {
248252
249253 const Decl = struct {
250254 name: []const u8,
251 kind: []const u8, // TODO: where do we find this info?
255 kind: []const u8,
252256 src: usize, // index into astNodes
253257 // typeRef: TypeRef,
254258 value: WalkResult,
......@@ -272,8 +276,15 @@ const DocData = struct {
272276 NoReturn: struct { name: []const u8 },
273277 Int: struct { name: []const u8 },
274278 Float: struct { name: []const u8 },
275 Pointer: struct { name: []const u8 },
276 Array: struct { name: []const u8 },
279 Pointer: struct {
280 name: []const u8,
281 child: TypeRef,
282 },
283 Array: struct {
284 name: []const u8,
285 len: usize,
286 child: TypeRef,
287 },
277288 Struct: struct {
278289 name: []const u8,
279290 src: ?usize = null, // index into astNodes
......@@ -286,7 +297,10 @@ const DocData = struct {
286297 ComptimeInt: struct { name: []const u8 },
287298 Undefined: struct { name: []const u8 },
288299 Null: struct { name: []const u8 },
289 Optional: struct { name: []const u8 },
300 Optional: struct {
301 name: []const u8,
302 child: TypeRef,
303 },
290304 ErrorUnion: struct { name: []const u8 },
291305 ErrorSet: struct { name: []const u8 },
292306 Enum: struct {
......@@ -335,6 +349,7 @@ const DocData = struct {
335349 .ComptimeInt => |v| try printTypeBody(v, options, w),
336350 .ComptimeFloat => |v| try printTypeBody(v, options, w),
337351 .Null => |v| try printTypeBody(v, options, w),
352 .Optional => |v| try printTypeBody(v, options, w),
338353
339354 .Struct => |v| try printTypeBody(v, options, w),
340355 .Fn => |v| try printTypeBody(v, options, w),
......@@ -376,13 +391,13 @@ const DocData = struct {
376391
377392 const TypeRef = union(enum) {
378393 unspecified,
379 declRef: usize, // index in `decls`
394 declPath: []usize, // indexes in `decls`
380395 type: usize, // index in `types`
381396 comptimeExpr: usize, // index in `comptimeExprs`
382397
383398 pub fn fromWalkResult(wr: WalkResult) TypeRef {
384399 return switch (wr) {
385 .declRef => |v| .{ .declRef = v },
400 .declPath => |v| .{ .declPath = v },
386401 .type => |v| .{ .type = v },
387402 else => @panic("Found non-type WalkResult"),
388403 };
......@@ -400,11 +415,18 @@ const DocData = struct {
400415 , .{});
401416 },
402417
403 .declRef, .type, .comptimeExpr => |v| {
418 .type, .comptimeExpr => |v| {
404419 try w.print(
405420 \\{{ "{s}":{} }}
406421 , .{ @tagName(self), v });
407422 },
423 .declPath => |v| {
424 try w.print("{{ \"declPath\": [", .{});
425 for (v) |d, i| {
426 const comma = if (i == v.len - 1) "]}" else ",";
427 try w.print("{d}{s}", .{ d, comma });
428 }
429 },
408430 }
409431 }
410432 };
......@@ -415,16 +437,10 @@ const DocData = struct {
415437 @"unreachable",
416438 @"null": TypeRef,
417439 @"undefined": TypeRef,
418 @"struct": struct {
419 typeRef: TypeRef,
420 fieldVals: []struct {
421 name: []const u8,
422 val: WalkResult,
423 },
424 },
440 @"struct": Struct,
425441 bool: bool,
426442 type: usize, // index in `types`
427 declRef: usize, // index in `decls`
443 declPath: []usize, // indices in `decls`
428444 int: struct {
429445 typeRef: TypeRef,
430446 value: usize, // direct value
......@@ -435,6 +451,14 @@ const DocData = struct {
435451 value: f64, // direct value
436452 negated: bool = false,
437453 },
454
455 const Struct = struct {
456 typeRef: TypeRef,
457 fieldVals: []struct {
458 name: []const u8,
459 val: WalkResult,
460 },
461 };
438462 pub fn jsonStringify(
439463 self: WalkResult,
440464 options: std.json.StringifyOptions,
......@@ -446,7 +470,7 @@ const DocData = struct {
446470 \\{{ "{s}":{{}} }}
447471 , .{@tagName(self)});
448472 },
449 .type, .declRef, .comptimeExpr => |v| {
473 .type, .comptimeExpr => |v| {
450474 try w.print(
451475 \\{{ "{s}":{} }}
452476 , .{ @tagName(self), v });
......@@ -478,12 +502,18 @@ const DocData = struct {
478502 },
479503 .@"undefined" => |v| try std.json.stringify(v, options, w),
480504 .@"null" => |v| try std.json.stringify(v, options, w),
481 .@"struct" => |v| try std.json.stringify(v, options, w),
482 // .decl_ref => |v| {
483 // try w.print(
484 // \\{{ "{s}":"{s}" }}
485 // , .{ @tagName(self), v });
486 // },
505 .@"struct" => |v| try std.json.stringify(
506 struct { @"struct": Struct }{ .@"struct" = v },
507 options,
508 w,
509 ),
510 .declPath => |v| {
511 try w.print("{{ \"declPath\": [", .{});
512 for (v) |d, i| {
513 const comma = if (i == v.len - 1) "]}" else ",";
514 try w.print("{d}{s}", .{ d, comma });
515 }
516 },
487517 }
488518 }
489519 };
......@@ -571,13 +601,15 @@ fn walkInstruction(
571601 "TODO: handle {s} in `walkInstruction.as_node`\n",
572602 .{@tagName(operand)},
573603 ),
574 .declRef => {},
604 .declPath, .type => {},
575605 // we don't do anything because up until now,
576606 // I've only seen this used as such:
577607 // @as(@as(type, Baz), .{})
578608 // and we don't want to toss away the
579609 // decl_val information (eg by replacing it with
580610 // a WalkResult.type).
611 // TODO: Actually, this is a good moment to check if
612 // the result is indeed a type!!
581613 .comptimeExpr => {
582614 self.comptimeExprs.items[operand.comptimeExpr].typeRef = dest_type_ref;
583615 },
......@@ -588,11 +620,39 @@ fn walkInstruction(
588620
589621 return operand;
590622 },
623 .optional_type => {
624 const un_node = data[inst_index].un_node;
625 var operand: DocData.WalkResult = try self.walkRef(
626 file,
627 parent_scope,
628 un_node.operand,
629 );
630 const type_ref = walkResultToTypeRef(operand);
631 const res = DocData.WalkResult{ .type = self.types.items.len };
632 try self.types.append(self.arena, .{
633 .Optional = .{ .name = "?TODO", .child = type_ref },
634 });
635 return res;
636 },
591637 .decl_val => {
592638 const str_tok = data[inst_index].str_tok;
593639 const decls_slot_index = parent_scope.resolveDeclName(str_tok.start);
594 return DocData.WalkResult{ .declRef = decls_slot_index };
640 var path = try self.arena.alloc(usize, 1);
641 path[0] = decls_slot_index;
642 return DocData.WalkResult{ .declPath = path };
595643 },
644 //.field_val => {
645 // const pl_node = data[inst_index].pl_node;
646 // const extra = file.zir.extraData(Zir.Inst.Field, pl_node.payload_index);
647 // // In case that we have a path (eg Foo.Bar.Baz.X.Y.Z),
648 // // then we want to deal with them in a while loop instead
649 // // of using `walkRef()`.
650 //
651 // var path = try self.arena.alloc(usize, 1);
652 // path[0] = decls_slot_index;
653 // return DocData.WalkResult{ .declPath = path };
654
655 //},
596656 .int_type => {
597657 const int_type = data[inst_index].int_type;
598658 const sign = if (int_type.signedness == .unsigned) "u" else "i";
......@@ -945,17 +1005,13 @@ fn walkInstruction(
9451005 // Done to make sure that all decl refs can be resolved correctly,
9461006 // even if we haven't fully analyzed the decl yet.
9471007 {
948 var actual_decls_len: usize = 0;
9491008 var it = file.zir.declIterator(@intCast(u32, inst_index));
1009 try self.decls.resize(self.arena, decls_first_index + it.decls_len);
9501010 var decls_slot_index = decls_first_index;
9511011 while (it.next()) |d| : (decls_slot_index += 1) {
9521012 const decl_name_index = file.zir.extra[d.sub_index + 5];
953 if (decl_name_index == 2) continue; // we don't do decltests here
954 actual_decls_len += 1;
9551013 try scope.insertDeclRef(self.arena, decl_name_index, decls_slot_index);
9561014 }
957 // we don't count decltests in our decls
958 try self.decls.resize(self.arena, decls_first_index + actual_decls_len);
9591015 }
9601016
9611017 extra_index = try self.walkDecls(
......@@ -1144,6 +1200,12 @@ fn walkDecls(
11441200 break :idx idx;
11451201 };
11461202 self.decls.items[decl_being_tested].decltest = ast_node_index;
1203 self.decls.items[decls_slot_index] = .{
1204 .name = "test",
1205 .src = ast_node_index,
1206 .value = .{ .type = 0 },
1207 .kind = "const",
1208 };
11471209 continue;
11481210 } else {
11491211 const raw_decl_name = file.zir.nullTerminatedString(decl_name_index);
......@@ -1450,7 +1512,7 @@ fn walkResultToTypeRef(wr: DocData.WalkResult) DocData.TypeRef {
14501512 .{@tagName(wr)},
14511513 ),
14521514
1453 .declRef => |v| .{ .declRef = v },
1515 .declPath => |v| .{ .declPath = v },
14541516 .type => |v| .{ .type = v },
14551517 };
14561518}