Skip to content

Commit 9b8a62e

Browse files
committed
disable language services if Pyrefly extension installed + active
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags:
1 parent c3f601d commit 9b8a62e

File tree

6 files changed

+64
-10
lines changed

6 files changed

+64
-10
lines changed

src/client/activation/common/defaultlanguageServer.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Licensed under the MIT License.
33

44
import { injectable } from 'inversify';
5-
import { PYLANCE_EXTENSION_ID } from '../../common/constants';
5+
import { PYLANCE_EXTENSION_ID, PYREFLY_EXTENSION_ID } from '../../common/constants';
66
import { IDefaultLanguageServer, IExtensions, DefaultLSType } from '../../common/types';
77
import { IServiceManager } from '../../ioc/types';
88
import { LanguageServerType } from '../types';
@@ -28,9 +28,13 @@ export async function setDefaultLanguageServer(
2828
}
2929

3030
async function getDefaultLanguageServer(extensions: IExtensions): Promise<DefaultLSType> {
31+
let type = LanguageServerType.Jedi;
3132
if (extensions.getExtension(PYLANCE_EXTENSION_ID)) {
32-
return LanguageServerType.Node;
33+
type = LanguageServerType.Node;
3334
}
34-
35-
return LanguageServerType.Jedi;
35+
36+
if (extensions.getExtension(PYREFLY_EXTENSION_ID)) {
37+
return {type: "none or (if pyrefly language services disabled)", languageServerType: type};
38+
}
39+
return {type: "always", languageServerType: type};
3640
}

src/client/common/configSettings.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,14 +268,29 @@ export class PythonSettings implements IPythonSettings {
268268
let userLS = pythonSettings.get<string>('languageServer');
269269
userLS = systemVariables.resolveAny(userLS);
270270

271+
// Default language server type: if `IDefaultLanguageServer?.defaultLSType` is undefined, default to `None`.
272+
let defaultLS = LanguageServerType.None;
273+
274+
let defaultLSType = this.defaultLS?.defaultLSType;
275+
if (defaultLSType !== undefined) {
276+
// If we are sure what to default the language server type to, use it.
277+
if (defaultLSType.type === "always") {
278+
defaultLS = defaultLSType.languageServerType;
279+
}
280+
// If Pyrefly extension is installed, keep defaultLS = None unless Pyrefly has disabled language services.
281+
else if (defaultLSType.type === "none or (if pyrefly language services disabled)" && pythonSettings.get<WorkspaceConfiguration>('pyrefly')?.get<boolean>('disableLanguageServices') !== true) {
282+
defaultLS = defaultLSType.languageServerType;
283+
}
284+
}
285+
271286
// Validate the user's input; if invalid, set it to the default.
272-
if (
287+
else if (
273288
!userLS ||
274289
userLS === 'Default' ||
275290
userLS === 'Microsoft' ||
276291
!Object.values(LanguageServerType).includes(userLS as LanguageServerType)
277292
) {
278-
this.languageServer = this.defaultLS?.defaultLSType ?? LanguageServerType.None;
293+
this.languageServer = defaultLS;
279294
this.languageServerIsDefault = true;
280295
} else if (userLS === 'JediLSP') {
281296
// Switch JediLSP option to Jedi.

src/client/common/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export const PYTHON_NOTEBOOKS = [
2222

2323
export const PVSC_EXTENSION_ID = 'ms-python.python';
2424
export const PYLANCE_EXTENSION_ID = 'ms-python.vscode-pylance';
25+
export const PYREFLY_EXTENSION_ID = 'meta.pyrefly';
2526
export const JUPYTER_EXTENSION_ID = 'ms-toolsai.jupyter';
2627
export const TENSORBOARD_EXTENSION_ID = 'ms-toolsai.tensorboard';
2728
export const AppinsightsKey = '0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255';

src/client/common/types.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,22 @@ export interface IInterpreterPathService {
348348
copyOldInterpreterStorageValuesToNew(resource: Resource): Promise<void>;
349349
}
350350

351-
export type DefaultLSType = LanguageServerType.Jedi | LanguageServerType.Node;
351+
/**
352+
* If Pyrefly extension is installed, LS default should be `None`. But if Pyrefly language services are disabled,
353+
* fall back to T.
354+
*/
355+
export type PyreflyOr<T extends LanguageServerType> = {
356+
type: 'none or (if pyrefly language services disabled)',
357+
languageServerType: T,
358+
};
359+
360+
export type Always<T extends LanguageServerType> = {
361+
type: 'always',
362+
languageServerType: T,
363+
};
364+
365+
type DefaultLSTypes = LanguageServerType.Jedi | LanguageServerType.Node;
366+
export type DefaultLSType = Always<DefaultLSTypes> | PyreflyOr<DefaultLSTypes>;
352367

353368
/**
354369
* Interface used to retrieve the default language server.

src/client/languageServer/watcher.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,8 @@ export class LanguageServerWatcher implements IExtensionActivationService, ILang
297297
await this.refreshLanguageServer(resource);
298298
} else if (event.affectsConfiguration(`python.analysis.pylanceLspClientEnabled`, resource)) {
299299
await this.refreshLanguageServer(resource, /* forced */ true);
300+
} else if (event.affectsConfiguration('python.pyrefly.languageServer', resource)) {
301+
await this.refreshLanguageServer(resource);
300302
}
301303
});
302304
}

