Skip to content

Commit 653a2bb

Browse files
committed
Merge branch 'main' into wenyt/agent
2 parents 71c59e3 + 89ec914 commit 653a2bb

File tree

5 files changed

+154
-15
lines changed

5 files changed

+154
-15
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ All notable changes to the "vscode-java-debugger" extension will be documented i
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## 0.58.4 - 2025-12-09
8+
### Added
9+
- Add command to manage breakpoint exception types in command palette. [#1566](https://github.com/microsoft/vscode-java-debug/pull/1566). Thanks to [Roland Schaer](https://github.com/roele) for contribution.
10+
11+
### Fixed
12+
- Fix `lspFrame.source` NPE on stackTrace request. [java-debug#616](https://github.com/microsoft/java-debug/pull/616). Thanks to [Mathias Fußenegger](https://github.com/mfussenegger) for contribution.
13+
- Handle unavailable sources in compliance with DAP spec. [java-debug#609](https://github.com/microsoft/java-debug/pull/609), [java-debug#614](https://github.com/microsoft/java-debug/pull/614). Thanks to [Karl-Erik Enkelmann](https://github.com/playdohface) for contribution.
14+
15+
716
## 0.58.3 - 2025-11-03
817
### Added
918
- No config debug [[#1530](https://github.com/microsoft/vscode-java-debug/issues/1530)]

package-lock.json

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "vscode-java-debug",
33
"displayName": "Debugger for Java",
44
"description": "A lightweight Java debugger for Visual Studio Code",
5-
"version": "0.58.3",
5+
"version": "0.58.4",
66
"publisher": "vscjava",
77
"preview": false,
88
"aiKey": "67d4461e-ccba-418e-8082-1bd0acfe8516",
@@ -100,6 +100,10 @@
100100
"command": "java.debug.pauseOthers",
101101
"title": "Pause Others"
102102
},
103+
{
104+
"command": "java.debug.breakpoints.exceptionTypes",
105+
"title": "Manage Java Breakpoint Exception Types"
106+
},
103107
{
104108
"command": "java.debug.variables.showHex",
105109
"title": "Show as Hex"

src/breakpointCommands.ts

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import * as vscode from "vscode";
2+
3+
export function registerBreakpointCommands(context: vscode.ExtensionContext): void {
4+
context.subscriptions.push(vscode.commands.registerCommand('java.debug.breakpoints.exceptionTypes', exceptionTypes));
5+
}
6+
7+
async function exceptionTypes() {
8+
const config = vscode.workspace.getConfiguration('java.debug.settings.exceptionBreakpoint');
9+
let currentTypes = config.get<string[]>('exceptionTypes', []);
10+
const addExceptionTypeItem: vscode.QuickPickItem = {
11+
label: '$(add) Add Exception Types...',
12+
alwaysShow: true,
13+
};
14+
const removeExceptionTypeItem: any = (type: string): any => ({
15+
label: type,
16+
buttons: [{
17+
iconPath: new vscode.ThemeIcon('close'),
18+
tooltip: 'Remove this Exception Type'
19+
}]
20+
});
21+
22+
// Step 1: Show Breakpoint Exception Types
23+
const pickStep = async (state: any) => {
24+
return new Promise<any>((resolve) => {
25+
const items: vscode.QuickPickItem[] = [
26+
addExceptionTypeItem,
27+
...currentTypes.map(type => removeExceptionTypeItem(type))
28+
];
29+
const quickPick = vscode.window.createQuickPick();
30+
quickPick.items = items;
31+
quickPick.title = 'Breakpoint Exception Types';
32+
quickPick.canSelectMany = false;
33+
quickPick.matchOnDescription = false;
34+
quickPick.matchOnDetail = false;
35+
36+
quickPick.onDidAccept(() => {
37+
const selected = quickPick.selectedItems[0];
38+
if (selected.label.includes('Add Exception Types')) {
39+
quickPick.hide();
40+
// go to next step
41+
resolve(state);
42+
}
43+
});
44+
45+
quickPick.onDidTriggerItemButton(async (e) => {
46+
const typeToRemove = e.item.label;
47+
currentTypes = currentTypes.filter(type => type !== typeToRemove);
48+
await config.update('exceptionTypes', currentTypes, vscode.ConfigurationTarget.Global);
49+
quickPick.items = [
50+
addExceptionTypeItem,
51+
...currentTypes.map(type => removeExceptionTypeItem(type))
52+
];
53+
});
54+
quickPick.onDidHide(() => {
55+
quickPick.dispose();
56+
});
57+
quickPick.show();
58+
});
59+
};
60+
61+
// Step 2: Add Exception Type(s)
62+
const inputStep = async (state: any) => {
63+
return new Promise<any>((resolve, reject) => {
64+
const input = vscode.window.createInputBox();
65+
input.title = 'Add Breakpoint Exception Type(s)';
66+
input.placeholder = 'Enter exception type(s) (comma or space separated). "java.lang.NullPointerException" e.g.';
67+
input.prompt = 'Input exception types';
68+
input.buttons = [vscode.QuickInputButtons.Back];
69+
input.onDidAccept(async () => {
70+
const exceptionType = input.value;
71+
if (exceptionType) {
72+
const types = exceptionType.split(/[,\s]+/).map(type => type.trim()).filter(type => type.length > 0);
73+
let updated = false;
74+
for (const type of types) {
75+
if (!currentTypes.includes(type)) {
76+
currentTypes.push(type);
77+
updated = true;
78+
}
79+
}
80+
if (updated) {
81+
await config.update('exceptionTypes', currentTypes, vscode.ConfigurationTarget.Global);
82+
}
83+
}
84+
input.hide();
85+
// go back to pick step
86+
resolve(state);
87+
});
88+
input.onDidTriggerButton((btn) => {
89+
if (btn === vscode.QuickInputButtons.Back) {
90+
input.hide();
91+
reject({ stepBack: true });
92+
}
93+
});
94+
input.onDidHide(() => {
95+
input.dispose();
96+
});
97+
input.show();
98+
});
99+
};
100+
101+
while (true) {
102+
await multiStepInput([pickStep, inputStep], {});
103+
}
104+
}
105+
106+
async function multiStepInput<T>(steps: ((input: T) => Promise<T>)[], initial: T): Promise<T> {
107+
let state = initial;
108+
let currentStep = 0;
109+
while (currentStep < steps.length) {
110+
try {
111+
state = await steps[currentStep](state);
112+
currentStep++;
113+
} catch (err) {
114+
if (err?.stepBack) {
115+
if (currentStep > 0) {
116+
currentStep--;
117+
}
118+
} else {
119+
throw err;
120+
}
121+
}
122+
}
123+
return state;
124+
}

src/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { progressProvider } from "./progressImpl";
2727
import { JavaTerminalLinkProvder } from "./terminalLinkProvider";
2828
import { initializeThreadOperations } from "./threadOperations";
2929
import * as utility from "./utility";
30+
import { registerBreakpointCommands } from "./breakpointCommands";
3031
import { registerVariableMenuCommands } from "./variableMenu";
3132
import { promisify } from "util";
3233

@@ -49,6 +50,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<any> {
4950

5051
function initializeExtension(_operationId: string, context: vscode.ExtensionContext): any {
5152
registerDebugEventListener(context);
53+
registerBreakpointCommands(context);
5254
registerVariableMenuCommands(context);
5355
context.subscriptions.push(vscode.window.registerTerminalLinkProvider(new JavaTerminalLinkProvder()));
5456
context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider("java", new JavaDebugConfigurationProvider()));

0 commit comments

Comments
 (0)