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 {...@@ -65,7 +65,11 @@ pub fn generateZirData(self: *Autodoc) !void {
65 // @tagName(t),65 // @tagName(t),
66 //});66 //});
67 break :blk .{67 break :blk .{
68 .Array = .{ .name = tmpbuf.toOwnedSlice() },68 .Array = .{
69 .len = 1,
70 .name = tmpbuf.toOwnedSlice(),
71 .child = .{ .type = 0 },
72 },
69 };73 };
70 },74 },
71 .u1_type,75 .u1_type,
...@@ -248,7 +252,7 @@ const DocData = struct {...@@ -248,7 +252,7 @@ const DocData = struct {
248252
249 const Decl = struct {253 const Decl = struct {
250 name: []const u8,254 name: []const u8,
251 kind: []const u8, // TODO: where do we find this info?255 kind: []const u8,
252 src: usize, // index into astNodes256 src: usize, // index into astNodes
253 // typeRef: TypeRef,257 // typeRef: TypeRef,
254 value: WalkResult,258 value: WalkResult,
...@@ -272,8 +276,15 @@ const DocData = struct {...@@ -272,8 +276,15 @@ const DocData = struct {
272 NoReturn: struct { name: []const u8 },276 NoReturn: struct { name: []const u8 },
273 Int: struct { name: []const u8 },277 Int: struct { name: []const u8 },
274 Float: struct { name: []const u8 },278 Float: struct { name: []const u8 },
275 Pointer: struct { name: []const u8 },279 Pointer: struct {
276 Array: struct { name: []const u8 },280 name: []const u8,
281 child: TypeRef,
282 },
283 Array: struct {
284 name: []const u8,
285 len: usize,
286 child: TypeRef,
287 },
277 Struct: struct {288 Struct: struct {
278 name: []const u8,289 name: []const u8,
279 src: ?usize = null, // index into astNodes290 src: ?usize = null, // index into astNodes
...@@ -286,7 +297,10 @@ const DocData = struct {...@@ -286,7 +297,10 @@ const DocData = struct {
286 ComptimeInt: struct { name: []const u8 },297 ComptimeInt: struct { name: []const u8 },
287 Undefined: struct { name: []const u8 },298 Undefined: struct { name: []const u8 },
288 Null: struct { name: []const u8 },299 Null: struct { name: []const u8 },
289 Optional: struct { name: []const u8 },300 Optional: struct {
301 name: []const u8,
302 child: TypeRef,
303 },
290 ErrorUnion: struct { name: []const u8 },304 ErrorUnion: struct { name: []const u8 },
291 ErrorSet: struct { name: []const u8 },305 ErrorSet: struct { name: []const u8 },
292 Enum: struct {306 Enum: struct {
...@@ -335,6 +349,7 @@ const DocData = struct {...@@ -335,6 +349,7 @@ const DocData = struct {
335 .ComptimeInt => |v| try printTypeBody(v, options, w),349 .ComptimeInt => |v| try printTypeBody(v, options, w),
336 .ComptimeFloat => |v| try printTypeBody(v, options, w),350 .ComptimeFloat => |v| try printTypeBody(v, options, w),
337 .Null => |v| try printTypeBody(v, options, w),351 .Null => |v| try printTypeBody(v, options, w),
352 .Optional => |v| try printTypeBody(v, options, w),
338353
339 .Struct => |v| try printTypeBody(v, options, w),354 .Struct => |v| try printTypeBody(v, options, w),
340 .Fn => |v| try printTypeBody(v, options, w),355 .Fn => |v| try printTypeBody(v, options, w),
...@@ -376,13 +391,13 @@ const DocData = struct {...@@ -376,13 +391,13 @@ const DocData = struct {
376391
377 const TypeRef = union(enum) {392 const TypeRef = union(enum) {
378 unspecified,393 unspecified,
379 declRef: usize, // index in `decls`394 declPath: []usize, // indexes in `decls`
380 type: usize, // index in `types`395 type: usize, // index in `types`
381 comptimeExpr: usize, // index in `comptimeExprs`396 comptimeExpr: usize, // index in `comptimeExprs`
382397
383 pub fn fromWalkResult(wr: WalkResult) TypeRef {398 pub fn fromWalkResult(wr: WalkResult) TypeRef {
384 return switch (wr) {399 return switch (wr) {
385 .declRef => |v| .{ .declRef = v },400 .declPath => |v| .{ .declPath = v },
386 .type => |v| .{ .type = v },401 .type => |v| .{ .type = v },
387 else => @panic("Found non-type WalkResult"),402 else => @panic("Found non-type WalkResult"),
388 };403 };
...@@ -400,11 +415,18 @@ const DocData = struct {...@@ -400,11 +415,18 @@ const DocData = struct {
400 , .{});415 , .{});
401 },416 },
402417
403 .declRef, .type, .comptimeExpr => |v| {418 .type, .comptimeExpr => |v| {
404 try w.print(419 try w.print(
405 \\{{ "{s}":{} }}420 \\{{ "{s}":{} }}
406 , .{ @tagName(self), v });421 , .{ @tagName(self), v });
407 },422 },
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 },
408 }430 }
409 }431 }
410 };432 };
...@@ -415,16 +437,10 @@ const DocData = struct {...@@ -415,16 +437,10 @@ const DocData = struct {
415 @"unreachable",437 @"unreachable",
416 @"null": TypeRef,438 @"null": TypeRef,
417 @"undefined": TypeRef,439 @"undefined": TypeRef,
418 @"struct": struct {440 @"struct": Struct,
419 typeRef: TypeRef,
420 fieldVals: []struct {
421 name: []const u8,
422 val: WalkResult,
423 },
424 },
425 bool: bool,441 bool: bool,
426 type: usize, // index in `types`442 type: usize, // index in `types`
427 declRef: usize, // index in `decls`443 declPath: []usize, // indices in `decls`
428 int: struct {444 int: struct {
429 typeRef: TypeRef,445 typeRef: TypeRef,
430 value: usize, // direct value446 value: usize, // direct value
...@@ -435,6 +451,14 @@ const DocData = struct {...@@ -435,6 +451,14 @@ const DocData = struct {
435 value: f64, // direct value451 value: f64, // direct value
436 negated: bool = false,452 negated: bool = false,
437 },453 },
454
455 const Struct = struct {
456 typeRef: TypeRef,
457 fieldVals: []struct {
458 name: []const u8,
459 val: WalkResult,
460 },
461 };
438 pub fn jsonStringify(462 pub fn jsonStringify(
439 self: WalkResult,463 self: WalkResult,
440 options: std.json.StringifyOptions,464 options: std.json.StringifyOptions,
...@@ -446,7 +470,7 @@ const DocData = struct {...@@ -446,7 +470,7 @@ const DocData = struct {
446 \\{{ "{s}":{{}} }}470 \\{{ "{s}":{{}} }}
447 , .{@tagName(self)});471 , .{@tagName(self)});
448 },472 },
449 .type, .declRef, .comptimeExpr => |v| {473 .type, .comptimeExpr => |v| {
450 try w.print(474 try w.print(
451 \\{{ "{s}":{} }}475 \\{{ "{s}":{} }}
452 , .{ @tagName(self), v });476 , .{ @tagName(self), v });
...@@ -478,12 +502,18 @@ const DocData = struct {...@@ -478,12 +502,18 @@ const DocData = struct {
478 },502 },
479 .@"undefined" => |v| try std.json.stringify(v, options, w),503 .@"undefined" => |v| try std.json.stringify(v, options, w),
480 .@"null" => |v| try std.json.stringify(v, options, w),504 .@"null" => |v| try std.json.stringify(v, options, w),
481 .@"struct" => |v| try std.json.stringify(v, options, w),505 .@"struct" => |v| try std.json.stringify(
482 // .decl_ref => |v| {506 struct { @"struct": Struct }{ .@"struct" = v },
483 // try w.print(507 options,
484 // \\{{ "{s}":"{s}" }}508 w,
485 // , .{ @tagName(self), v });509 ),
486 // },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 },
487 }517 }
488 }518 }
489 };519 };
...@@ -571,13 +601,15 @@ fn walkInstruction(...@@ -571,13 +601,15 @@ fn walkInstruction(
571 "TODO: handle {s} in `walkInstruction.as_node`\n",601 "TODO: handle {s} in `walkInstruction.as_node`\n",
572 .{@tagName(operand)},602 .{@tagName(operand)},
573 ),603 ),
574 .declRef => {},604 .declPath, .type => {},
575 // we don't do anything because up until now,605 // we don't do anything because up until now,
576 // I've only seen this used as such:606 // I've only seen this used as such:
577 // @as(@as(type, Baz), .{})607 // @as(@as(type, Baz), .{})
578 // and we don't want to toss away the608 // and we don't want to toss away the
579 // decl_val information (eg by replacing it with609 // decl_val information (eg by replacing it with
580 // a WalkResult.type).610 // a WalkResult.type).
611 // TODO: Actually, this is a good moment to check if
612 // the result is indeed a type!!
581 .comptimeExpr => {613 .comptimeExpr => {
582 self.comptimeExprs.items[operand.comptimeExpr].typeRef = dest_type_ref;614 self.comptimeExprs.items[operand.comptimeExpr].typeRef = dest_type_ref;
583 },615 },
...@@ -588,11 +620,39 @@ fn walkInstruction(...@@ -588,11 +620,39 @@ fn walkInstruction(
588620
589 return operand;621 return operand;
590 },622 },
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 },
591 .decl_val => {637 .decl_val => {
592 const str_tok = data[inst_index].str_tok;638 const str_tok = data[inst_index].str_tok;
593 const decls_slot_index = parent_scope.resolveDeclName(str_tok.start);639 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 };
595 },643 },
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 //},
596 .int_type => {656 .int_type => {
597 const int_type = data[inst_index].int_type;657 const int_type = data[inst_index].int_type;
598 const sign = if (int_type.signedness == .unsigned) "u" else "i";658 const sign = if (int_type.signedness == .unsigned) "u" else "i";
...@@ -945,17 +1005,13 @@ fn walkInstruction(...@@ -945,17 +1005,13 @@ fn walkInstruction(
945 // Done to make sure that all decl refs can be resolved correctly,1005 // Done to make sure that all decl refs can be resolved correctly,
946 // even if we haven't fully analyzed the decl yet.1006 // even if we haven't fully analyzed the decl yet.
947 {1007 {
948 var actual_decls_len: usize = 0;
949 var it = file.zir.declIterator(@intCast(u32, inst_index));1008 var it = file.zir.declIterator(@intCast(u32, inst_index));
1009 try self.decls.resize(self.arena, decls_first_index + it.decls_len);
950 var decls_slot_index = decls_first_index;1010 var decls_slot_index = decls_first_index;
951 while (it.next()) |d| : (decls_slot_index += 1) {1011 while (it.next()) |d| : (decls_slot_index += 1) {
952 const decl_name_index = file.zir.extra[d.sub_index + 5];1012 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;
955 try scope.insertDeclRef(self.arena, decl_name_index, decls_slot_index);1013 try scope.insertDeclRef(self.arena, decl_name_index, decls_slot_index);
956 }1014 }
957 // we don't count decltests in our decls
958 try self.decls.resize(self.arena, decls_first_index + actual_decls_len);
959 }1015 }
9601016
961 extra_index = try self.walkDecls(1017 extra_index = try self.walkDecls(
...@@ -1144,6 +1200,12 @@ fn walkDecls(...@@ -1144,6 +1200,12 @@ fn walkDecls(
1144 break :idx idx;1200 break :idx idx;
1145 };1201 };
1146 self.decls.items[decl_being_tested].decltest = ast_node_index;1202 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 };
1147 continue;1209 continue;
1148 } else {1210 } else {
1149 const raw_decl_name = file.zir.nullTerminatedString(decl_name_index);1211 const raw_decl_name = file.zir.nullTerminatedString(decl_name_index);
...@@ -1450,7 +1512,7 @@ fn walkResultToTypeRef(wr: DocData.WalkResult) DocData.TypeRef {...@@ -1450,7 +1512,7 @@ fn walkResultToTypeRef(wr: DocData.WalkResult) DocData.TypeRef {
1450 .{@tagName(wr)},1512 .{@tagName(wr)},
1451 ),1513 ),
14521514
1453 .declRef => |v| .{ .declRef = v },1515 .declPath => |v| .{ .declPath = v },
1454 .type => |v| .{ .type = v },1516 .type => |v| .{ .type = v },
1455 };1517 };
1456}1518}