@@ -13,9 +13,8 @@ import * as commands from "./commands";
1313import * as lsPlugin from "./languageServerPlugin" ;
1414import { addMoreHelpfulVMArgs , detectLaunchCommandStyle , validateRuntime } from "./launchCommand" ;
1515import { logger , Type } from "./logger" ;
16- import { resolveProcessId } from "./processPicker" ;
16+ import { resolveJavaProcess } from "./processPicker" ;
1717import * as utility from "./utility" ;
18- import { VariableResolver } from "./variableResolver" ;
1918
2019const platformNameMappings = {
2120 win32 : "windows" ,
@@ -27,9 +26,7 @@ const platformName = platformNameMappings[process.platform];
2726export 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 } ) ;
0 commit comments