forked from microsoft/vscode-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmanager.ts
More file actions
118 lines (102 loc) · 4.29 KB
/
manager.ts
File metadata and controls
118 lines (102 loc) · 4.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import '../../common/extensions';
import { inject, injectable, named } from 'inversify';
import { traceDecorators } from '../../common/logger';
import {
BANNER_NAME_LS_SURVEY,
IDisposable,
IExperimentsManager,
IPythonExtensionBanner,
Resource
} from '../../common/types';
import { debounceSync } from '../../common/utils/decorators';
import { PythonInterpreter } from '../../interpreter/contracts';
import { IServiceContainer } from '../../ioc/types';
import { captureTelemetry } from '../../telemetry';
import { EventName } from '../../telemetry/constants';
import { LanguageClientMiddleware } from '../languageClientMiddleware';
import {
ILanguageServerAnalysisOptions,
ILanguageServerFolderService,
ILanguageServerManager,
ILanguageServerProxy,
LanguageServerType
} from '../types';
@injectable()
export class NodeLanguageServerManager implements ILanguageServerManager {
private languageServerProxy?: ILanguageServerProxy;
private resource!: Resource;
private interpreter: PythonInterpreter | undefined;
private middleware: LanguageClientMiddleware | undefined;
private disposables: IDisposable[] = [];
private connected: boolean = false;
constructor(
@inject(IServiceContainer) private readonly serviceContainer: IServiceContainer,
@inject(ILanguageServerAnalysisOptions) private readonly analysisOptions: ILanguageServerAnalysisOptions,
@inject(IPythonExtensionBanner)
@named(BANNER_NAME_LS_SURVEY)
private readonly surveyBanner: IPythonExtensionBanner,
@inject(ILanguageServerFolderService) private readonly folderService: ILanguageServerFolderService,
@inject(IExperimentsManager) private readonly experimentsManager: IExperimentsManager
) {}
public dispose() {
if (this.languageProxy) {
this.languageProxy.dispose();
}
this.disposables.forEach(d => d.dispose());
}
public get languageProxy() {
return this.languageServerProxy;
}
@traceDecorators.error('Failed to start Language Server')
public async start(resource: Resource, interpreter: PythonInterpreter | undefined): Promise<void> {
if (this.languageProxy) {
throw new Error('Language Server already started');
}
this.resource = resource;
this.interpreter = interpreter;
this.analysisOptions.onDidChange(this.restartLanguageServerDebounced, this, this.disposables);
await this.analysisOptions.initialize(resource, interpreter);
await this.startLanguageServer();
}
public connect() {
this.connected = true;
this.middleware?.connect();
}
public disconnect() {
this.connected = false;
this.middleware?.disconnect();
}
@debounceSync(1000)
protected restartLanguageServerDebounced(): void {
this.restartLanguageServer().ignoreErrors();
}
@traceDecorators.error('Failed to restart Language Server')
@traceDecorators.verbose('Restarting Language Server')
protected async restartLanguageServer(): Promise<void> {
if (this.languageProxy) {
this.languageProxy.dispose();
}
await this.startLanguageServer();
}
@captureTelemetry(EventName.PYTHON_NODE_SERVER_STARTUP, undefined, true)
@traceDecorators.verbose('Starting Language Server')
protected async startLanguageServer(): Promise<void> {
this.languageServerProxy = this.serviceContainer.get<ILanguageServerProxy>(ILanguageServerProxy);
const versionPair = await this.folderService.getCurrentLanguageServerDirectory();
const options = await this.analysisOptions!.getAnalysisOptions();
options.middleware = this.middleware = new LanguageClientMiddleware(
this.surveyBanner,
this.experimentsManager,
LanguageServerType.Node,
versionPair?.version.format()
);
// Make sure the middleware is connected if we restart and we we're already connected.
if (this.connected) {
this.middleware.connect();
}
// Then use this middleware to start a new language client.
await this.languageServerProxy.start(this.resource, this.interpreter, options);
}
}