Skip to content

Commit 6d6d33d

Browse files
authored
Refactor language service activation to support more activation handlers (#4039)
* Address code review comments * Refactor language server activation * Fix typo * Fix references
1 parent db55fa1 commit 6d6d33d

20 files changed

Lines changed: 364 additions & 320 deletions

package.nls.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,5 +183,10 @@
183183
"UnitTests.testErrorDiagnosticMessage": "Error",
184184
"UnitTests.testFailDiagnosticMessage": "Fail",
185185
"UnitTests.testSkippedDiagnosticMessage": "Skipped",
186-
"Common.openOutputPanel":"Show output"
186+
"Common.openOutputPanel": "Show output",
187+
"LanguageService.downloadFailedOutputMessage": "download failed",
188+
"LanguageService.extractionFailedOutputMessage": "extraction failed",
189+
"LanguageService.extractionCompletedOutputMessage": "complete",
190+
"LanguageService.extractionDoneOutputMessage": "done",
191+
"LanguageService.reloadVSCodeIfSeachPathHasChanged": "Search paths have changed for this Python interpreter. Please reload the extension to ensure that the IntelliSense works correctly"
187192
}

src/client/activation/downloadChannelRules.ts renamed to src/client/activation/languageServer/downloadChannelRules.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
'use strict';
55

66
import { inject, injectable } from 'inversify';
7-
import { IPersistentStateFactory } from '../common/types';
8-
import { IServiceContainer } from '../ioc/types';
9-
import { FolderVersionPair, IDownloadChannelRule } from './types';
7+
import { IPersistentStateFactory } from '../../common/types';
8+
import { IServiceContainer } from '../../ioc/types';
9+
import { FolderVersionPair, IDownloadChannelRule } from '../types';
1010

1111
const lastCheckedForLSDateTimeCacheKey = 'LS.LAST.CHECK.TIME';
1212
const frequencyForBetalLSDownloadCheck = 1000 * 60 * 60 * 24; // One day.

src/client/activation/downloader.ts renamed to src/client/activation/languageServer/downloader.ts

Lines changed: 190 additions & 189 deletions
Large diffs are not rendered by default.

src/client/activation/interpreterDataService.ts renamed to src/client/activation/languageServer/interpreterDataService.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
'use strict';
5+
46
import { createHash } from 'crypto';
57
import * as fs from 'fs';
68
import { inject, injectable } from 'inversify';
79
import * as path from 'path';
8-
import { IApplicationShell } from '../common/application/types';
9-
import '../common/extensions';
10-
import { IPlatformService } from '../common/platform/types';
11-
import { IPythonExecutionFactory, IPythonExecutionService } from '../common/process/types';
12-
import { IExtensionContext, Resource } from '../common/types';
13-
import { createDeferred } from '../common/utils/async';
14-
import { IServiceContainer } from '../ioc/types';
15-
import { IInterpreterDataService, InterpreterData } from './types';
10+
import { IApplicationShell } from '../../common/application/types';
11+
import '../../common/extensions';
12+
import { IPlatformService } from '../../common/platform/types';
13+
import { IPythonExecutionFactory, IPythonExecutionService } from '../../common/process/types';
14+
import { IExtensionContext, Resource } from '../../common/types';
15+
import { createDeferred } from '../../common/utils/async';
16+
import { LanguageService } from '../../common/utils/localize';
17+
import { IServiceContainer } from '../../ioc/types';
18+
import { IInterpreterDataService, InterpreterData } from '../types';
1619

1720
const DataVersion = 1;
1821
class InterpreterDataCls {
@@ -137,7 +140,7 @@ export class InterpreterDataService implements IInterpreterDataService {
137140
if (paths !== currentPaths) {
138141
this.context.globalState.update(interpreterPath, undefined);
139142
const appShell = this.serviceContainer.get<IApplicationShell>(IApplicationShell);
140-
await appShell.showWarningMessage('Search paths have changed for this Python interpreter. Please reload the extension to ensure that the IntelliSense works correctly.');
143+
await appShell.showWarningMessage(LanguageService.reloadVSCodeIfSeachPathHasChanged());
141144
}
142145
}).ignoreErrors();
143146
}

