| ... | ... | @@ -65,7 +65,11 @@ pub fn generateZirData(self: *Autodoc) !void { |
| 65 | 65 | // @tagName(t), |
| 66 | 66 | //}); |
| 67 | 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 | 75 | .u1_type, |
| ... | ... | @@ -248,7 +252,7 @@ const DocData = struct { |
| 248 | 252 | |
| 249 | 253 | const Decl = struct { |
| 250 | 254 | name: []const u8, |
| 251 | | kind: []const u8, // TODO: where do we find this info? |
| 255 | kind: []const u8, |
| 252 | 256 | src: usize, // index into astNodes |
| 253 | 257 | // typeRef: TypeRef, |
| 254 | 258 | value: WalkResult, |
| ... | ... | @@ -272,8 +276,15 @@ const DocData = struct { |
| 272 | 276 | NoReturn: struct { name: []const u8 }, |
| 273 | 277 | Int: struct { name: []const u8 }, |
| 274 | 278 | 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 | }, |
| 277 | 288 | Struct: struct { |
| 278 | 289 | name: []const u8, |
| 279 | 290 | src: ?usize = null, // index into astNodes |
| ... | ... | @@ -286,7 +297,10 @@ const DocData = struct { |
| 286 | 297 | ComptimeInt: struct { name: []const u8 }, |
| 287 | 298 | Undefined: struct { name: []const u8 }, |
| 288 | 299 | Null: struct { name: []const u8 }, |
| 289 | | Optional: struct { name: []const u8 }, |
| 300 | Optional: struct { |
| 301 | name: []const u8, |
| 302 | child: TypeRef, |
| 303 | }, |
| 290 | 304 | ErrorUnion: struct { name: []const u8 }, |
| 291 | 305 | ErrorSet: struct { name: []const u8 }, |
| 292 | 306 | Enum: struct { |
| ... | ... | @@ -335,6 +349,7 @@ const DocData = struct { |
| 335 | 349 | .ComptimeInt => |v| try printTypeBody(v, options, w), |
| 336 | 350 | .ComptimeFloat => |v| try printTypeBody(v, options, w), |
| 337 | 351 | .Null => |v| try printTypeBody(v, options, w), |
| 352 | .Optional => |v| try printTypeBody(v, options, w), |
| 338 | 353 | |
| 339 | 354 | .Struct => |v| try printTypeBody(v, options, w), |
| 340 | 355 | .Fn => |v| try printTypeBody(v, options, w), |
| ... | ... | @@ -376,13 +391,13 @@ const DocData = struct { |
| 376 | 391 | |
| 377 | 392 | const TypeRef = union(enum) { |
| 378 | 393 | unspecified, |
| 379 | | declRef: usize, // index in `decls` |
| 394 | declPath: []usize, // indexes in `decls` |
| 380 | 395 | type: usize, // index in `types` |
| 381 | 396 | comptimeExpr: usize, // index in `comptimeExprs` |
| 382 | 397 | |
| 383 | 398 | pub fn fromWalkResult(wr: WalkResult) TypeRef { |
| 384 | 399 | return switch (wr) { |
| 385 | | .declRef => |v| .{ .declRef = v }, |
| 400 | .declPath => |v| .{ .declPath = v }, |
| 386 | 401 | .type => |v| .{ .type = v }, |
| 387 | 402 | else => @panic("Found non-type WalkResult"), |
| 388 | 403 | }; |
| ... | ... | @@ -400,11 +415,18 @@ const DocData = struct { |
| 400 | 415 | , .{}); |
| 401 | 416 | }, |
| 402 | 417 | |
| 403 | | .declRef, .type, .comptimeExpr => |v| { |
| 418 | .type, .comptimeExpr => |v| { |
| 404 | 419 | try w.print( |
| 405 | 420 | \\{{ "{s}":{} }} |
| 406 | 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 | 437 | @"unreachable", |
| 416 | 438 | @"null": TypeRef, |
| 417 | 439 | @"undefined": TypeRef, |
| 418 | | @"struct": struct { |
| 419 | | typeRef: TypeRef, |
| 420 | | fieldVals: []struct { |
| 421 | | name: []const u8, |
| 422 | | val: WalkResult, |
| 423 | | }, |
| 424 | | }, |
| 440 | @"struct": Struct, |
| 425 | 441 | bool: bool, |
| 426 | 442 | type: usize, // index in `types` |
| 427 | | declRef: usize, // index in `decls` |
| 443 | declPath: []usize, // indices in `decls` |
| 428 | 444 | int: struct { |
| 429 | 445 | typeRef: TypeRef, |
| 430 | 446 | value: usize, // direct value |
| ... | ... | @@ -435,6 +451,14 @@ const DocData = struct { |
| 435 | 451 | value: f64, // direct value |
| 436 | 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 | 462 | pub fn jsonStringify( |
| 439 | 463 | self: WalkResult, |
| 440 | 464 | options: std.json.StringifyOptions, |
| ... | ... | @@ -446,7 +470,7 @@ const DocData = struct { |
| 446 | 470 | \\{{ "{s}":{{}} }} |
| 447 | 471 | , .{@tagName(self)}); |
| 448 | 472 | }, |
| 449 | | .type, .declRef, .comptimeExpr => |v| { |
| 473 | .type, .comptimeExpr => |v| { |
| 450 | 474 | try w.print( |
| 451 | 475 | \\{{ "{s}":{} }} |
| 452 | 476 | , .{ @tagName(self), v }); |
| ... | ... | @@ -478,12 +502,18 @@ const DocData = struct { |
| 478 | 502 | }, |
| 479 | 503 | .@"undefined" => |v| try std.json.stringify(v, options, w), |
| 480 | 504 | .@"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 | }, |
| 487 | 517 | } |
| 488 | 518 | } |
| 489 | 519 | }; |
| ... | ... | @@ -571,13 +601,15 @@ fn walkInstruction( |
| 571 | 601 | "TODO: handle {s} in `walkInstruction.as_node`\n", |
| 572 | 602 | .{@tagName(operand)}, |
| 573 | 603 | ), |
| 574 | | .declRef => {}, |
| 604 | .declPath, .type => {}, |
| 575 | 605 | // we don't do anything because up until now, |
| 576 | 606 | // I've only seen this used as such: |
| 577 | 607 | // @as(@as(type, Baz), .{}) |
| 578 | 608 | // and we don't want to toss away the |
| 579 | 609 | // decl_val information (eg by replacing it with |
| 580 | 610 | // a WalkResult.type). |
| 611 | // TODO: Actually, this is a good moment to check if |
| 612 | // the result is indeed a type!! |
| 581 | 613 | .comptimeExpr => { |
| 582 | 614 | self.comptimeExprs.items[operand.comptimeExpr].typeRef = dest_type_ref; |
| 583 | 615 | }, |
| ... | ... | @@ -588,11 +620,39 @@ fn walkInstruction( |
| 588 | 620 | |
| 589 | 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 | 637 | .decl_val => { |
| 592 | 638 | const str_tok = data[inst_index].str_tok; |
| 593 | 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 | 656 | .int_type => { |
| 597 | 657 | const int_type = data[inst_index].int_type; |
| 598 | 658 | const sign = if (int_type.signedness == .unsigned) "u" else "i"; |
| ... | ... | @@ -945,17 +1005,13 @@ fn walkInstruction( |
| 945 | 1005 | // Done to make sure that all decl refs can be resolved correctly, |
| 946 | 1006 | // even if we haven't fully analyzed the decl yet. |
| 947 | 1007 | { |
| 948 | | var actual_decls_len: usize = 0; |
| 949 | 1008 | var it = file.zir.declIterator(@intCast(u32, inst_index)); |
| 1009 | try self.decls.resize(self.arena, decls_first_index + it.decls_len); |
| 950 | 1010 | var decls_slot_index = decls_first_index; |
| 951 | 1011 | while (it.next()) |d| : (decls_slot_index += 1) { |
| 952 | 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 | 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 | } |
| 960 | 1016 | |
| 961 | 1017 | extra_index = try self.walkDecls( |
| ... | ... | @@ -1144,6 +1200,12 @@ fn walkDecls( |
| 1144 | 1200 | break :idx idx; |
| 1145 | 1201 | }; |
| 1146 | 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 | 1209 | continue; |
| 1148 | 1210 | } else { |
| 1149 | 1211 | const raw_decl_name = file.zir.nullTerminatedString(decl_name_index); |
| ... | ... | @@ -1450,7 +1512,7 @@ fn walkResultToTypeRef(wr: DocData.WalkResult) DocData.TypeRef { |
| 1450 | 1512 | .{@tagName(wr)}, |
| 1451 | 1513 | ), |
| 1452 | 1514 | |
| 1453 | | .declRef => |v| .{ .declRef = v }, |
| 1515 | .declPath => |v| .{ .declPath = v }, |
| 1454 | 1516 | .type => |v| .{ .type = v }, |
| 1455 | 1517 | }; |
| 1456 | 1518 | } |