src/test/activation/defaultLanguageServer.unit.test.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { anything, instance, mock, when, verify } from 'ts-mockito';
88
import { Extension } from 'vscode';
99
import { setDefaultLanguageServer } from '../../client/activation/common/defaultlanguageServer';
1010
import { LanguageServerType } from '../../client/activation/types';
11-
import { PYLANCE_EXTENSION_ID } from '../../client/common/constants';
11+
import { PYLANCE_EXTENSION_ID, PYREFLY_EXTENSION_ID } from '../../client/common/constants';
1212
import { IDefaultLanguageServer, IExtensions } from '../../client/common/types';
1313
import { ServiceManager } from '../../client/ioc/serviceManager';
1414
import { IServiceManager } from '../../client/ioc/types';
@@ -37,7 +37,7 @@ suite('Activation - setDefaultLanguageServer()', () => {
3737

3838
verify(extensions.getExtension(PYLANCE_EXTENSION_ID)).once();
3939
verify(serviceManager.addSingletonInstance<IDefaultLanguageServer>(IDefaultLanguageServer, anything())).once();
40-
expect(defaultServerType).to.equal(LanguageServerType.Jedi);
40+
expect(defaultServerType).to.deep.equal({type: "always", languageServerType: LanguageServerType.Jedi});
4141
});
4242

4343
test('Pylance installed', async () => {
@@ -54,6 +54,23 @@ suite('Activation - setDefaultLanguageServer()', () => {
5454

5555
verify(extensions.getExtension(PYLANCE_EXTENSION_ID)).once();
5656
verify(serviceManager.addSingletonInstance<IDefaultLanguageServer>(IDefaultLanguageServer, anything())).once();
57-
expect(defaultServerType).to.equal(LanguageServerType.Node);
57+
expect(defaultServerType).to.deep.equal({type: "always", languageServerType: LanguageServerType.Node});
58+
});
59+
60+
test('Pyrefly installed', async () => {
61+
let defaultServerType;
62+
63+
when(extensions.getExtension(PYREFLY_EXTENSION_ID)).thenReturn(instance(extension));
64+
when(serviceManager.addSingletonInstance<IDefaultLanguageServer>(IDefaultLanguageServer, anything())).thenCall(
65+
(_symbol, value: IDefaultLanguageServer) => {
66+
defaultServerType = value.defaultLSType;
67+
},
68+
);
69+
70+
await setDefaultLanguageServer(instance(extensions), instance(serviceManager));
71+
72+
verify(extensions.getExtension(PYREFLY_EXTENSION_ID)).once();
73+
verify(serviceManager.addSingletonInstance<IDefaultLanguageServer>(IDefaultLanguageServer, anything())).once();
74+
expect(defaultServerType).to.deep.equal({type: "none or (if pyrefly language services disabled)", languageServerType: LanguageServerType.Jedi});
5875
});
5976
});

0 commit comments

Comments
 (0)