src/client/activation/languageServer/languageServer.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import { createDeferred, Deferred, sleep } from '../../common/utils/async';
1212
import { noop } from '../../common/utils/misc';
1313
import { captureTelemetry, sendTelemetryEvent } from '../../telemetry';
1414
import { EventName } from '../../telemetry/constants';
15-
import { ProgressReporting } from '../progress';
16-
import { ILanaguageServer as ILanguageServer, ILanguageClientFactory, LanguageClientFactory } from '../types';
15+
import { ILanguageClientFactory, ILanguageServer, LanguageClientFactory } from '../types';
16+
import { ProgressReporting } from './progress';
1717

1818
@injectable()
1919
export class LanguageServer implements ILanguageServer {

src/client/activation/languageServer/manager.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,21 @@ import { debounce } from '../../common/utils/decorators';
1111
import { IServiceContainer } from '../../ioc/types';
1212
import { captureTelemetry } from '../../telemetry';
1313
import { EventName } from '../../telemetry/constants';
14-
import { ILanaguageServer, ILanguageServerAnalysisOptions, ILanguageServerManager } from '../types';
14+
import { ILanguageServer, ILanguageServerAnalysisOptions, ILanguageServerManager } from '../types';
1515

1616
const loadExtensionCommand = 'python._loadLanguageServerExtension';
1717

1818
@injectable()
1919
export class LanguageServerManager implements ILanguageServerManager {
2020
protected static loadExtensionArgs?: {};
21-
private languageServer?: ILanaguageServer;
21+
private languageServer?: ILanguageServer;
2222
private resource!: Resource;
2323
private disposables: IDisposable[] = [];
2424
constructor(
2525
@inject(IServiceContainer) private readonly serviceContainer: IServiceContainer,
2626
@inject(ICommandManager) private readonly commandManager: ICommandManager,
27-
@inject(ILanguageServerAnalysisOptions) private readonly analysisOptions: ILanguageServerAnalysisOptions) { }
27+
@inject(ILanguageServerAnalysisOptions) private readonly analysisOptions: ILanguageServerAnalysisOptions
28+
) {}
2829
public dispose() {
2930
if (this.languageServer) {
3031
this.languageServer.dispose();
@@ -67,7 +68,7 @@ export class LanguageServerManager implements ILanguageServerManager {
6768
@captureTelemetry(EventName.PYTHON_LANGUAGE_SERVER_STARTUP, undefined, true)
6869
@traceDecorators.verbose('Starting Language Server')
6970
protected async startLanguageServer(): Promise<void> {
70-
this.languageServer = this.serviceContainer.get<ILanaguageServer>(ILanaguageServer);
71+
this.languageServer = this.serviceContainer.get<ILanguageServer>(ILanguageServer);
7172
const options = await this.analysisOptions!.getAnalysisOptions();
7273
await this.languageServer.start(this.resource, options);
7374
this.loadExtensionIfNecessary();
Lines changed: 57 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,57 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
2-
// Licensed under the MIT License.
3-
4-
import { inject, injectable } from 'inversify';
5-
import { IPlatformService } from '../common/platform/types';
6-
import { IPlatformData } from './types';
7-
8-
export enum PlatformName {
9-
Windows32Bit = 'win-x86',
10-
Windows64Bit = 'win-x64',
11-
Mac64Bit = 'osx-x64',
12-
Linux64Bit = 'linux-x64'
13-
}
14-
15-
export enum PlatformLSExecutables {
16-
Windows = 'Microsoft.Python.LanguageServer.exe',
17-
MacOS = 'Microsoft.Python.LanguageServer',
18-
Linux = 'Microsoft.Python.LanguageServer'
19-
}
20-
21-
@injectable()
22-
export class PlatformData implements IPlatformData {
23-
constructor(@inject(IPlatformService) private readonly platform: IPlatformService) { }
24-
public get platformName(): PlatformName {
25-
if (this.platform.isWindows) {
26-
return this.platform.is64bit ? PlatformName.Windows64Bit : PlatformName.Windows32Bit;
27-
}
28-
if (this.platform.isMac) {
29-
return PlatformName.Mac64Bit;
30-
}
31-
if (this.platform.isLinux) {
32-
if (!this.platform.is64bit) {
33-
throw new Error('Microsoft Python Language Server does not support 32-bit Linux.');
34-
}
35-
return PlatformName.Linux64Bit;
36-
}
37-
throw new Error('Unknown OS platform.');
38-
}
39-
40-
public get engineDllName(): string {
41-
return 'Microsoft.Python.LanguageServer.dll';
42-
}
43-
44-
public get engineExecutableName(): string {
45-
if (this.platform.isWindows) {
46-
return PlatformLSExecutables.Windows;
47-
} else if (this.platform.isLinux) {
48-
return PlatformLSExecutables.Linux;
49-
} else if (this.platform.isMac) {
50-
return PlatformLSExecutables.MacOS;
51-
} else {
52-
return 'unknown-platform';
53-
}
54-
}
55-
}
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
import { inject, injectable } from 'inversify';
7+
import { IPlatformService } from '../../common/platform/types';
8+
import { IPlatformData } from '../types';
9+
10+
export enum PlatformName {
11+
Windows32Bit = 'win-x86',
12+
Windows64Bit = 'win-x64',
13+
Mac64Bit = 'osx-x64',
14+
Linux64Bit = 'linux-x64'
15+
}
16+
17+
export enum PlatformLSExecutables {
18+
Windows = 'Microsoft.Python.LanguageServer.exe',
19+
MacOS = 'Microsoft.Python.LanguageServer',
20+
Linux = 'Microsoft.Python.LanguageServer'
21+
}
22+
23+
@injectable()
24+
export class PlatformData implements IPlatformData {
25+
constructor(@inject(IPlatformService) private readonly platform: IPlatformService) { }
26+
public get platformName(): PlatformName {
27+
if (this.platform.isWindows) {
28+
return this.platform.is64bit ? PlatformName.Windows64Bit : PlatformName.Windows32Bit;
29+
}
30+
if (this.platform.isMac) {
31+
return PlatformName.Mac64Bit;
32+
}
33+
if (this.platform.isLinux) {
34+
if (!this.platform.is64bit) {
35+
throw new Error('Microsoft Python Language Server does not support 32-bit Linux.');
36+
}
37+
return PlatformName.Linux64Bit;
38+
}
39+
throw new Error('Unknown OS platform.');
40+
}
41+
42+
public get engineDllName(): string {
43+
return 'Microsoft.Python.LanguageServer.dll';
44+
}
45+
46+
public get engineExecutableName(): string {
47+
if (this.platform.isWindows) {
48+
return PlatformLSExecutables.Windows;
49+
} else if (this.platform.isLinux) {
50+
return PlatformLSExecutables.Linux;
51+
} else if (this.platform.isMac) {
52+
return PlatformLSExecutables.MacOS;
53+
} else {
54+
return 'unknown-platform';
55+
}
56+
}
57+
}

src/client/activation/progress.ts renamed to src/client/activation/languageServer/progress.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
'use strict';
5+
46
import { Progress, ProgressLocation, window } from 'vscode';
57
import { Disposable, LanguageClient } from 'vscode-languageclient';
6-
import { createDeferred, Deferred } from '../common/utils/async';
7-
import { StopWatch } from '../common/utils/stopWatch';
8-
import { sendTelemetryEvent } from '../telemetry';
9-
import { EventName } from '../telemetry/constants';
8+
import { createDeferred, Deferred } from '../../common/utils/async';
9+
import { StopWatch } from '../../common/utils/stopWatch';
10+
import { sendTelemetryEvent } from '../../telemetry';
11+
import { EventName } from '../../telemetry/constants';
1012

1113
// Draw the line at Language Server analysis 'timing out'
1214
// and becoming a failure-case at 1 minute:

src/client/activation/serviceRegistry.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@ import { IServiceManager } from '../ioc/types';
1010
import { LanguageServerSurveyBanner } from '../languageServices/languageServerSurveyBanner';
1111
import { ProposeLanguageServerBanner } from '../languageServices/proposeLanguageServerBanner';
1212
import { ExtensionActivationService } from './activationService';
13-
import { DownloadBetaChannelRule, DownloadDailyChannelRule, DownloadStableChannelRule } from './downloadChannelRules';
14-
import { LanguageServerDownloader } from './downloader';
15-
import { InterpreterDataService } from './interpreterDataService';
1613
import { JediExtensionActivator } from './jedi';
1714
import { LanguageServerExtensionActivator } from './languageServer/activator';
1815
import { LanguageServerAnalysisOptions } from './languageServer/analysisOptions';
16+
import { DownloadBetaChannelRule, DownloadDailyChannelRule, DownloadStableChannelRule } from './languageServer/downloadChannelRules';
17+
import { LanguageServerDownloader } from './languageServer/downloader';
18+
import { InterpreterDataService } from './languageServer/interpreterDataService';
1919
import { BaseLanguageClientFactory, DownloadedLanguageClientFactory, SimpleLanguageClientFactory } from './languageServer/languageClientFactory';
2020
import { LanguageServer } from './languageServer/languageServer';
2121
import { LanguageServerCompatibilityService } from './languageServer/languageServerCompatibilityService';
2222
import { LanguageServerFolderService } from './languageServer/languageServerFolderService';
2323
import { BetaLanguageServerPackageRepository, DailyLanguageServerPackageRepository, LanguageServerDownloadChannel, StableLanguageServerPackageRepository } from './languageServer/languageServerPackageRepository';
2424
import { LanguageServerPackageService } from './languageServer/languageServerPackageService';
2525
import { LanguageServerManager } from './languageServer/manager';
26-
import { PlatformData } from './platformData';
27-
import { ExtensionActivators, IDownloadChannelRule, IExtensionActivationService, IExtensionActivator, IInterpreterDataService, ILanaguageServer, ILanguageClientFactory, ILanguageServerAnalysisOptions, ILanguageServerCompatibilityService as ILanagueServerCompatibilityService, ILanguageServerDownloader, ILanguageServerFolderService, ILanguageServerManager, ILanguageServerPackageService, IPlatformData, LanguageClientFactory } from './types';
26+
import { PlatformData } from './languageServer/platformData';
27+
import { ExtensionActivators, IDownloadChannelRule, IExtensionActivationService, IExtensionActivator, IInterpreterDataService, ILanguageClientFactory, ILanguageServer, ILanguageServerAnalysisOptions, ILanguageServerCompatibilityService as ILanagueServerCompatibilityService, ILanguageServerDownloader, ILanguageServerFolderService, ILanguageServerManager, ILanguageServerPackageService, IPlatformData, LanguageClientFactory } from './types';
2828

2929
export function registerTypes(serviceManager: IServiceManager) {
3030
serviceManager.addSingleton<IExtensionActivationService>(IExtensionActivationService, ExtensionActivationService);
@@ -49,6 +49,6 @@ export function registerTypes(serviceManager: IServiceManager) {
4949
serviceManager.addSingleton<ILanguageServerDownloader>(ILanguageServerDownloader, LanguageServerDownloader);
5050
serviceManager.addSingleton<IPlatformData>(IPlatformData, PlatformData);
5151
serviceManager.add<ILanguageServerAnalysisOptions>(ILanguageServerAnalysisOptions, LanguageServerAnalysisOptions);
52-
serviceManager.add<ILanaguageServer>(ILanaguageServer, LanguageServer);
52+
serviceManager.add<ILanguageServer>(ILanguageServer, LanguageServer);
5353
serviceManager.add<ILanguageServerManager>(ILanguageServerManager, LanguageServerManager);
5454
}

src/client/activation/types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ export const ILanguageServerManager = Symbol('ILanguageServerManager');
8282
export interface ILanguageServerManager extends IDisposable {
8383
start(resource: Resource): Promise<void>;
8484
}
85-
export const ILanaguageServer = Symbol('ILanaguageServer');
86-
export interface ILanaguageServer extends IDisposable {
85+
export const ILanguageServer = Symbol('ILanguageServer');
86+
export interface ILanguageServer extends IDisposable {
8787
start(resource: Resource, options: LanguageClientOptions): Promise<void>;
8888
/**
8989
* Sends a request to LS so as to load other extensions.
9090
* This is used as a plugin loader mechanism.
9191
* Anyone (such as intellicode) wanting to interact with LS, needs to send this request to LS.
9292
* @param {{}} [args]
93-
* @memberof ILanaguageServer
93+
* @memberof ILanguageServer
9494
*/
9595
loadExtension(args?: {}): void;
9696
}

0 commit comments

Comments
 (0)