| ... | @@ -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 { |
| 248 | | 252 | |
| 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 astNodes | 256 | 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 astNodes | 290 | 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), |
| 338 | | 353 | |
| 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 { |
| 376 | | 391 | |
| 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` |
| 382 | | 397 | |
| 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 | }, |
| 402 | | 417 | |
| 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 value | 446 | value: usize, // direct value |
| ... | @@ -435,6 +451,14 @@ const DocData = struct { | ... | @@ -435,6 +451,14 @@ const DocData = struct { |
| 435 | value: f64, // direct value | 451 | 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 the | 608 | // and we don't want to toss away the |
| 579 | // decl_val information (eg by replacing it with | 609 | // 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( |
| 588 | | 620 | |
| 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 | } |
| 960 | | 1016 | |
| 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 | ), |
| 1452 | | 1514 | |
| 1453 | .declRef => |v| .{ .declRef = v }, | 1515 | .declPath => |v| .{ .declPath = v }, |
| 1454 | .type => |v| .{ .type = v }, | 1516 | .type => |v| .{ .type = v }, |
| 1455 | }; | 1517 | }; |
| 1456 | } | 1518 | } |