4
4
import { inject , injectable } from 'inversify' ;
5
5
import * as path from 'path' ;
6
6
import { ExtensionContext , OutputChannel } from 'vscode' ;
7
- import { Message } from 'vscode-jsonrpc' ;
8
- import { CloseAction , Disposable , ErrorAction , ErrorHandler , LanguageClient , LanguageClientOptions , ServerOptions } from 'vscode-languageclient' ;
7
+ import { Disposable , LanguageClient , LanguageClientOptions , ServerOptions } from 'vscode-languageclient' ;
9
8
import { IApplicationShell } from '../common/application/types' ;
10
9
import { isTestExecution , STANDARD_OUTPUT_CHANNEL } from '../common/constants' ;
11
- import { createDeferred , Deferred } from '../common/helpers' ;
12
10
import { IFileSystem , IPlatformService } from '../common/platform/types' ;
13
11
import { StopWatch } from '../common/stopWatch' ;
14
12
import { IConfigurationService , IExtensionContext , IOutputChannel } from '../common/types' ;
@@ -18,8 +16,7 @@ import { IServiceContainer } from '../ioc/types';
18
16
import {
19
17
PYTHON_ANALYSIS_ENGINE_DOWNLOADED ,
20
18
PYTHON_ANALYSIS_ENGINE_ENABLED ,
21
- PYTHON_ANALYSIS_ENGINE_ERROR ,
22
- PYTHON_ANALYSIS_ENGINE_STARTUP
19
+ PYTHON_ANALYSIS_ENGINE_ERROR
23
20
} from '../telemetry/constants' ;
24
21
import { getTelemetryReporter } from '../telemetry/telemetry' ;
25
22
import { AnalysisEngineDownloader } from './downloader' ;
@@ -32,18 +29,6 @@ const dotNetCommand = 'dotnet';
32
29
const languageClientName = 'Python Tools' ;
33
30
const analysisEngineFolder = 'analysis' ;
34
31
35
- class LanguageServerStartupErrorHandler implements ErrorHandler {
36
- constructor ( private readonly deferred : Deferred < void > ) { }
37
- public error ( error : Error , message : Message , count : number ) : ErrorAction {
38
- this . deferred . reject ( error ) ;
39
- return ErrorAction . Continue ;
40
- }
41
- public closed ( ) : CloseAction {
42
- this . deferred . reject ( ) ;
43
- return CloseAction . Restart ;
44
- }
45
- }
46
-
47
32
@injectable ( )
48
33
export class AnalysisExtensionActivator implements IExtensionActivator {
49
34
private readonly configuration : IConfigurationService ;
@@ -102,8 +87,6 @@ export class AnalysisExtensionActivator implements IExtensionActivator {
102
87
103
88
private async startLanguageServer ( context : ExtensionContext , clientOptions : LanguageClientOptions ) : Promise < boolean > {
104
89
// Determine if we are running MSIL/Universal via dotnet or self-contained app.
105
- const mscorlib = path . join ( context . extensionPath , analysisEngineFolder , 'mscorlib.dll' ) ;
106
- const downloader = new AnalysisEngineDownloader ( this . services , analysisEngineFolder ) ;
107
90
108
91
const reporter = getTelemetryReporter ( ) ;
109
92
reporter . sendTelemetryEvent ( PYTHON_ANALYSIS_ENGINE_ENABLED ) ;
@@ -112,20 +95,21 @@ export class AnalysisExtensionActivator implements IExtensionActivator {
112
95
if ( ! settings . downloadCodeAnalysis ) {
113
96
// Depends on .NET Runtime or SDK. Typically development-only case.
114
97
this . languageClient = this . createSimpleLanguageClient ( context , clientOptions ) ;
115
- await this . tryStartLanguageClient ( context , this . languageClient ) ;
98
+ await this . startLanguageClient ( context ) ;
116
99
return true ;
117
100
}
118
101
102
+ const mscorlib = path . join ( context . extensionPath , analysisEngineFolder , 'mscorlib.dll' ) ;
119
103
if ( ! await this . fs . fileExists ( mscorlib ) ) {
104
+ const downloader = new AnalysisEngineDownloader ( this . services , analysisEngineFolder ) ;
120
105
await downloader . downloadAnalysisEngine ( context ) ;
121
106
reporter . sendTelemetryEvent ( PYTHON_ANALYSIS_ENGINE_DOWNLOADED ) ;
122
107
}
123
108
124
109
const serverModule = path . join ( context . extensionPath , analysisEngineFolder , this . platformData . getEngineExecutableName ( ) ) ;
125
- // Now try to start self-contained app
126
110
this . languageClient = this . createSelfContainedLanguageClient ( context , serverModule , clientOptions ) ;
127
111
try {
128
- await this . tryStartLanguageClient ( context , this . languageClient ) ;
112
+ await this . startLanguageClient ( context ) ;
129
113
return true ;
130
114
} catch ( ex ) {
131
115
this . appShell . showErrorMessage ( `Language server failed to start. Error ${ ex } ` ) ;
@@ -134,31 +118,10 @@ export class AnalysisExtensionActivator implements IExtensionActivator {
134
118
}
135
119
}
136
120
137
- private async tryStartLanguageClient ( context : ExtensionContext , lc : LanguageClient ) : Promise < void > {
138
- let disposable : Disposable | undefined ;
139
- const deferred = createDeferred < void > ( ) ;
140
- try {
141
- const sw = new StopWatch ( ) ;
142
- lc . clientOptions . errorHandler = new LanguageServerStartupErrorHandler ( deferred ) ;
143
-
144
- disposable = lc . start ( ) ;
145
- lc . onReady ( )
146
- . then ( ( ) => deferred . resolve ( ) )
147
- . catch ( ( reason ) => {
148
- deferred . reject ( reason ) ;
149
- } ) ;
150
- await deferred . promise ;
151
-
152
- this . output . appendLine ( `Language server ready: ${ this . sw . elapsedTime } ms` ) ;
153
- context . subscriptions . push ( disposable ) ;
154
-
155
- const reporter = getTelemetryReporter ( ) ;
156
- reporter . sendTelemetryEvent ( PYTHON_ANALYSIS_ENGINE_STARTUP , { } , { startup_time : sw . elapsedTime } ) ;
157
- } catch ( ex ) {
158
- if ( disposable ) {
159
- disposable . dispose ( ) ;
160
- }
161
- throw ex ;
121
+ private async startLanguageClient ( context : ExtensionContext ) : Promise < void > {
122
+ context . subscriptions . push ( this . languageClient ! . start ( ) ) ;
123
+ if ( isTestExecution ( ) ) {
124
+ await this . languageClient ! . onReady ( ) ;
162
125
}
163
126
}
164
127
0 commit comments