authorgravatar for der.teufel.mail@gmail.comKrzysztof Wolicki <der.teufel.mail@gmail.com> 2022-09-04 13:26:28+02:00
committergravatar for kappaloris@gmail.comLoris Cro <kappaloris@gmail.com> 2022-09-04 22:47:58+02:00
logb8001335c48096113520ab07592f96086b799cdc
tree5454c07c5c43b07f4c5494fd4b6608806306f191
parentdbd60e3d296f1c195c4b4d56ca55ecb30444d407

autodoc: Opaque now handled like other container types


2 files changed, 105 insertions(+), 19 deletions(-)

lib/docs/main.js+3-3
...@@ -243,7 +243,8 @@ var zigAnalysis;...@@ -243,7 +243,8 @@ var zigAnalysis;
243 return (243 return (
244 typeKind === typeKinds.Struct ||244 typeKind === typeKinds.Struct ||
245 typeKind === typeKinds.Union ||245 typeKind === typeKinds.Union ||
246 typeKind === typeKinds.Enum246 typeKind === typeKinds.Enum ||
247 typeKind === typeKinds.Opaque
247 );248 );
248 }249 }
249250
...@@ -1624,8 +1625,7 @@ var zigAnalysis;...@@ -1624,8 +1625,7 @@ var zigAnalysis;
1624 }1625 }
1625 case typeKinds.Opaque: {1626 case typeKinds.Opaque: {
1626 let opaqueObj = typeObj;1627 let opaqueObj = typeObj;
16271628 return opaqueObj;
1628 return opaqueObj.name;
1629 }1629 }
1630 case typeKinds.ComptimeExpr: {1630 case typeKinds.ComptimeExpr: {
1631 return "anyopaque";1631 return "anyopaque";
src/Autodoc.zig+102-16
...@@ -577,7 +577,13 @@ const DocData = struct {...@@ -577,7 +577,13 @@ const DocData = struct {
577 is_extern: bool = false,577 is_extern: bool = false,
578 },578 },
579 BoundFn: struct { name: []const u8 },579 BoundFn: struct { name: []const u8 },
580 Opaque: struct { name: []const u8 },580 Opaque: struct {
581 name: []const u8,
582 src: usize, // index into astNodes
583 privDecls: []usize = &.{}, // index into decls
584 pubDecls: []usize = &.{}, // index into decls
585 ast: usize,
586 },
581 Frame: struct { name: []const u8 },587 Frame: struct { name: []const u8 },
582 AnyFrame: struct { name: []const u8 },588 AnyFrame: struct { name: []const u8 },
583 Vector: struct { name: []const u8 },589 Vector: struct { name: []const u8 },
...@@ -2433,6 +2439,14 @@ fn walkInstruction(...@@ -2433,6 +2439,14 @@ fn walkInstruction(
2433 return result;2439 return result;
2434 },2440 },
2435 .opaque_decl => {2441 .opaque_decl => {
2442 const type_slot_index = self.types.items.len;
2443 try self.types.append(self.arena, .{ .Unanalyzed = .{} });
2444
2445 var scope: Scope = .{
2446 .parent = parent_scope,
2447 .enclosing_type = type_slot_index,
2448 };
2449
2436 const small = @bitCast(Zir.Inst.OpaqueDecl.Small, extended.small);2450 const small = @bitCast(Zir.Inst.OpaqueDecl.Small, extended.small);
2437 var extra_index: usize = extended.operand;2451 var extra_index: usize = extended.operand;
24382452
...@@ -2453,22 +2467,63 @@ fn walkInstruction(...@@ -2453,22 +2467,63 @@ fn walkInstruction(
2453 extra_index += 1;2467 extra_index += 1;
2454 break :blk decls_len;2468 break :blk decls_len;
2455 } else 0;2469 } else 0;
2456 _ = decls_len;2470
24572471 var decl_indexes: std.ArrayListUnmanaged(usize) = .{};
2458 const decls_bits = file.zir.extra[extra_index];2472 var priv_decl_indexes: std.ArrayListUnmanaged(usize) = .{};
2459 _ = decls_bits;2473
24602474 const decls_first_index = self.decls.items.len;
2461 // const sep = "=" ** 200;2475 // Decl name lookahead for reserving slots in `scope` (and `decls`).
2462 // log.debug("{s}", .{sep});2476 // Done to make sure that all decl refs can be resolved correctly,
2463 // log.debug("small = {any}", .{small});2477 // even if we haven't fully analyzed the decl yet.
2464 // log.debug("src_node = {}", .{src_node});2478 {
2465 // log.debug("decls_len = {}", .{decls_len});2479 var it = file.zir.declIterator(@intCast(u32, inst_index));
2466 // log.debug("decls_bit = {}", .{decls_bits});2480 try self.decls.resize(self.arena, decls_first_index + it.decls_len);
2467 // log.debug("{s}", .{sep});2481 for (self.decls.items[decls_first_index..]) |*slot| {
2468 const type_slot_index = self.types.items.len - 1;2482 slot._analyzed = false;
2469 try self.types.append(self.arena, .{ .Opaque = .{ .name = "TODO" } });2483 }
2484 var decls_slot_index = decls_first_index;
2485 while (it.next()) |d| : (decls_slot_index += 1) {
2486 const decl_name_index = file.zir.extra[d.sub_index + 5];
2487 try scope.insertDeclRef(self.arena, decl_name_index, decls_slot_index);
2488 }
2489 }
2490
2491 extra_index = try self.walkDecls(
2492 file,
2493 &scope,
2494 src_info,
2495 decls_first_index,
2496 decls_len,
2497 &decl_indexes,
2498 &priv_decl_indexes,
2499 extra_index,
2500 );
2501
2502 self.types.items[type_slot_index] = .{
2503 .Opaque = .{
2504 .name = "todo_name",
2505 .src = self_ast_node_index,
2506 .privDecls = priv_decl_indexes.items,
2507 .pubDecls = decl_indexes.items,
2508 .ast = self_ast_node_index,
2509 },
2510 };
2511 if (self.ref_paths_pending_on_types.get(type_slot_index)) |paths| {
2512 for (paths.items) |resume_info| {
2513 try self.tryResolveRefPath(
2514 resume_info.file,
2515 inst_index,
2516 resume_info.ref_path,
2517 );
2518 }
2519
2520 _ = self.ref_paths_pending_on_types.remove(type_slot_index);
2521 // TODO: we should deallocate the arraylist that holds all the
2522 // decl paths. not doing it now since it's arena-allocated
2523 // anyway, but maybe we should put it elsewhere.
2524 }
2470 return DocData.WalkResult{2525 return DocData.WalkResult{
2471 .typeRef = .{ .type = @enumToInt(Ref.anyopaque_type) },2526 .typeRef = .{ .type = @enumToInt(Ref.type_type) },
2472 .expr = .{ .type = type_slot_index },2527 .expr = .{ .type = type_slot_index },
2473 };2528 };
2474 },2529 },
...@@ -3428,6 +3483,37 @@ fn tryResolveRefPath(...@@ -3428,6 +3483,37 @@ fn tryResolveRefPath(
3428 path[i + 1] = (try self.cteTodo(child_string)).expr;3483 path[i + 1] = (try self.cteTodo(child_string)).expr;
3429 continue :outer;3484 continue :outer;
3430 },3485 },
3486 .Opaque => |t_opaque| {
3487 for (t_opaque.pubDecls) |d| {
3488 // TODO: this could be improved a lot
3489 // by having our own string table!
3490 const decl = self.decls.items[d];
3491 if (std.mem.eql(u8, decl.name, child_string)) {
3492 path[i + 1] = .{ .declRef = d };
3493 continue :outer;
3494 }
3495 }
3496 for (t_opaque.privDecls) |d| {
3497 // TODO: this could be improved a lot
3498 // by having our own string table!
3499 const decl = self.decls.items[d];
3500 if (std.mem.eql(u8, decl.name, child_string)) {
3501 path[i + 1] = .{ .declRef = d };
3502 continue :outer;
3503 }
3504 }
3505
3506 // if we got here, our search failed
3507 printWithContext(
3508 file,
3509 inst_index,
3510 "failed to match `{s}` in opaque",
3511 .{child_string},
3512 );
3513
3514 path[i + 1] = (try self.cteTodo("match failure")).expr;
3515 continue :outer;
3516 },
3431 },3517 },
3432 }3518 }
3433 }3519 }