╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ IncrementalDebugServer.zig ───────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
305 .failed_unit => |other_unit| { 306 var buf: [32]u8 = undefined; 307 try w.print("analysis result: transitive failure (failed unit: {s})\n", .{printAnalUnit(other_unit, &buf)}); 308 }, 309 .func_nav_val_changed => |func_index| try w.print("analysis result: transitive failure (owner nav of func '{d}' changed value)\n", .{@backingInt(func_index)}), 310 } 311 } else { 312 try w.writeAll("analysis result: success\n"); 313 } 314 if (unit.unwrap() == .func) { 315 const nav_id = zcu.intern_pool.indexToKey(unit.unwrap().func).func.owner_nav; 316 try w.print("owner nav: {d}\n", .{@backingInt(nav_id)}); 317 } 318 } else if (std.mem.eql(u8, cmd_str, "unit_dependencies")) { 319 const unit = parseAnalUnit(arg_str) orelse return w.writeAll("malformed anal unit"); 320 const unit_info = zcu.incremental_debug_state.units.get(unit) orelse return w.writeAll("unknown anal unit"); 321 for (unit_info.deps.items, 0..) |dependee, i| { 322 try w.print("[{d}] ", .{i}); 323 switch (dependee) { 324 .src_hash, .namespace, .namespace_name, .source_file, .embed_file => try w.print("{f}", .{zcu.fmtDependee(dependee)}), 325 .nav_val, .nav_ty => |nav| try w.print("{t} {d}", .{ dependee, @backingInt(nav) }), 326 .type_layout, .struct_defaults, .func_ies => |ip_index| try w.print("{t} {d}", .{ dependee, @backingInt(ip_index) }), 327 .memoized_state => |stage| try w.print("memoized_state {s}", .{@tagName(stage)}), 328 } 329 try w.writeByte('\n'); 330 } 331 } else if (std.mem.eql(u8, cmd_str, "unit_trace")) { 332 const unit = parseAnalUnit(arg_str) orelse return w.writeAll("malformed anal unit"); 333 if (!zcu.incremental_debug_state.units.contains(unit)) return w.writeAll("unknown anal unit"); 334 const refs = try zcu.resolveReferences(); 335 if (!refs.contains(unit)) return w.writeAll("not referenced"); 336 var opt_cur: ?AnalUnit = unit; 337 while (opt_cur) |cur| { 338 var buf: [32]u8 = undefined; 339 try w.print("* {s}\n", .{printAnalUnit(cur, &buf)}); 340 opt_cur = if (refs.get(cur).?) |ref| ref.referencer else null; 341 } 342 } else if (std.mem.eql(u8, cmd_str, "type_info")) { 343 const ip_index: InternPool.Index = @fromBackingInt(@intCast(parseIndex(arg_str) orelse return w.writeAll("malformed ip index"))); 344 const create_gen = zcu.incremental_debug_state.types.get(ip_index) orelse return w.writeAll("unknown type"); 345 try w.print( 346 \\name: '{f}' 347 \\created on generation: {d} 348 \\ 349 , .{ 350 Type.fromInterned(ip_index).containerTypeName(ip).fqn.fmt(ip), 351 create_gen, 352 }); 353 } else if (std.mem.eql(u8, cmd_str, "type_namespace")) { 354 const ip_index: InternPool.Index = @fromBackingInt(@intCast(parseIndex(arg_str) orelse return w.writeAll("malformed ip index"))); 355 if (!zcu.incremental_debug_state.types.contains(ip_index)) return w.writeAll("unknown type"); 356 const ns = zcu.namespacePtr(Type.fromInterned(ip_index).getNamespaceIndex(zcu)); 357 try w.print("{d} pub decls:\n", .{ns.pub_decls.count()}); 358 for (ns.pub_decls.keys()) |nav| { 359 try w.print("* nav {d}\n", .{@backingInt(nav)}); 360 } 361 try w.print("{d} non-pub decls:\n", .{ns.priv_decls.count()}); 362 for (ns.priv_decls.keys()) |nav| { 363 try w.print("* nav {d}\n", .{@backingInt(nav)}); 364 } 365 try w.print("{d} comptime decls:\n", .{ns.comptime_decls.items.len}); 366 for (ns.comptime_decls.items) |id| { 367 try w.print("* comptime {d}\n", .{@backingInt(id)}); 368 } 369 try w.print("{d} tests:\n", .{ns.test_decls.items.len}); 370 for (ns.test_decls.items) |nav| { 371 try w.print("* nav {d}\n", .{@backingInt(nav)}); 372 } 373 } else { 374 try w.writeAll("command not found; run 'help' for a command list"); 375 } 376 } 377 378 fn parseIndex(str: []const u8) ?u32 { 379 return std.fmt.parseInt(u32, str, 10) catch null; 380 } 381 fn parseAnalUnit(str: []const u8) ?AnalUnit { 382 const split_idx = std.mem.findScalar(u8, str, ' ') orelse return null; 383 const kind = str[0..split_idx]; 384 const idx_str = str[split_idx + 1 ..]; 385 if (std.mem.eql(u8, kind, "comptime")) { 386 return .wrap(.{ .@"comptime" = @fromBackingInt(@intCast(parseIndex(idx_str) orelse return null)) }); 387 } else if (std.mem.eql(u8, kind, "nav_val")) { 388 return .wrap(.{ .nav_val = @fromBackingInt(@intCast(parseIndex(idx_str) orelse return null)) }); 389 } else if (std.mem.eql(u8, kind, "nav_ty")) { 390 return .wrap(.{ .nav_ty = @fromBackingInt(@intCast(parseIndex(idx_str) orelse return null)) }); 391 } else if (std.mem.eql(u8, kind, "type_layout")) { 392 return .wrap(.{ .type_layout = @fromBackingInt(@intCast(parseIndex(idx_str) orelse return null)) }); 393 } else if (std.mem.eql(u8, kind, "struct_defaults")) { 394 return .wrap(.{ .struct_defaults = @fromBackingInt(@intCast(parseIndex(idx_str) orelse return null)) }); 395 } else if (std.mem.eql(u8, kind, "func")) { 396 return .wrap(.{ .func = @fromBackingInt(@intCast(parseIndex(idx_str) orelse return null)) }); 397 } else if (std.mem.eql(u8, kind, "memoized_state")) { 398 return .wrap(.{ .memoized_state = std.meta.stringToEnum( 399 InternPool.MemoizedStateStage, 400 idx_str, 401 ) orelse return null }); 402 } else { 403 return null; 404 } 405 } 406 fn printAnalUnit(unit: AnalUnit, buf: *[32]u8) []const u8 { 407 const idx: u32 = switch (unit.unwrap()) { 408 .memoized_state => |stage| return std.mem.print(buf, "memoized_state {s}", .{@tagName(stage)}) catch unreachable, 409 inline else => |i| @backingInt(i), 410 }; 411 return std.mem.print(buf, "{s} {d}", .{ @tagName(unit.unwrap()), idx }) catch unreachable; 412 } 413 414 fn printType(ty: Type, zcu: *const Zcu, w: *Io.Writer) Io.Writer.Error!void { 415 const ip = &zcu.intern_pool; 416 switch (ip.indexToKey(ty.toIntern())) { 417 .int_type => |int| try w.print("{c}{d}", .{ 418 @as(u8, if (int.signedness == .unsigned) 'u' else 'i'), 419 int.bits, 420 }), 421 .tuple_type => try w.writeAll("(tuple)"), 422 .error_set_type => try w.writeAll("(error set)"), 423 .inferred_error_set_type => try w.writeAll("(inferred error set)"), 424 .func_type => try w.writeAll("(function)"), 425 .anyframe_type => try w.writeAll("(anyframe)"), 426 .vector_type => { 427 try w.print("@Vector({d}, ", .{ty.vectorLen(zcu)}); 428 try printType(ty.childType(zcu), zcu, w); 429 try w.writeByte(')'); 430 }, 431 .array_type => { 432 try w.print("[{d}]", .{ty.arrayLen(zcu)}); 433 try printType(ty.childType(zcu), zcu, w); 434 }, 435 .opt_type => { 436 try w.writeByte('?'); 437 try printType(ty.optionalChild(zcu), zcu, w); 438 }, 439 .error_union_type => { 440 try printType(ty.errorUnionSet(zcu), zcu, w); 441 try w.writeByte('!'); 442 try printType(ty.errorUnionPayload(zcu), zcu, w); 443 }, 444 .ptr_type => { 445 try w.writeAll("*(attrs) "); 446 try printType(ty.childType(zcu), zcu, w); 447 }, 448 .simple_type => |simple| try w.writeAll(@tagName(simple)), 449 450 .struct_type, 451 .union_type, 452 .enum_type, 453 .opaque_type, 454 => try w.print("{f}[{d}]", .{ ty.containerTypeName(ip).fqn.fmt(ip), @backingInt(ty.toIntern()) }), 455 456 else => unreachable, 457 } 458 } 459 460 const std = @import("std"); 461 const Io = std.Io; 462 const Allocator = std.mem.Allocator; 463 const log = std.log.scoped(.incremental_debug_server); 464 465 const Compilation = @import("Compilation.zig"); 466 const Zcu = @import("Zcu.zig"); 467 const InternPool = @import("InternPool.zig"); 468 const Type = @import("Type.zig"); 469 const AnalUnit = InternPool.AnalUnit; 470 471 const IncrementalDebugServer = @This(); 472