22// Licensed under the MIT license.
33
44import * as vscode from "vscode" ;
5- import { dispose as disposeTelemetryWrapper , initializeFromJsonFile , instrumentOperation } from "vscode-extension-telemetry-wrapper" ;
5+ import { dispose as disposeTelemetryWrapper , initializeFromJsonFile , instrumentOperation ,
6+ instrumentOperationAsVsCodeCommand } from "vscode-extension-telemetry-wrapper" ;
67import * as commands from "./commands" ;
78import { JavaDebugConfigurationProvider } from "./configurationProvider" ;
89import { HCR_EVENT , JAVA_LANGID , USER_NOTIFICATION_EVENT } from "./constants" ;
9- import { initializeCodeLensProvider } from "./debugCodeLensProvider"
10+ import { initializeCodeLensProvider , startDebugging } from "./debugCodeLensProvider"
1011import { handleHotCodeReplaceCustomEvent , initializeHotCodeReplace } from "./hotCodeReplace" ;
12+ import { IMainMethod , resolveMainMethod } from "./languageServerPlugin" ;
1113import { logger , Type } from "./logger" ;
1214import * as utility from "./utility" ;
1315
@@ -23,8 +25,31 @@ function initializeExtension(operationId: string, context: vscode.ExtensionConte
2325 description : "activateExtension" ,
2426 } ) ;
2527
28+ registerDebugEventListener ( context ) ;
29+ context . subscriptions . push ( logger ) ;
30+ context . subscriptions . push ( vscode . debug . registerDebugConfigurationProvider ( "java" , new JavaDebugConfigurationProvider ( ) ) ) ;
31+ context . subscriptions . push ( instrumentOperationAsVsCodeCommand ( "JavaDebug.SpecifyProgramArgs" , async ( ) => {
32+ return specifyProgramArguments ( context ) ;
33+ } ) ) ;
34+ context . subscriptions . push ( instrumentOperationAsVsCodeCommand ( "java.debug.hotCodeReplace" , applyHCR ) ) ;
35+ context . subscriptions . push ( instrumentOperationAsVsCodeCommand ( "java.debug.runJavaFile" , async ( uri : vscode . Uri ) => {
36+ await runJavaFile ( uri , true ) ;
37+ } ) ) ;
38+ context . subscriptions . push ( instrumentOperationAsVsCodeCommand ( "java.debug.debugJavaFile" , async ( uri : vscode . Uri ) => {
39+ await runJavaFile ( uri , false ) ;
40+ } ) ) ;
41+ initializeHotCodeReplace ( context ) ;
42+ initializeCodeLensProvider ( context ) ;
43+ }
44+
45+ // this method is called when your extension is deactivated
46+ export async function deactivate ( ) {
47+ await disposeTelemetryWrapper ( ) ;
48+ }
49+
50+ function registerDebugEventListener ( context : vscode . ExtensionContext ) {
2651 const measureKeys = [ "duration" ] ;
27- vscode . debug . onDidTerminateDebugSession ( ( e ) => {
52+ context . subscriptions . push ( vscode . debug . onDidTerminateDebugSession ( ( e ) => {
2853 if ( e . type !== "java" ) {
2954 return ;
3055 }
@@ -44,45 +69,8 @@ function initializeExtension(operationId: string, context: vscode.ExtensionConte
4469 } ) ;
4570 }
4671 } ) ;
47- } ) ;
48-
49- context . subscriptions . push ( logger ) ;
50- context . subscriptions . push ( vscode . debug . registerDebugConfigurationProvider ( "java" , new JavaDebugConfigurationProvider ( ) ) ) ;
51- context . subscriptions . push ( instrumentAndRegisterCommand ( "JavaDebug.SpecifyProgramArgs" , async ( ) => {
52- return specifyProgramArguments ( context ) ;
5372 } ) ) ;
54- context . subscriptions . push ( instrumentAndRegisterCommand ( "java.debug.hotCodeReplace" , async ( args : any ) => {
55- const autobuildConfig : vscode . WorkspaceConfiguration = vscode . workspace . getConfiguration ( "java.autobuild" ) ;
56- if ( ! autobuildConfig . enabled ) {
57- const ans = await vscode . window . showWarningMessage (
58- "The hot code replace feature requires you to enable the autobuild flag, do you want to enable it?" ,
59- "Yes" , "No" ) ;
60- if ( ans === "Yes" ) {
61- await autobuildConfig . update ( "enabled" , true ) ;
62- // Force an incremental build to avoid auto build is not finishing during HCR.
63- try {
64- await commands . executeJavaExtensionCommand ( commands . JAVA_BUILD_WORKSPACE , false )
65- } catch ( err ) {
66- // do nothing.
67- }
68- }
69- }
7073
71- const debugSession : vscode . DebugSession = vscode . debug . activeDebugSession ;
72- if ( ! debugSession ) {
73- return ;
74- }
75-
76- return vscode . window . withProgress ( { location : vscode . ProgressLocation . Window } , async ( progress ) => {
77- progress . report ( { message : "Applying code changes..." } ) ;
78-
79- const response = await debugSession . customRequest ( "redefineClasses" ) ;
80- if ( ! response || ! response . changedClasses || ! response . changedClasses . length ) {
81- vscode . window . showWarningMessage ( "Cannot find any changed classes for hot replace!" ) ;
82- }
83- } ) ;
84- } ) ) ;
85- initializeHotCodeReplace ( context ) ;
8674 context . subscriptions . push ( vscode . debug . onDidReceiveDebugSessionCustomEvent ( ( customEvent ) => {
8775 const t = customEvent . session ? customEvent . session . type : undefined ;
8876 if ( t !== JAVA_LANGID ) {
@@ -94,13 +82,6 @@ function initializeExtension(operationId: string, context: vscode.ExtensionConte
9482 handleUserNotification ( customEvent ) ;
9583 }
9684 } ) ) ;
97-
98- initializeCodeLensProvider ( context ) ;
99- }
100-
101- // this method is called when your extension is deactivated
102- export async function deactivate ( ) {
103- await disposeTelemetryWrapper ( ) ;
10485}
10586
10687function handleUserNotification ( customEvent ) {
@@ -144,7 +125,69 @@ function specifyProgramArguments(context: vscode.ExtensionContext): Thenable<str
144125 } ) ;
145126}
146127
147- function instrumentAndRegisterCommand ( name : string , cb : ( ...args : any [ ] ) => any ) {
148- const instrumented = instrumentOperation ( name , async ( _operationId , myargs ) => await cb ( myargs ) ) ;
149- return vscode . commands . registerCommand ( name , instrumented ) ;
128+ async function applyHCR ( ) {
129+ const autobuildConfig : vscode . WorkspaceConfiguration = vscode . workspace . getConfiguration ( "java.autobuild" ) ;
130+ if ( ! autobuildConfig . enabled ) {
131+ const ans = await vscode . window . showWarningMessage (
132+ "The hot code replace feature requires you to enable the autobuild flag, do you want to enable it?" ,
133+ "Yes" , "No" ) ;
134+ if ( ans === "Yes" ) {
135+ await autobuildConfig . update ( "enabled" , true ) ;
136+ // Force an incremental build to avoid auto build is not finishing during HCR.
137+ try {
138+ await commands . executeJavaExtensionCommand ( commands . JAVA_BUILD_WORKSPACE , false )
139+ } catch ( err ) {
140+ // do nothing.
141+ }
142+ }
143+ }
144+
145+ const debugSession : vscode . DebugSession = vscode . debug . activeDebugSession ;
146+ if ( ! debugSession ) {
147+ return ;
148+ }
149+
150+ return vscode . window . withProgress ( { location : vscode . ProgressLocation . Window } , async ( progress ) => {
151+ progress . report ( { message : "Applying code changes..." } ) ;
152+
153+ const response = await debugSession . customRequest ( "redefineClasses" ) ;
154+ if ( ! response || ! response . changedClasses || ! response . changedClasses . length ) {
155+ vscode . window . showWarningMessage ( "Cannot find any changed classes for hot replace!" ) ;
156+ }
157+ } ) ;
158+ }
159+
160+ async function runJavaFile ( uri : vscode . Uri , noDebug : boolean ) {
161+ try {
162+ // Wait for Java Language Support extension being activated.
163+ await utility . getJavaExtensionAPI ( ) ;
164+ } catch ( ex ) {
165+ if ( ex instanceof utility . JavaExtensionNotActivatedError ) {
166+ utility . guideToInstallJavaExtension ( ) ;
167+ return ;
168+ }
169+
170+ throw ex ;
171+ }
172+
173+ const mainMethods : IMainMethod [ ] = await resolveMainMethod ( uri ) ;
174+ if ( ! mainMethods || ! mainMethods . length ) {
175+ vscode . window . showErrorMessage (
176+ "Error: Main method not found in the file, please define the main method as: public static void main(String[] args)" ) ;
177+ return ;
178+ }
179+
180+ const projectName = mainMethods [ 0 ] . projectName ;
181+ let mainClass = mainMethods [ 0 ] . mainClass ;
182+ if ( mainMethods . length > 1 ) {
183+ mainClass = await vscode . window . showQuickPick ( mainMethods . map ( ( mainMethod ) => mainMethod . mainClass ) , {
184+ placeHolder : "Select the main class to launch." ,
185+ } ) ;
186+ }
187+
188+ if ( ! mainClass ) {
189+ return ;
190+ }
191+
192+ await startDebugging ( mainClass , projectName , uri , noDebug ) ;
150193}
0 commit comments