Skip to content

Commit 0e623f8

Browse files
Adopt the new resolveVariable API (#826)
Signed-off-by: Jinbo Wang <[email protected]>
1 parent 14dd6db commit 0e623f8

File tree

6 files changed

+67
-302
lines changed

6 files changed

+67
-302
lines changed

package-lock.json

Lines changed: 3 additions & 3 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 & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"debugger"
1515
],
1616
"engines": {
17-
"vscode": "^1.38.0"
17+
"vscode": "^1.42.0"
1818
},
1919
"license": "SEE LICENSE IN LICENSE.txt",
2020
"repository": {
@@ -35,6 +35,7 @@
3535
"onDebugInitialConfigurations",
3636
"onDebugResolve:java",
3737
"onCommand:JavaDebug.SpecifyProgramArgs",
38+
"onCommand:JavaDebug.PickJavaProcess",
3839
"onCommand:java.debug.runJavaFile",
3940
"onCommand:java.debug.debugJavaFile"
4041
],
@@ -171,7 +172,8 @@
171172
"java"
172173
],
173174
"variables": {
174-
"SpecifyProgramArgs": "JavaDebug.SpecifyProgramArgs"
175+
"SpecifyProgramArgs": "JavaDebug.SpecifyProgramArgs",
176+
"PickJavaProcess": "JavaDebug.PickJavaProcess"
175177
},
176178
"configurationAttributes": {
177179
"launch": {
@@ -605,7 +607,7 @@
605607
"@types/lodash": "^4.14.137",
606608
"@types/mocha": "^5.2.7",
607609
"@types/node": "^8.10.51",
608-
"@types/vscode": "1.38.0",
610+
"@types/vscode": "1.42.0",
609611
"cross-env": "^5.2.0",
610612
"gulp": "^4.0.2",
611613
"gulp-tslint": "^8.1.4",

src/configurationProvider.ts

Lines changed: 44 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ import * as commands from "./commands";
1313
import * as lsPlugin from "./languageServerPlugin";
1414
import { addMoreHelpfulVMArgs, detectLaunchCommandStyle, validateRuntime } from "./launchCommand";
1515
import { logger, Type } from "./logger";
16-
import { resolveProcessId } from "./processPicker";
16+
import { resolveJavaProcess } from "./processPicker";
1717
import * as utility from "./utility";
18-
import { VariableResolver } from "./variableResolver";
1918

2019
const platformNameMappings = {
2120
win32: "windows",
@@ -27,9 +26,7 @@ const platformName = platformNameMappings[process.platform];
2726
export class JavaDebugConfigurationProvider implements vscode.DebugConfigurationProvider {
2827
private isUserSettingsDirty: boolean = true;
2928
private debugHistory: MostRecentlyUsedHistory = new MostRecentlyUsedHistory();
30-
private resolver: VariableResolver;
3129
constructor() {
32-
this.resolver = new VariableResolver();
3330
vscode.workspace.onDidChangeConfiguration((event) => {
3431
if (vscode.debug.activeDebugSession) {
3532
this.isUserSettingsDirty = false;
@@ -52,13 +49,27 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
5249
// Try to add all missing attributes to the debug configuration being launched.
5350
public resolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, token?: vscode.CancellationToken):
5451
vscode.ProviderResult<vscode.DebugConfiguration> {
52+
// If no debug configuration is provided, then generate one in memory.
53+
if (this.isEmptyConfig(config)) {
54+
config.type = "java";
55+
config.name = "Java Debug";
56+
config.request = "launch";
57+
}
58+
59+
return config;
60+
}
61+
62+
// Try to add all missing attributes to the debug configuration being launched.
63+
public resolveDebugConfigurationWithSubstitutedVariables(
64+
folder: vscode.WorkspaceFolder | undefined,
65+
config: vscode.DebugConfiguration,
66+
token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration> {
5567
const resolveDebugConfigurationHandler = instrumentOperation("resolveDebugConfiguration", (operationId: string) => {
5668
try {
5769
// See https://github.com/microsoft/vscode-java-debug/issues/778
5870
// Merge the platform specific properties to the global config to simplify the subsequent resolving logic.
5971
this.mergePlatformProperties(folder, config);
60-
this.resolveVariables(folder, config);
61-
return this.heuristicallyResolveDebugConfiguration(folder, config);
72+
return this.resolveAndValidateDebugConfiguration(folder, config);
6273
} catch (ex) {
6374
utility.showErrorMessage({
6475
message: String((ex && ex.message) || ex),
@@ -117,26 +128,6 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
117128
}
118129
}
119130

120-
private resolveVariables(folder: vscode.WorkspaceFolder, config: vscode.DebugConfiguration): void {
121-
// all the properties whose values are string or array of string
122-
const keys = ["mainClass", "args", "vmArgs", "modulePaths", "classPaths", "projectName",
123-
"env", "sourcePaths", "encoding", "cwd", "hostName"];
124-
if (!config) {
125-
return;
126-
}
127-
for (const key of keys) {
128-
if (config.hasOwnProperty(key)) {
129-
const value = config[key];
130-
if (_.isString(value)) {
131-
config[key] = this.resolver.resolveString(folder ? folder.uri : undefined, value);
132-
} else if (_.isArray(value)) {
133-
config[key] = _.map(value, (item) =>
134-
_.isString(item) ? this.resolver.resolveString(folder ? folder.uri : undefined, item) : item);
135-
}
136-
}
137-
}
138-
}
139-
140131
private constructLaunchConfigName(mainClass: string, projectName: string, cache: {}) {
141132
const prefix = "Debug (Launch)-";
142133
let name = prefix + mainClass.substr(mainClass.lastIndexOf(".") + 1);
@@ -152,7 +143,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
152143
}
153144
}
154145

155-
private async heuristicallyResolveDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration) {
146+
private async resolveAndValidateDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration) {
156147
try {
157148
if (this.isUserSettingsDirty) {
158149
this.isUserSettingsDirty = false;
@@ -233,18 +224,35 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
233224
config.launcherScript = utility.getLauncherScriptPath();
234225
}
235226
} else if (config.request === "attach") {
236-
if (config.processId !== undefined) {
237-
try {
238-
if (!(await resolveProcessId(config))) {
239-
return undefined;
240-
}
241-
} catch (error) {
242-
vscode.window.showErrorMessage(error.message ? error.message : String(error));
227+
if (config.hostName && config.port) {
228+
config.processId = undefined;
229+
// Continue if the hostName and port are configured.
230+
} else if (config.processId !== undefined) {
231+
// tslint:disable-next-line
232+
if (config.processId === "${command:PickJavaProcess}") {
233+
return undefined;
234+
}
235+
236+
const pid: number = Number(config.processId);
237+
if (Number.isNaN(pid)) {
238+
vscode.window.showErrorMessage(`The processId config '${config.processId}' is not a valid process id.`);
243239
return undefined;
244240
}
245-
} else if (!config.hostName || !config.port) {
241+
242+
const javaProcess = await resolveJavaProcess(pid);
243+
if (!javaProcess) {
244+
vscode.window.showErrorMessage(`Attach to process: pid '${config.processId}' is not a debuggable Java process. `
245+
+ `Please make sure the process has turned on debug mode using vmArgs like `
246+
+ `'-agentlib:jdwp=transport=dt_socket,server=y,address=5005.'`);
247+
return undefined;
248+
}
249+
250+
config.processId = undefined;
251+
config.hostName = javaProcess.hostName;
252+
config.port = javaProcess.debugPort;
253+
} else {
246254
throw new utility.UserError({
247-
message: "Please specify the host name and the port of the remote debuggee in the launch.json.",
255+
message: "Please specify the hostName/port directly, or provide the processId of the remote debuggee in the launch.json.",
248256
type: Type.USAGEERROR,
249257
anchor: anchor.ATTACH_CONFIG_ERROR,
250258
});

src/extension.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { handleHotCodeReplaceCustomEvent, initializeHotCodeReplace, NO_BUTTON, Y
1414
import { JavaDebugAdapterDescriptorFactory } from "./javaDebugAdapterDescriptorFactory";
1515
import { IMainMethod, resolveMainMethod } from "./languageServerPlugin";
1616
import { logger, Type } from "./logger";
17+
import { pickJavaProcess } from "./processPicker";
1718
import { initializeThreadOperations } from "./threadOperations";
1819
import * as utility from "./utility";
1920

@@ -38,6 +39,17 @@ function initializeExtension(operationId: string, context: vscode.ExtensionConte
3839
context.subscriptions.push(instrumentOperationAsVsCodeCommand("JavaDebug.SpecifyProgramArgs", async () => {
3940
return specifyProgramArguments(context);
4041
}));
42+
context.subscriptions.push(instrumentOperationAsVsCodeCommand("JavaDebug.PickJavaProcess", async () => {
43+
let javaProcess;
44+
try {
45+
javaProcess = await pickJavaProcess();
46+
} catch (error) {
47+
vscode.window.showErrorMessage(error.message ? error.message : String(error));
48+
}
49+
50+
// tslint:disable-next-line
51+
return javaProcess ? String(javaProcess.pid) : "${command:PickJavaProcess}";
52+
}));
4153
context.subscriptions.push(instrumentOperationAsVsCodeCommand("java.debug.hotCodeReplace", applyHCR));
4254
context.subscriptions.push(instrumentOperationAsVsCodeCommand("java.debug.runJavaFile", async (uri: vscode.Uri) => {
4355
await runJavaFile(uri, true);

src/processPicker.ts

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,6 @@ interface IJavaProcess {
1616
debugPort: number;
1717
}
1818

19-
export async function resolveProcessId(config: DebugConfiguration): Promise<boolean> {
20-
let javaProcess;
21-
const pid: number = Number(config.processId);
22-
// tslint:disable-next-line
23-
if (!config.processId || Number.isNaN(pid)) {
24-
javaProcess = await pickJavaProcess();
25-
} else {
26-
javaProcess = await resolveJavaProcess(pid);
27-
if (!javaProcess) {
28-
throw new Error(`Attach to process: pid '${config.processId}' is not a debuggable Java process. `
29-
+ `Please make sure the process has turned on debug mode using vmArgs like `
30-
+ `'-agentlib:jdwp=transport=dt_socket,server=y,address=5005.'`);
31-
}
32-
}
33-
34-
if (javaProcess) {
35-
config.processId = undefined;
36-
config.hostName = javaProcess.hostName;
37-
config.port = javaProcess.debugPort;
38-
}
39-
40-
return !!javaProcess;
41-
}
42-
4319
function convertToJavaProcess(pid: number, command: string, args: string): IJavaProcess | undefined {
4420
if (process.platform === "win32" && command.indexOf("\\??\\") === 0) {
4521
// remove leading device specifier
@@ -68,7 +44,7 @@ function convertToJavaProcess(pid: number, command: string, args: string): IJava
6844
}
6945
}
7046

71-
async function pickJavaProcess(): Promise<IJavaProcess> {
47+
export async function pickJavaProcess(): Promise<IJavaProcess> {
7248
const javaProcesses: IJavaProcess[] = [];
7349
try {
7450
await getProcesses((pid: number, ppid: number, command: string, args: string, date: number) => {
@@ -82,7 +58,7 @@ async function pickJavaProcess(): Promise<IJavaProcess> {
8258
}
8359

8460
if (!javaProcesses.length) {
85-
throw new Error("Process picker: No debuggable Java process was found. Please make sure to use vmArgs like "
61+
throw new Error("Process picker: Cannot find any debuggable Java process. Please make sure to use vmArgs like "
8662
+ "'-agentlib:jdwp=transport=dt_socket,server=y,address=5005' to turn on debug mode when you start your "
8763
+ "program.");
8864
}
@@ -105,7 +81,7 @@ async function pickJavaProcess(): Promise<IJavaProcess> {
10581
}
10682
}
10783

108-
async function resolveJavaProcess(pid: number): Promise<IJavaProcess | undefined> {
84+
export async function resolveJavaProcess(pid: number): Promise<IJavaProcess | undefined> {
10985
const processTree = await getProcessTree(pid);
11086
if (!processTree || processTree.pid !== pid) {
11187
return undefined;

0 commit comments

Comments
 (0)