@@ -30,6 +30,8 @@ const platformNameMappings: { [key: string]: string } = {
3030} ;
3131const platformName = platformNameMappings [ process . platform ] ;
3232
33+ export let lastUsedLaunchConfig : vscode . DebugConfiguration | undefined ;
34+
3335export class JavaDebugConfigurationProvider implements vscode . DebugConfigurationProvider {
3436 private isUserSettingsDirty : boolean = true ;
3537 constructor ( ) {
@@ -75,6 +77,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
7577 config . type = "java" ;
7678 config . name = "Java Debug" ;
7779 config . request = "launch" ;
80+ config . __origin = "internal" ;
7881 }
7982
8083 return config ;
@@ -200,6 +203,15 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
200203
201204 private async resolveAndValidateDebugConfiguration ( folder : vscode . WorkspaceFolder | undefined , config : vscode . DebugConfiguration ,
202205 token ?: vscode . CancellationToken ) {
206+ let configCopy : vscode . DebugConfiguration | undefined ;
207+ const isConfigFromInternal = config . __origin === "internal" /** in-memory configuration from debugger */
208+ || config . __configurationTarget /** configuration from launch.json */ ;
209+ if ( config . request === "launch" && isConfigFromInternal ) {
210+ configCopy = _ . cloneDeep ( config ) ;
211+ delete configCopy . __progressId ;
212+ delete configCopy . noDebug ;
213+ }
214+
203215 let progressReporter = progressProvider . getProgressReporter ( config . __progressId ) ;
204216 if ( ! progressReporter && config . __progressId ) {
205217 return undefined ;
@@ -231,35 +243,26 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
231243 }
232244
233245 if ( config . request === "launch" ) {
234- this . mergeEnvFile ( config ) ;
235-
236- // If the user doesn't specify 'vmArgs' in launch.json, use the global setting to get the default vmArgs.
237- if ( config . vmArgs === undefined ) {
238- const debugSettings : vscode . WorkspaceConfiguration = vscode . workspace . getConfiguration ( "java.debug.settings" ) ;
239- config . vmArgs = debugSettings . vmArgs ;
246+ const mainClassOption = await this . resolveAndValidateMainClass ( folder && folder . uri , config , progressReporter ) ;
247+ if ( ! mainClassOption || ! mainClassOption . mainClass ) { // Exit silently if the user cancels the prompt fix by ESC.
248+ // Exit the debug session.
249+ return undefined ;
240250 }
241- // If the user doesn't specify 'console' in launch.json, use the global setting to get the launch console.
242- if ( ! config . console ) {
243- const debugSettings : vscode . WorkspaceConfiguration = vscode . workspace . getConfiguration ( "java.debug.settings" ) ;
244- config . console = debugSettings . console ;
251+
252+ config . mainClass = mainClassOption . mainClass ;
253+ config . projectName = mainClassOption . projectName ;
254+ if ( config . __workspaceFolder && config . __workspaceFolder !== folder ) {
255+ folder = config . __workspaceFolder ;
245256 }
246- // If the console is integratedTerminal, don't auto switch the focus to DEBUG CONSOLE.
247- if ( config . console === "integratedTerminal" && ! config . internalConsoleOptions ) {
248- config . internalConsoleOptions = "neverOpen" ;
257+ // Update the job name if the main class is changed during the resolving of configuration provider.
258+ if ( configCopy && configCopy . mainClass !== config . mainClass ) {
259+ config . name = config . mainClass . substr ( config . mainClass . lastIndexOf ( "." ) + 1 ) ;
260+ progressReporter . setJobName ( utility . launchJobName ( config . name , config . noDebug ) ) ;
249261 }
250-
251-
252262 if ( progressReporter . isCancelled ( ) ) {
253263 return undefined ;
254264 }
255265
256- progressReporter . report ( "Resolving main class..." ) ;
257- const mainClassOption = await this . resolveAndValidateMainClass ( folder && folder . uri , config , progressReporter ) ;
258- if ( ! mainClassOption || ! mainClassOption . mainClass ) { // Exit silently if the user cancels the prompt fix by ESC.
259- // Exit the debug session.
260- return undefined ;
261- }
262-
263266 if ( needsBuildWorkspace ( ) ) {
264267 progressReporter . report ( "Compiling..." ) ;
265268 const proceed = await buildWorkspace ( {
@@ -272,9 +275,26 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
272275 }
273276 }
274277
278+ if ( progressReporter . isCancelled ( ) ) {
279+ return undefined ;
280+ }
281+
275282 progressReporter . report ( "Resolving launch configuration..." ) ;
276- config . mainClass = mainClassOption . mainClass ;
277- config . projectName = mainClassOption . projectName ;
283+ this . mergeEnvFile ( config ) ;
284+ // If the user doesn't specify 'vmArgs' in launch.json, use the global setting to get the default vmArgs.
285+ if ( config . vmArgs === undefined ) {
286+ const debugSettings : vscode . WorkspaceConfiguration = vscode . workspace . getConfiguration ( "java.debug.settings" ) ;
287+ config . vmArgs = debugSettings . vmArgs ;
288+ }
289+ // If the user doesn't specify 'console' in launch.json, use the global setting to get the launch console.
290+ if ( ! config . console ) {
291+ const debugSettings : vscode . WorkspaceConfiguration = vscode . workspace . getConfiguration ( "java.debug.settings" ) ;
292+ config . console = debugSettings . console ;
293+ }
294+ // If the console is integratedTerminal, don't auto switch the focus to DEBUG CONSOLE.
295+ if ( config . console === "integratedTerminal" && ! config . internalConsoleOptions ) {
296+ config . internalConsoleOptions = "neverOpen" ;
297+ }
278298
279299 if ( progressReporter . isCancelled ( ) ) {
280300 return undefined ;
@@ -407,6 +427,14 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
407427 utility . showErrorMessageWithTroubleshooting ( utility . convertErrorToMessage ( ex ) ) ;
408428 return undefined ;
409429 } finally {
430+ if ( configCopy && config . mainClass ) {
431+ configCopy . name = config . name ;
432+ configCopy . mainClass = config . mainClass ;
433+ configCopy . projectName = config . projectName ;
434+ configCopy . __workspaceFolder = folder ;
435+ lastUsedLaunchConfig = configCopy ;
436+ }
437+
410438 progressReporter . done ( ) ;
411439 }
412440 }
@@ -521,6 +549,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
521549 progressReporter : IProgressReporter ) : Promise < lsPlugin . IMainClassOption | undefined > {
522550 // Validate it if the mainClass is already set in launch configuration.
523551 if ( config . mainClass && ! this . isFilePath ( config . mainClass ) ) {
552+ progressReporter . report ( "Resolving main class..." ) ;
524553 const containsExternalClasspaths = ! _ . isEmpty ( config . classPaths ) || ! _ . isEmpty ( config . modulePaths ) ;
525554 const validationResponse = await lsPlugin . validateLaunchConfig ( config . mainClass , config . projectName , containsExternalClasspaths , folder ) ;
526555 if ( progressReporter . isCancelled ( ) ) {
@@ -541,6 +570,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
541570 private async resolveMainClass ( config : vscode . DebugConfiguration , progressReporter : IProgressReporter ) :
542571 Promise < lsPlugin . IMainClassOption | undefined > {
543572 if ( config . projectName ) {
573+ progressReporter . report ( "Resolving main class..." ) ;
544574 if ( this . isFilePath ( config . mainClass ) ) {
545575 const mainEntries = await lsPlugin . resolveMainMethod ( vscode . Uri . file ( config . mainClass ) ) ;
546576 if ( progressReporter . isCancelled ( ) ) {
@@ -570,6 +600,18 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
570600 }
571601 }
572602
603+ // If current file is not executable, run previously used launch config.
604+ if ( lastUsedLaunchConfig ) {
605+ Object . assign ( config , lastUsedLaunchConfig ) ;
606+ progressReporter . setJobName ( utility . launchJobName ( config . name , config . noDebug ) ) ;
607+ progressReporter . report ( "Resolving main class..." ) ;
608+ return {
609+ mainClass : config . mainClass ,
610+ projectName : config . projectName ,
611+ } ;
612+ }
613+
614+ progressReporter . report ( "Resolving main class..." ) ;
573615 const hintMessage = currentFile ?
574616 `The file '${ path . basename ( currentFile ) } ' is not executable, please select a main class you want to run.` :
575617 "Please select a main class you want to run." ;
0 commit comments