@@ -51,7 +51,9 @@ namespace GetExperimentValue {
51
51
export class NodeLanguageServerProxy implements ILanguageServerProxy {
52
52
public languageClient : LanguageClient | undefined ;
53
53
54
- private languageServerTask : Promise < void > | undefined ;
54
+ private languageDisposeTask : Promise < void > | undefined ;
55
+
56
+ private languageServerTask : Promise < LanguageClient > | undefined ;
55
57
56
58
private cancellationStrategy : FileBasedCancellationStrategy | undefined ;
57
59
@@ -80,11 +82,12 @@ export class NodeLanguageServerProxy implements ILanguageServerProxy {
80
82
public dispose ( ) : void {
81
83
if ( this . languageClient ) {
82
84
// Do not await on this.
83
- this . languageServerTask = this . languageClient
85
+ this . languageDisposeTask = this . languageClient
84
86
. stop ( )
85
87
. then ( noop , ( ex ) => traceError ( 'Stopping language client failed' , ex ) ) ;
86
88
87
89
this . languageClient = undefined ;
90
+ this . languageServerTask = undefined ;
88
91
}
89
92
if ( this . cancellationStrategy ) {
90
93
this . cancellationStrategy . dispose ( ) ;
@@ -110,42 +113,45 @@ export class NodeLanguageServerProxy implements ILanguageServerProxy {
110
113
interpreter : PythonEnvironment | undefined ,
111
114
options : LanguageClientOptions ,
112
115
) : Promise < void > {
113
- if ( this . languageServerTask ) {
114
- // Make sure to hold onto local client so that
115
- // await below doesn't use wrong client.
116
- const client = this . languageClient ;
117
-
118
- // Wait if there is pending server task.
119
- await this . languageServerTask ;
120
-
121
- // if client is already started, bail out.
122
- if ( client ) {
123
- return ;
124
- }
116
+ if ( this . languageDisposeTask ) {
117
+ await this . languageDisposeTask ;
118
+ this . languageDisposeTask = undefined ;
119
+ }
120
+
121
+ if ( ! this . languageServerTask ) {
122
+ this . languageServerTask = this . startServer ( resource , interpreter , options ) ;
125
123
}
126
124
125
+ this . languageClient = await this . languageDisposeTask ;
126
+ }
127
+
128
+ // eslint-disable-next-line class-methods-use-this
129
+ public loadExtension ( ) : void {
130
+ // No body.
131
+ }
132
+
133
+ private async startServer (
134
+ resource : Resource ,
135
+ interpreter : PythonEnvironment | undefined ,
136
+ options : LanguageClientOptions ,
137
+ ) {
127
138
const extension = this . extensions . getExtension ( PYLANCE_EXTENSION_ID ) ;
128
139
this . lsVersion = extension ?. packageJSON . version || '0' ;
129
140
130
141
this . cancellationStrategy = new FileBasedCancellationStrategy ( ) ;
131
142
options . connectionOptions = { cancellationStrategy : this . cancellationStrategy } ;
132
143
133
- this . languageClient = await this . factory . createLanguageClient ( resource , interpreter , options ) ;
134
- this . registerHandlers ( resource ) ;
144
+ const languageClient = await this . factory . createLanguageClient ( resource , interpreter , options ) ;
145
+ this . registerHandlers ( languageClient , resource ) ;
135
146
136
147
this . disposables . push (
137
148
this . workspace . onDidGrantWorkspaceTrust ( ( ) => {
138
- this . languageClient ! . sendNotification ( 'python/workspaceTrusted' , { isTrusted : true } ) ;
149
+ languageClient . sendNotification ( 'python/workspaceTrusted' , { isTrusted : true } ) ;
139
150
} ) ,
140
151
) ;
141
152
142
- this . languageServerTask = this . languageClient . start ( ) ;
143
- await this . languageServerTask ;
144
- }
145
-
146
- // eslint-disable-next-line class-methods-use-this
147
- public loadExtension ( ) : void {
148
- // No body.
153
+ await languageClient . start ( ) ;
154
+ return languageClient ;
149
155
}
150
156
151
157
@captureTelemetry (
@@ -155,13 +161,13 @@ export class NodeLanguageServerProxy implements ILanguageServerProxy {
155
161
undefined ,
156
162
NodeLanguageServerProxy . versionTelemetryProps ,
157
163
)
158
- private registerHandlers ( _resource : Resource ) {
164
+ private registerHandlers ( languageClient : LanguageClient , _resource : Resource ) {
159
165
if ( this . disposed ) {
160
166
// Check if it got disposed in the interim.
161
167
return ;
162
168
}
163
169
164
- const progressReporting = new ProgressReporting ( this . languageClient ! ) ;
170
+ const progressReporting = new ProgressReporting ( languageClient ) ;
165
171
this . disposables . push ( progressReporting ) ;
166
172
167
173
this . disposables . push (
@@ -170,28 +176,28 @@ export class NodeLanguageServerProxy implements ILanguageServerProxy {
170
176
// the workspace configurations (to then pick up pythonPath set in the middleware).
171
177
// This is needed as interpreter changes via the interpreter path service happen
172
178
// outside of VS Code's settings (which would mean VS Code sends the config updates itself).
173
- this . languageClient ! . sendNotification ( DidChangeConfigurationNotification . type , {
179
+ languageClient . sendNotification ( DidChangeConfigurationNotification . type , {
174
180
settings : null ,
175
181
} ) ;
176
182
} ) ,
177
183
) ;
178
184
this . disposables . push (
179
185
this . environmentService . onDidEnvironmentVariablesChange ( ( ) => {
180
- this . languageClient ! . sendNotification ( DidChangeConfigurationNotification . type , {
186
+ languageClient . sendNotification ( DidChangeConfigurationNotification . type , {
181
187
settings : null ,
182
188
} ) ;
183
189
} ) ,
184
190
) ;
185
191
186
- this . languageClient ! . onRequest (
192
+ languageClient . onRequest (
187
193
InExperiment . Method ,
188
194
async ( params : InExperiment . IRequest ) : Promise < InExperiment . IResponse > => {
189
195
const inExperiment = await this . experimentService . inExperiment ( params . experimentName ) ;
190
196
return { inExperiment } ;
191
197
} ,
192
198
) ;
193
199
194
- this . languageClient ! . onRequest (
200
+ languageClient . onRequest (
195
201
GetExperimentValue . Method ,
196
202
async < T extends boolean | number | string > (
197
203
params : GetExperimentValue . IRequest ,
@@ -202,7 +208,7 @@ export class NodeLanguageServerProxy implements ILanguageServerProxy {
202
208
) ;
203
209
204
210
this . disposables . push (
205
- this . languageClient ! . onRequest ( 'python/isTrustedWorkspace' , async ( ) => ( {
211
+ languageClient . onRequest ( 'python/isTrustedWorkspace' , async ( ) => ( {
206
212
isTrusted : this . workspace . isTrusted ,
207
213
} ) ) ,
208
214
) ;
0 commit comments