2
2
// Licensed under the MIT license.
3
3
4
4
import * 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" ;
6
7
import * as commands from "./commands" ;
7
8
import { JavaDebugConfigurationProvider } from "./configurationProvider" ;
8
9
import { HCR_EVENT , JAVA_LANGID , USER_NOTIFICATION_EVENT } from "./constants" ;
9
- import { initializeCodeLensProvider } from "./debugCodeLensProvider"
10
+ import { initializeCodeLensProvider , startDebugging } from "./debugCodeLensProvider"
10
11
import { handleHotCodeReplaceCustomEvent , initializeHotCodeReplace } from "./hotCodeReplace" ;
12
+ import { IMainMethod , resolveMainMethod } from "./languageServerPlugin" ;
11
13
import { logger , Type } from "./logger" ;
12
14
import * as utility from "./utility" ;
13
15
@@ -23,8 +25,31 @@ function initializeExtension(operationId: string, context: vscode.ExtensionConte
23
25
description : "activateExtension" ,
24
26
} ) ;
25
27
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 ) {
26
51
const measureKeys = [ "duration" ] ;
27
- vscode . debug . onDidTerminateDebugSession ( ( e ) => {
52
+ context . subscriptions . push ( vscode . debug . onDidTerminateDebugSession ( ( e ) => {
28
53
if ( e . type !== "java" ) {
29
54
return ;
30
55
}
@@ -44,45 +69,8 @@ function initializeExtension(operationId: string, context: vscode.ExtensionConte
44
69
} ) ;
45
70
}
46
71
} ) ;
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 ) ;
53
72
} ) ) ;
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
- }
70
73
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 ) ;
86
74
context . subscriptions . push ( vscode . debug . onDidReceiveDebugSessionCustomEvent ( ( customEvent ) => {
87
75
const t = customEvent . session ? customEvent . session . type : undefined ;
88
76
if ( t !== JAVA_LANGID ) {
@@ -94,13 +82,6 @@ function initializeExtension(operationId: string, context: vscode.ExtensionConte
94
82
handleUserNotification ( customEvent ) ;
95
83
}
96
84
} ) ) ;
97
-
98
- initializeCodeLensProvider ( context ) ;
99
- }
100
-
101
- // this method is called when your extension is deactivated
102
- export async function deactivate ( ) {
103
- await disposeTelemetryWrapper ( ) ;
104
85
}
105
86
106
87
function handleUserNotification ( customEvent ) {
@@ -144,7 +125,69 @@ function specifyProgramArguments(context: vscode.ExtensionContext): Thenable<str
144
125
} ) ;
145
126
}
146
127
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 ) ;
150
193
}
0 commit comments