@@ -432,7 +432,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
432
432
exclude = path . join ( folder ?. uri . fsPath || "" , exclude ) ;
433
433
}
434
434
// use Uri to normalize the fs path
435
- excludes . set ( vscode . Uri . file ( exclude ) . fsPath , this . isFile ( exclude ) ) ;
435
+ excludes . set ( vscode . Uri . file ( exclude ) . fsPath , this . isFilePath ( exclude ) ) ;
436
436
continue ;
437
437
}
438
438
@@ -496,10 +496,30 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
496
496
497
497
private async resolveAndValidateMainClass ( folder : vscode . Uri | undefined , config : vscode . DebugConfiguration ,
498
498
progressReporter : IProgressReporter ) : Promise < lsPlugin . IMainClassOption | undefined > {
499
- if ( ! config . mainClass || this . isFile ( config . mainClass ) ) {
500
- const currentFile = config . mainClass || _ . get ( vscode . window . activeTextEditor , "document.uri.fsPath" ) ;
501
- if ( currentFile ) {
502
- const mainEntries = await lsPlugin . resolveMainMethod ( vscode . Uri . file ( currentFile ) ) ;
499
+ // Validate it if the mainClass is already set in launch configuration.
500
+ if ( config . mainClass && ! this . isFilePath ( config . mainClass ) ) {
501
+ const containsExternalClasspaths = ! _ . isEmpty ( config . classPaths ) || ! _ . isEmpty ( config . modulePaths ) ;
502
+ const validationResponse = await lsPlugin . validateLaunchConfig ( config . mainClass , config . projectName , containsExternalClasspaths , folder ) ;
503
+ if ( progressReporter . isCancelled ( ) ) {
504
+ return undefined ;
505
+ } else if ( ! validationResponse . mainClass . isValid || ! validationResponse . projectName . isValid ) {
506
+ return this . fixMainClass ( folder , config , validationResponse , progressReporter ) ;
507
+ }
508
+
509
+ return {
510
+ mainClass : config . mainClass ,
511
+ projectName : config . projectName ,
512
+ } ;
513
+ }
514
+
515
+ return this . resolveMainClass ( config , progressReporter ) ;
516
+ }
517
+
518
+ private async resolveMainClass ( config : vscode . DebugConfiguration , progressReporter : IProgressReporter ) :
519
+ Promise < lsPlugin . IMainClassOption | undefined > {
520
+ if ( config . projectName ) {
521
+ if ( this . isFilePath ( config . mainClass ) ) {
522
+ const mainEntries = await lsPlugin . resolveMainMethod ( vscode . Uri . file ( config . mainClass ) ) ;
503
523
if ( progressReporter . isCancelled ( ) ) {
504
524
return undefined ;
505
525
} else if ( mainEntries . length ) {
@@ -510,27 +530,34 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
510
530
}
511
531
}
512
532
513
- const hintMessage = currentFile ?
514
- `The file '${ path . basename ( currentFile ) } ' is not executable, please select a main class you want to run.` :
515
- "Please select a main class you want to run." ;
516
- return this . promptMainClass ( folder , progressReporter , hintMessage ) ;
533
+ return this . promptMainClassUnderProject ( config . projectName , progressReporter , "Please select a main class you wan to run" ) ;
517
534
}
518
535
519
- const containsExternalClasspaths = ! _ . isEmpty ( config . classPaths ) || ! _ . isEmpty ( config . modulePaths ) ;
520
- const validationResponse = await lsPlugin . validateLaunchConfig ( config . mainClass , config . projectName , containsExternalClasspaths , folder ) ;
521
- if ( progressReporter . isCancelled ( ) ) {
522
- return undefined ;
523
- } else if ( ! validationResponse . mainClass . isValid || ! validationResponse . projectName . isValid ) {
524
- return this . fixMainClass ( folder , config , validationResponse , progressReporter ) ;
536
+ // Try to resolve main class from current file
537
+ const currentFile = config . mainClass || vscode . window . activeTextEditor ?. document . uri . fsPath ;
538
+ if ( currentFile ) {
539
+ const mainEntries = await lsPlugin . resolveMainMethod ( vscode . Uri . file ( currentFile ) ) ;
540
+ if ( progressReporter . isCancelled ( ) ) {
541
+ return undefined ;
542
+ } else if ( mainEntries . length ) {
543
+ if ( ! mainClassPicker . isAutoPicked ( mainEntries ) ) {
544
+ progressReporter . hide ( true ) ;
545
+ }
546
+ return mainClassPicker . showQuickPick ( mainEntries , "Please select a main class you want to run." ) ;
547
+ }
525
548
}
526
549
527
- return {
528
- mainClass : config . mainClass ,
529
- projectName : config . projectName ,
530
- } ;
550
+ const hintMessage = currentFile ?
551
+ `The file ' ${ path . basename ( currentFile ) } ' is not executable, please select a main class you want to run.` :
552
+ "Please select a main class you want to run." ;
553
+ return this . promptMainClassUnderPath ( undefined , progressReporter , hintMessage ) ;
531
554
}
532
555
533
- private isFile ( filePath : string ) : boolean {
556
+ private isFilePath ( filePath : string ) : boolean {
557
+ if ( ! filePath ) {
558
+ return false ;
559
+ }
560
+
534
561
try {
535
562
return fs . lstatSync ( filePath ) . isFile ( ) ;
536
563
} catch ( error ) {
@@ -631,7 +658,7 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
631
658
}
632
659
}
633
660
634
- private async promptMainClass ( folder : vscode . Uri | undefined , progressReporter : IProgressReporter , hintMessage ?: string ) :
661
+ private async promptMainClassUnderPath ( folder : vscode . Uri | undefined , progressReporter : IProgressReporter , hintMessage ?: string ) :
635
662
Promise < lsPlugin . IMainClassOption | undefined > {
636
663
const res = await lsPlugin . resolveMainClass ( folder ) ;
637
664
if ( progressReporter . isCancelled ( ) ) {
@@ -650,6 +677,25 @@ export class JavaDebugConfigurationProvider implements vscode.DebugConfiguration
650
677
}
651
678
return mainClassPicker . showQuickPickWithRecentlyUsed ( res , hintMessage || "Select main class<project name>" ) ;
652
679
}
680
+
681
+ private async promptMainClassUnderProject ( projectName : string , progressReporter : IProgressReporter , hintMessage ?: string ) :
682
+ Promise < lsPlugin . IMainClassOption | undefined > {
683
+ const res = await lsPlugin . resolveMainClassFromProject ( projectName ) ;
684
+ if ( progressReporter . isCancelled ( ) ) {
685
+ return undefined ;
686
+ } else if ( res . length === 0 ) {
687
+ throw new utility . UserError ( {
688
+ message : `Cannot find a class with the main method in the project '${ projectName } '.` ,
689
+ type : Type . USAGEERROR ,
690
+ anchor : anchor . CANNOT_FIND_MAIN_CLASS ,
691
+ } ) ;
692
+ }
693
+
694
+ if ( ! mainClassPicker . isAutoPicked ( res ) ) {
695
+ progressReporter . hide ( true ) ;
696
+ }
697
+ return mainClassPicker . showQuickPickWithRecentlyUsed ( res , hintMessage || "Select main class<project name>" ) ;
698
+ }
653
699
}
654
700
655
701
async function updateDebugSettings ( event ?: vscode . ConfigurationChangeEvent ) {
0 commit comments