Порівняти коміти

...
Автор SHA1 Повідомлення Дата
l0ng-ai 5e8869337c fix(debugger): show a JVM session's Memory tab from the start; pass lldb-dap's environment for cargo debugging
The Memory tab appeared only once the debugger had reported its capabilities, so the tab bar of a Java or Kotlin session grew a tab after the program started. It is now there from the start and says the view is available once the program has started.

A cargo run configuration with lldb-dap as its debug adapter passed CodeLLDB's sourceLanguages and the environment as an object; lldb-dap gets the environment as KEY=VALUE strings, as for other native programs.
2026-11-14 21:54:27 +08:00
6 змінених файлів з 42 додано та 3 видалено

No files matched your search

+9
Переглянути файл
@@ -98,6 +98,15 @@ describe("run config → launch config", () => {
});
});
it("cargo run under lldb-dap builds the same way and passes the environment as strings", () => {
const l = launchConfigFor(
rc({ kind: "cargo", command: "cargo", args: ["run"], env: { RUST_LOG: "debug" }, debugAdapter: "lldb-dap" }),
"/p",
)!;
expect(l.adapter).toBe("lldb-dap");
expect(extra(l)).toEqual({ cargo: { args: ["build"], filter: { kind: "bin" } }, env: ["RUST_LOG=debug"] });
});
it("cargo test builds test binaries without running", () => {
const l = launchConfigFor(
rc({ kind: "cargo", command: "cargo", args: ["test", "--workspace"], debugAdapter: "codelldb" }),
+10
Переглянути файл
@@ -157,6 +157,16 @@ describe("debug tool window", () => {
expect(screen.getByRole("tab", { name: "Memory" })).toBeTruthy();
});
it("shows the Memory tab of a JVM session while it starts, before its capabilities arrive", () => {
const starting = { ...session, adapter: "java-debug", status: "starting" as const, caps: null };
useDebug.setState({ sessions: { 1: starting }, active: 1 });
render(<DebugToolWindow />);
fireEvent.click(screen.getByRole("tab", { name: "Memory" }));
expect(screen.getByText("The Memory view is available once the program has started.")).toBeTruthy();
act(() => useDebug.setState({ sessions: { 1: { ...starting, adapter: "debugpy" } } }));
expect(screen.queryByRole("tab", { name: "Memory" })).toBeNull();
});
it("keeps the Memory tab selected when the session pauses", async () => {
const caps = { jvmMemory: true } as DebugSession["caps"];
useDebug.setState({ sessions: { 1: { ...session, caps, status: "running" } }, active: 1 });
+6 -1
Переглянути файл
@@ -67,7 +67,12 @@ function cargoLaunch(rc: RunConfig, cwd: string, adapter: string): LaunchConfig
return {
...base(rc, adapter, cwd),
args: programArgs,
extraJson: JSON.stringify({ cargo: filter ? { args, filter } : { args }, sourceLanguages: ["rust"] }),
extraJson: JSON.stringify({
cargo: filter ? { args, filter } : { args },
...(adapter === "codelldb" ? { sourceLanguages: ["rust"] } : {}),
// lldb-dap takes the environment as `KEY=VALUE` strings.
...(adapter === "lldb-dap" ? { env: Object.entries(rc.env).map(([k, v]) => `${k}=${v}`) } : {}),
}),
};
}
+15 -2
Переглянути файл
@@ -169,7 +169,9 @@ export function DebugToolWindow() {
? "variables"
: view.tab,
});
const hasMemory = !!active && sessionSupports("jvmMemory", active);
// A JVM session shows the Memory tab from the start, before the debugger has reported what it supports.
const memoryPending = !!active && !active.caps && JVM_ADAPTERS.has(rootOf(active).adapter);
const hasMemory = !!active && (sessionSupports("jvmMemory", active) || memoryPending);
const hasNetwork = !!active && sessionSupports("jsPage", active);
// The selected session may be one without the Memory or the Network tab.
const tab: Tab =
@@ -255,7 +257,15 @@ export function DebugToolWindow() {
{tab === "variables" ? (
<ThreadsAndVariables session={active} />
) : tab === "memory" ? (
<MemoryView key={active.id} session={active} />
memoryPending ? (
<div className={styles.emptyWrap}>
<EmptyState title="Memory">
<T>The Memory view is available once the program has started.</T>
</EmptyState>
</div>
) : (
<MemoryView key={active.id} session={active} />
)
) : tab === "network" ? (
<NetworkView key={active.id} session={active.id} />
) : (
@@ -266,6 +276,9 @@ export function DebugToolWindow() {
);
}
/** Debug adapters whose sessions have the Memory view (`ide-dap`'s `JVM_MEMORY_ADAPTERS`). */
const JVM_ADAPTERS = new Set(["java-debug", "kotlin-debug-adapter", "kotlin-lsp"]);
// --- threads & frames ----------------------------------------------------------
function ThreadsAndVariables({ session }: { session: DebugSession }) {
+1
Переглянути файл
@@ -181,6 +181,7 @@
"This debugger cannot list instances.": "This debugger cannot list instances.",
"The debugger cannot list instances: {detail}": "The debugger cannot list instances: {detail}",
"Pause the program to see instances.": "Pause the program to see instances.",
"The Memory view is available once the program has started.": "The Memory view is available once the program has started.",
"The object has been garbage collected.": "The object has been garbage collected.",
"The class is not loaded in the JVM.": "The class is not loaded in the JVM.",
"Could not tell which JVM this session debugs.": "Could not tell which JVM this session debugs.",
+1
Переглянути файл
@@ -158,6 +158,7 @@
"This debugger cannot list instances.": "此调试器无法列出实例。",
"The debugger cannot list instances: {detail}": "调试器无法列出实例:{detail}",
"Pause the program to see instances.": "暂停程序以查看实例。",
"The Memory view is available once the program has started.": "程序启动后即可使用内存视图。",
"The object has been garbage collected.": "该对象已被垃圾回收。",
"The class is not loaded in the JVM.": "JVM 中未加载该类。",
"Could not tell which JVM this session debugs.": "无法确定此会话调试的是哪个 JVM。",