From 8c5d8b90bffe4c5530901176585be0adc60894e2 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 24 Sep 2021 17:12:14 -0700 Subject: [PATCH 01/18] Only activate Pylance when running in virtual workspaces --- package.json | 3 +- package.nls.json | 1 + src/client/activation/activationManager.ts | 38 ++++--- src/client/activation/activationService.ts | 23 ++++- src/client/activation/serviceRegistry.ts | 2 + src/client/activation/types.ts | 3 + src/client/common/application/types.ts | 5 +- src/client/common/application/workspace.ts | 6 ++ src/client/common/utils/localize.ts | 4 + src/client/extension.ts | 29 ++++-- src/client/extensionActivation.ts | 99 ++++++++++--------- src/client/extensionInit.ts | 8 +- .../common/testConfigurationManager.ts | 8 +- .../testing/testController/controller.ts | 5 +- .../testing/testController/serviceRegistry.ts | 2 + .../activation/activationManager.unit.test.ts | 12 ++- 16 files changed, 165 insertions(+), 83 deletions(-) diff --git a/package.json b/package.json index 700dd23424af..15aa61740bd3 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ }, "capabilities": { "untrustedWorkspaces": { - "supported": false + "supported": "limited", + "description": "Only intellisense with Pylance is supported. Cannot execute Python with untrusted files." }, "virtualWorkspaces": { "supported": false, diff --git a/package.nls.json b/package.nls.json index 1e980bdaaa9c..9e9de8c725e6 100644 --- a/package.nls.json +++ b/package.nls.json @@ -180,6 +180,7 @@ "LanguageService.startingJedi": "Starting Jedi language server.", "LanguageService.startingNone": "Editor support is inactive since language server is set to None.", "LanguageService.reloadAfterLanguageServerChange": "Please reload the window switching between language servers.", + "LanguageService.virtualWorkspaceMessage": "Only Pylance is supported when running in virtual workspaces, setting language server to None.", "AttachProcess.unsupportedOS": "Operating system '{0}' not supported.", "AttachProcess.attachTitle": "Attach to process", "AttachProcess.selectProcessPlaceholder": "Select the process to attach to", diff --git a/src/client/activation/activationManager.ts b/src/client/activation/activationManager.ts index ade44d630004..9b998fa00eb7 100644 --- a/src/client/activation/activationManager.ts +++ b/src/client/activation/activationManager.ts @@ -15,7 +15,12 @@ import { Deferred } from '../common/utils/async'; import { IInterpreterAutoSelectionService } from '../interpreter/autoSelection/types'; import { traceDecoratorError } from '../logging'; import { sendActivationTelemetry } from '../telemetry/envFileTelemetry'; -import { IExtensionActivationManager, IExtensionActivationService, IExtensionSingleActivationService } from './types'; +import { + IExtensionActivationManager, + IExtensionActivationService, + IExtensionSingleActivationService, + ILanguageServerActivation, +} from './types'; @injectable() export class ExtensionActivationManager implements IExtensionActivationManager { @@ -39,6 +44,7 @@ export class ExtensionActivationManager implements IExtensionActivationManager { @inject(IActiveResourceService) private readonly activeResourceService: IActiveResourceService, @inject(IExperimentService) private readonly experiments: IExperimentService, @inject(IInterpreterPathService) private readonly interpreterPathService: IInterpreterPathService, + @inject(ILanguageServerActivation) private readonly languageServerActivation: ILanguageServerActivation, ) {} public dispose(): void { @@ -56,10 +62,15 @@ export class ExtensionActivationManager implements IExtensionActivationManager { await this.initialize(); // Activate all activation services together. - await Promise.all([ - Promise.all(this.singleActivationServices.map((item) => item.activate())), - this.activateWorkspace(this.activeResourceService.getActiveResource()), - ]); + + if (this.workspaceService.isVirtualWorkspace) { + await this.activateWorkspace(this.activeResourceService.getActiveResource()); + } else { + await Promise.all([ + Promise.all(this.singleActivationServices.map((item) => item.activate())), + this.activateWorkspace(this.activeResourceService.getActiveResource()), + ]); + } } @traceDecoratorError('Failed to activate a workspace') @@ -70,15 +81,18 @@ export class ExtensionActivationManager implements IExtensionActivationManager { } this.activatedWorkspaces.add(key); - if (this.experiments.inExperimentSync(DeprecatePythonPath.experiment)) { - await this.interpreterPathService.copyOldInterpreterStorageValuesToNew(resource); - } - await sendActivationTelemetry(this.fileSystem, this.workspaceService, resource); - await this.autoSelection.autoSelectInterpreter(resource); - await Promise.all(this.activationServices.map((item) => item.activate(resource))); - await this.appDiagnostics.performPreStartupHealthCheck(resource); + if (this.workspaceService.isVirtualWorkspace) { + await this.languageServerActivation.activate(resource); + } else { + if (this.experiments.inExperimentSync(DeprecatePythonPath.experiment)) { + await this.interpreterPathService.copyOldInterpreterStorageValuesToNew(resource); + } + await this.autoSelection.autoSelectInterpreter(resource); + await Promise.all(this.activationServices.map((item) => item.activate(resource))); + await this.appDiagnostics.performPreStartupHealthCheck(resource); + } } public async initialize(): Promise { diff --git a/src/client/activation/activationService.ts b/src/client/activation/activationService.ts index ef99d9780caa..3b8c31bae48e 100644 --- a/src/client/activation/activationService.ts +++ b/src/client/activation/activationService.ts @@ -55,7 +55,7 @@ export class LanguageServerExtensionActivationService private readonly output: OutputChannel; - private readonly interpreterService: IInterpreterService; + private readonly interpreterService?: IInterpreterService; private readonly languageServerChangeHandler: LanguageServerChangeHandler; @@ -67,14 +67,18 @@ export class LanguageServerExtensionActivationService ) { this.workspaceService = this.serviceContainer.get(IWorkspaceService); this.configurationService = this.serviceContainer.get(IConfigurationService); - this.interpreterService = this.serviceContainer.get(IInterpreterService); + if (!this.workspaceService.isVirtualWorkspace) { + this.interpreterService = this.serviceContainer.get(IInterpreterService); + } this.output = this.serviceContainer.get(IOutputChannel, STANDARD_OUTPUT_CHANNEL); const disposables = serviceContainer.get(IDisposableRegistry); disposables.push(this); disposables.push(this.workspaceService.onDidChangeConfiguration(this.onDidChangeConfiguration.bind(this))); disposables.push(this.workspaceService.onDidChangeWorkspaceFolders(this.onWorkspaceFoldersChanged, this)); - disposables.push(this.interpreterService.onDidChangeInterpreter(this.onDidChangeInterpreter.bind(this))); + if (this.interpreterService) { + disposables.push(this.interpreterService.onDidChangeInterpreter(this.onDidChangeInterpreter.bind(this))); + } this.languageServerChangeHandler = new LanguageServerChangeHandler( this.getCurrentLanguageServerType(), @@ -91,7 +95,7 @@ export class LanguageServerExtensionActivationService const stopWatch = new StopWatch(); // Get a new server and dispose of the old one (might be the same one) this.resource = resource; - const interpreter = await this.interpreterService.getActiveInterpreter(resource); + const interpreter = await this.interpreterService?.getActiveInterpreter(resource); const key = await this.getKey(resource, interpreter); // If we have an old server with a different key, then deactivate it as the @@ -235,11 +239,20 @@ export class LanguageServerExtensionActivationService this.sendTelemetryForChosenLanguageServer(serverType).ignoreErrors(); + if (this.workspaceService.isVirtualWorkspace && serverType !== LanguageServerType.Node) { + // Only Node is supported when using virtual workspaces. + this.output.appendLine(LanguageService.virtualWorkspaceMessage()); + serverType = LanguageServerType.None; + } + await this.logStartup(serverType); let server = this.serviceContainer.get(ILanguageServerActivator, serverType); try { await server.start(resource, interpreter); } catch (ex) { + if (this.workspaceService.isVirtualWorkspace) { + throw ex; + } if (serverType === LanguageServerType.Jedi) { throw ex; } @@ -304,7 +317,7 @@ export class LanguageServerExtensionActivationService resource, workspacePathNameForGlobalWorkspaces, ); - interpreter = interpreter || (await this.interpreterService.getActiveInterpreter(resource)); + interpreter = interpreter || (await this.interpreterService?.getActiveInterpreter(resource)); const interperterPortion = interpreter ? `${interpreter.path}-${interpreter.envName}` : ''; return `${resourcePortion}-${interperterPortion}`; } diff --git a/src/client/activation/serviceRegistry.ts b/src/client/activation/serviceRegistry.ts index c865307d8aa2..c5df85de7c00 100644 --- a/src/client/activation/serviceRegistry.ts +++ b/src/client/activation/serviceRegistry.ts @@ -22,6 +22,7 @@ import { IExtensionActivationService, IExtensionSingleActivationService, ILanguageClientFactory, + ILanguageServerActivation, ILanguageServerActivator, ILanguageServerAnalysisOptions, ILanguageServerCache, @@ -37,6 +38,7 @@ import { LoadLanguageServerExtension } from './common/loadLanguageServerExtensio export function registerTypes(serviceManager: IServiceManager, languageServerType: LanguageServerType): void { serviceManager.addSingleton(ILanguageServerCache, LanguageServerExtensionActivationService); serviceManager.addBinding(ILanguageServerCache, IExtensionActivationService); + serviceManager.addBinding(ILanguageServerCache, ILanguageServerActivation); serviceManager.add(IExtensionActivationManager, ExtensionActivationManager); serviceManager.add( ILanguageServerActivator, diff --git a/src/client/activation/types.ts b/src/client/activation/types.ts index d2f0d727d0cb..5c08ee0c1be4 100644 --- a/src/client/activation/types.ts +++ b/src/client/activation/types.ts @@ -104,6 +104,9 @@ export interface ILanguageServerCache { get(resource: Resource, interpreter?: PythonEnvironment): Promise; } +export const ILanguageServerActivation = Symbol('ILanguageServerActivation'); +export interface ILanguageServerActivation extends IExtensionActivationService {} + export type FolderVersionPair = { path: string; version: SemVer }; export const ILanguageServerFolderService = Symbol('ILanguageServerFolderService'); diff --git a/src/client/common/application/types.ts b/src/client/common/application/types.ts index eac770efafa6..ec5c7dcf5cab 100644 --- a/src/client/common/application/types.ts +++ b/src/client/common/application/types.ts @@ -729,7 +729,10 @@ export interface IWorkspaceService { * @memberof IWorkspaceService */ readonly hasWorkspaceFolders: boolean; - + /** + * Returns if we're running in a virtual workspace. + */ + readonly isVirtualWorkspace: boolean; /** * Returns the [workspace folder](#WorkspaceFolder) that contains a given uri. * * returns `undefined` when the given uri doesn't match any workspace folder diff --git a/src/client/common/application/workspace.ts b/src/client/common/application/workspace.ts index f3eb57c6156c..5ef4870a8808 100644 --- a/src/client/common/application/workspace.ts +++ b/src/client/common/application/workspace.ts @@ -83,6 +83,12 @@ export class WorkspaceService implements IWorkspaceService { : defaultValue; } + public get isVirtualWorkspace(): boolean { + const isVirtualWorkspace = + workspace.workspaceFolders && workspace.workspaceFolders.every((f) => f.uri.scheme !== 'file'); + return !!isVirtualWorkspace; + } + private get searchExcludes() { const searchExcludes = this.getConfiguration('search.exclude'); const enabledSearchExcludes = Object.keys(searchExcludes).filter((key) => searchExcludes.get(key) === true); diff --git a/src/client/common/utils/localize.ts b/src/client/common/utils/localize.ts index 1b245a896f89..ce821f065949 100644 --- a/src/client/common/utils/localize.ts +++ b/src/client/common/utils/localize.ts @@ -206,6 +206,10 @@ export namespace TensorBoard { export namespace LanguageService { export const startingPylance = localize('LanguageService.startingPylance', 'Starting Pylance language server.'); export const startingJedi = localize('LanguageService.startingJedi', 'Starting Jedi language server.'); + export const virtualWorkspaceMessage = localize( + 'LanguageService.virtualWorkspaceMessage', + 'Only Pylance is supported when running in virtual workspaces, setting language server to None.', + ); export const startingNone = localize( 'LanguageService.startingNone', 'Editor support is inactive since language server is set to None.', diff --git a/src/client/extension.ts b/src/client/extension.ts index 500a8ecd826a..c6260d363fa8 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -42,6 +42,7 @@ import { sendErrorTelemetry, sendStartupTelemetry } from './startupTelemetry'; import { IStartupDurations } from './types'; import { runAfterActivation } from './common/utils/runAfterActivation'; import { IInterpreterService } from './interpreter/contracts'; +import { WorkspaceService } from './common/application/workspace'; durations.codeLoadingTime = stopWatch.elapsedTime; @@ -68,9 +69,13 @@ export async function activate(context: IExtensionContext): Promise { if (activatedServiceContainer) { - const interpreterManager = activatedServiceContainer.get(IInterpreterService); const workspaceService = activatedServiceContainer.get(IWorkspaceService); - const workspaces = workspaceService.workspaceFolders ?? []; - await interpreterManager - .refresh(workspaces.length > 0 ? workspaces[0].uri : undefined) - .catch((ex) => traceError('Python Extension: interpreterManager.refresh', ex)); + if (!workspaceService.isVirtualWorkspace) { + const interpreterManager = activatedServiceContainer.get(IInterpreterService); + const workspaces = workspaceService.workspaceFolders ?? []; + await interpreterManager + .refresh(workspaces.length > 0 ? workspaces[0].uri : undefined) + .catch((ex) => traceError('Python Extension: interpreterManager.refresh', ex)); + } } runAfterActivation(); @@ -159,7 +166,11 @@ async function handleError(ex: Error, startupDurations: IStartupDurations) { "Extension activation failed, run the 'Developer: Toggle Developer Tools' command for more information.", ); traceError('extension activation failed', ex); - await sendErrorTelemetry(ex, startupDurations, activatedServiceContainer); + + const workspace = new WorkspaceService(); + if (!workspace.isVirtualWorkspace) { + await sendErrorTelemetry(ex, startupDurations, activatedServiceContainer); + } } interface IAppShell { diff --git a/src/client/extensionActivation.ts b/src/client/extensionActivation.ts index 52abe2d840e4..7a216b39d3ff 100644 --- a/src/client/extensionActivation.ts +++ b/src/client/extensionActivation.ts @@ -9,16 +9,13 @@ import { registerTypes as activationRegisterTypes } from './activation/serviceRe import { IExtensionActivationManager } from './activation/types'; import { registerTypes as appRegisterTypes } from './application/serviceRegistry'; import { IApplicationDiagnostics } from './application/types'; -import { DebugService } from './common/application/debugService'; -import { IApplicationEnvironment, ICommandManager } from './common/application/types'; +import { IApplicationEnvironment, ICommandManager, IWorkspaceService } from './common/application/types'; import { Commands, PYTHON, PYTHON_LANGUAGE, STANDARD_OUTPUT_CHANNEL, UseProposedApi } from './common/constants'; import { registerTypes as installerRegisterTypes } from './common/installer/serviceRegistry'; import { IFileSystem } from './common/platform/types'; import { IConfigurationService, IDisposableRegistry, IExtensions, IOutputChannel } from './common/types'; import { noop } from './common/utils/misc'; import { DebuggerTypeName } from './debugger/constants'; -import { DebugSessionEventDispatcher } from './debugger/extension/hooks/eventHandlerDispatcher'; -import { IDebugSessionEventHandlers } from './debugger/extension/hooks/types'; import { registerTypes as debugConfigurationRegisterTypes } from './debugger/extension/serviceRegistry'; import { IDebugConfigurationService, IDebuggerBanner } from './debugger/extension/types'; import { registerTypes as formattersRegisterTypes } from './formatters/serviceRegistry'; @@ -70,6 +67,11 @@ export async function activateComponents( // https://github.com/microsoft/vscode-python/issues/15380 // These will go away eventually once everything is refactored into components. const legacyActivationResult = await activateLegacy(ext); + const workspaceService = ext.legacyIOC.serviceContainer.get(IWorkspaceService); + if (workspaceService.isVirtualWorkspace) { + // Nothing other than Pylance is activated when using virtual workspaces. + return [legacyActivationResult]; + } const promises: Promise[] = [ // More component activations will go here pythonEnvironments.activate(components.pythonEnvs, ext), @@ -128,66 +130,71 @@ async function activateLegacy(ext: ExtensionState): Promise { // "initialize" "services" - const interpreterManager = serviceContainer.get(IInterpreterService); - interpreterManager.initialize(); - - const handlers = serviceManager.getAll(IDebugSessionEventHandlers); + serviceContainer.get(ILanguageServerExtension).register(); const disposables = serviceManager.get(IDisposableRegistry); - const dispatcher = new DebugSessionEventDispatcher(handlers, DebugService.instance, disposables); - dispatcher.registerEventHandlers(); - + const workspaceService = serviceContainer.get(IWorkspaceService); const cmdManager = serviceContainer.get(ICommandManager); - const outputChannel = serviceManager.get(IOutputChannel, STANDARD_OUTPUT_CHANNEL); - disposables.push(cmdManager.registerCommand(Commands.ViewOutput, () => outputChannel.show())); - cmdManager.executeCommand('setContext', 'python.vscode.channel', applicationEnv.channel).then(noop, noop); + languages.setLanguageConfiguration(PYTHON_LANGUAGE, getLanguageConfiguration()); + if (!workspaceService.isVirtualWorkspace) { + const interpreterManager = serviceContainer.get(IInterpreterService); + interpreterManager.initialize(); - serviceContainer.get(IApplicationDiagnostics).register(); + serviceContainer.get(IApplicationDiagnostics).register(); - // "activate" everything else + const outputChannel = serviceManager.get(IOutputChannel, STANDARD_OUTPUT_CHANNEL); + disposables.push(cmdManager.registerCommand(Commands.ViewOutput, () => outputChannel.show())); + cmdManager.executeCommand('setContext', 'python.vscode.channel', applicationEnv.channel).then(noop, noop); - const manager = serviceContainer.get(IExtensionActivationManager); - context.subscriptions.push(manager); + serviceContainer.get(IApplicationDiagnostics).register(); - // Settings are dependent on Experiment service, so we need to initialize it after experiments are activated. - serviceContainer.get(IConfigurationService).getSettings().initialize(); + serviceManager.get(ITerminalAutoActivation).register(); + const pythonSettings = configuration.getSettings(); - const activationPromise = manager.activate(); + const sortImports = serviceContainer.get(ISortImportsEditingProvider); + sortImports.registerCommands(); - serviceManager.get(ITerminalAutoActivation).register(); - const pythonSettings = configuration.getSettings(); + serviceManager.get(ICodeExecutionManager).registerCommands(); - const sortImports = serviceContainer.get(ISortImportsEditingProvider); - sortImports.registerCommands(); + context.subscriptions.push(new LinterCommands(serviceManager)); - serviceManager.get(ICodeExecutionManager).registerCommands(); + if (pythonSettings && pythonSettings.formatting && pythonSettings.formatting.provider !== 'internalConsole') { + const formatProvider = new PythonFormattingEditProvider(context, serviceContainer); + context.subscriptions.push(languages.registerDocumentFormattingEditProvider(PYTHON, formatProvider)); + context.subscriptions.push(languages.registerDocumentRangeFormattingEditProvider(PYTHON, formatProvider)); + } - context.subscriptions.push(new LinterCommands(serviceManager)); + context.subscriptions.push(new ReplProvider(serviceContainer)); - languages.setLanguageConfiguration(PYTHON_LANGUAGE, getLanguageConfiguration()); + const terminalProvider = new TerminalProvider(serviceContainer); + terminalProvider.initialize(window.activeTerminal).ignoreErrors(); + context.subscriptions.push(terminalProvider); - if (pythonSettings && pythonSettings.formatting && pythonSettings.formatting.provider !== 'internalConsole') { - const formatProvider = new PythonFormattingEditProvider(context, serviceContainer); - context.subscriptions.push(languages.registerDocumentFormattingEditProvider(PYTHON, formatProvider)); - context.subscriptions.push(languages.registerDocumentRangeFormattingEditProvider(PYTHON, formatProvider)); - } + context.subscriptions.push( + languages.registerCodeActionsProvider(PYTHON, new PythonCodeActionProvider(), { + providedCodeActionKinds: [CodeActionKind.SourceOrganizeImports], + }), + ); - context.subscriptions.push(new ReplProvider(serviceContainer)); + serviceContainer + .getAll(IDebugConfigurationService) + .forEach((debugConfigProvider) => { + context.subscriptions.push( + debug.registerDebugConfigurationProvider(DebuggerTypeName, debugConfigProvider), + ); + }); - const terminalProvider = new TerminalProvider(serviceContainer); - terminalProvider.initialize(window.activeTerminal).ignoreErrors(); - context.subscriptions.push(terminalProvider); + serviceContainer.get(IDebuggerBanner).initialize(); + } + + // "activate" everything else - context.subscriptions.push( - languages.registerCodeActionsProvider(PYTHON, new PythonCodeActionProvider(), { - providedCodeActionKinds: [CodeActionKind.SourceOrganizeImports], - }), - ); + const manager = serviceContainer.get(IExtensionActivationManager); + context.subscriptions.push(manager); - serviceContainer.getAll(IDebugConfigurationService).forEach((debugConfigProvider) => { - context.subscriptions.push(debug.registerDebugConfigurationProvider(DebuggerTypeName, debugConfigProvider)); - }); + // Settings are dependent on Experiment service, so we need to initialize it after experiments are activated. + serviceContainer.get(IConfigurationService).getSettings().initialize(); - serviceContainer.get(IDebuggerBanner).initialize(); + const activationPromise = manager.activate(); return { fullyReady: activationPromise }; } diff --git a/src/client/extensionInit.ts b/src/client/extensionInit.ts index 1a8bba2e7c76..b481325c69d0 100644 --- a/src/client/extensionInit.ts +++ b/src/client/extensionInit.ts @@ -5,6 +5,7 @@ import { Container } from 'inversify'; import { Disposable, Memento, OutputChannel, window } from 'vscode'; +import { instance, mock } from 'ts-mockito'; import { STANDARD_OUTPUT_CHANNEL } from './common/constants'; import { registerTypes as platformRegisterTypes } from './common/platform/serviceRegistry'; import { registerTypes as processRegisterTypes } from './common/process/serviceRegistry'; @@ -28,6 +29,7 @@ import { TEST_OUTPUT_CHANNEL } from './testing/constants'; import { IDiscoveryAPI } from './pythonEnvironments/base/locator'; import { registerLogger } from './logging'; import { OutputChannelLogger } from './logging/outputChannelLogger'; +import { WorkspaceService } from './common/application/workspace'; // The code in this module should do nothing more complex than register // objects to DI and simple init (e.g. no side effects). That implies @@ -54,7 +56,11 @@ export function initializeGlobals( const standardOutputChannel = window.createOutputChannel(OutputChannelNames.python()); context.subscriptions.push(registerLogger(new OutputChannelLogger(standardOutputChannel))); - const unitTestOutChannel = window.createOutputChannel(OutputChannelNames.pythonTest()); + const workspaceService = new WorkspaceService(); + const unitTestOutChannel = workspaceService.isVirtualWorkspace + ? // Do not create any test related output UI when using virtual workspaces. + instance(mock()) + : window.createOutputChannel(OutputChannelNames.pythonTest()); serviceManager.addSingletonInstance(IOutputChannel, standardOutputChannel, STANDARD_OUTPUT_CHANNEL); serviceManager.addSingletonInstance(IOutputChannel, unitTestOutChannel, TEST_OUTPUT_CHANNEL); diff --git a/src/client/testing/common/testConfigurationManager.ts b/src/client/testing/common/testConfigurationManager.ts index 391a26bd4ebf..c2b050cb524a 100644 --- a/src/client/testing/common/testConfigurationManager.ts +++ b/src/client/testing/common/testConfigurationManager.ts @@ -1,12 +1,11 @@ import * as path from 'path'; -import { OutputChannel, QuickPickItem, QuickPickOptions, Uri } from 'vscode'; +import { QuickPickItem, QuickPickOptions, Uri } from 'vscode'; import { IApplicationShell } from '../../common/application/types'; import { IFileSystem } from '../../common/platform/types'; -import { IInstaller, IOutputChannel } from '../../common/types'; +import { IInstaller } from '../../common/types'; import { createDeferred } from '../../common/utils/async'; import { IServiceContainer } from '../../ioc/types'; import { traceInfo } from '../../logging'; -import { TEST_OUTPUT_CHANNEL } from '../constants'; import { UNIT_TEST_PRODUCTS } from './constants'; import { ITestConfigSettingsService, ITestConfigurationManager, UnitTestProduct } from './types'; @@ -16,8 +15,6 @@ function handleCancelled(): void { } export abstract class TestConfigurationManager implements ITestConfigurationManager { - protected readonly outputChannel: OutputChannel; - protected readonly installer: IInstaller; protected readonly testConfigSettingsService: ITestConfigSettingsService; @@ -30,7 +27,6 @@ export abstract class TestConfigurationManager implements ITestConfigurationMana protected readonly serviceContainer: IServiceContainer, cfg?: ITestConfigSettingsService, ) { - this.outputChannel = serviceContainer.get(IOutputChannel, TEST_OUTPUT_CHANNEL); this.installer = serviceContainer.get(IInstaller); this.testConfigSettingsService = cfg || serviceContainer.get(ITestConfigSettingsService); diff --git a/src/client/testing/testController/controller.ts b/src/client/testing/testController/controller.ts index af0f56106a1b..bacdc8718337 100644 --- a/src/client/testing/testController/controller.ts +++ b/src/client/testing/testController/controller.ts @@ -16,6 +16,7 @@ import { Uri, EventEmitter, } from 'vscode'; +import { IExtensionSingleActivationService } from '../../activation/types'; import { IWorkspaceService } from '../../common/application/types'; import { IConfigurationService, IDisposableRegistry, Resource } from '../../common/types'; import { DelayedTrigger, IDelayedTrigger } from '../../common/utils/delayTrigger'; @@ -27,7 +28,7 @@ import { DebugTestTag, getNodeByUri, RunTestTag } from './common/testItemUtiliti import { ITestController, ITestFrameworkController, TestRefreshOptions } from './common/types'; @injectable() -export class PythonTestController implements ITestController { +export class PythonTestController implements ITestController, IExtensionSingleActivationService { private readonly testController: TestController; private readonly refreshData: IDelayedTrigger; @@ -90,7 +91,9 @@ export class PythonTestController implements ITestController { ), ); this.testController.resolveHandler = this.resolveChildren.bind(this); + } + public async activate(): Promise { this.watchForTestChanges(); } diff --git a/src/client/testing/testController/serviceRegistry.ts b/src/client/testing/testController/serviceRegistry.ts index 0e8320a4f153..840eb14b1f27 100644 --- a/src/client/testing/testController/serviceRegistry.ts +++ b/src/client/testing/testController/serviceRegistry.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import { IExtensionSingleActivationService } from '../../activation/types'; import { IServiceManager } from '../../ioc/types'; import { PYTEST_PROVIDER, UNITTEST_PROVIDER } from '../common/constants'; import { TestDiscoveryHelper } from './common/discoveryHelper'; @@ -24,4 +25,5 @@ export function registerTestControllerTypes(serviceManager: IServiceManager): vo ); serviceManager.addSingleton(ITestsRunner, UnittestRunner, UNITTEST_PROVIDER); serviceManager.addSingleton(ITestController, PythonTestController); + serviceManager.addBinding(ITestController, IExtensionSingleActivationService); } diff --git a/src/test/activation/activationManager.unit.test.ts b/src/test/activation/activationManager.unit.test.ts index 0f34208aed46..47d12b5edecb 100644 --- a/src/test/activation/activationManager.unit.test.ts +++ b/src/test/activation/activationManager.unit.test.ts @@ -10,7 +10,11 @@ import * as typemoq from 'typemoq'; import { TextDocument, Uri, WorkspaceFolder } from 'vscode'; import { ExtensionActivationManager } from '../../client/activation/activationManager'; import { LanguageServerExtensionActivationService } from '../../client/activation/activationService'; -import { IExtensionActivationService, IExtensionSingleActivationService } from '../../client/activation/types'; +import { + IExtensionActivationService, + IExtensionSingleActivationService, + ILanguageServerActivation, +} from '../../client/activation/types'; import { IApplicationDiagnostics } from '../../client/application/types'; import { ActiveResourceService } from '../../client/common/application/activeResource'; import { IActiveResourceService, IDocumentManager, IWorkspaceService } from '../../client/common/application/types'; @@ -50,6 +54,7 @@ suite('Activation Manager', () => { let experiments: IExperimentService; let activationService1: IExtensionActivationService; let activationService2: IExtensionActivationService; + let languageServerActivation: IExtensionActivationService; let fileSystem: IFileSystem; setup(() => { experiments = mock(ExperimentService); @@ -61,6 +66,7 @@ suite('Activation Manager', () => { documentManager = typemoq.Mock.ofType(); activationService1 = mock(LanguageServerExtensionActivationService); activationService2 = mock(LanguageServerExtensionActivationService); + languageServerActivation = mock(LanguageServerExtensionActivationService); fileSystem = mock(FileSystem); interpreterPathService .setup((i) => i.onDidChange(typemoq.It.isAny())) @@ -76,6 +82,7 @@ suite('Activation Manager', () => { instance(activeResourceService), instance(experiments), interpreterPathService.object, + instance(languageServerActivation), ); sinon.stub(EnvFileTelemetry, 'sendActivationTelemetry').resolves(); @@ -404,6 +411,7 @@ suite('Activation Manager', () => { const resource = Uri.parse('a'); let interpreterPathService: typemoq.IMock; let experiments: IExperimentService; + let languageServerActivation: ILanguageServerActivation; setup(() => { experiments = mock(ExperimentService); @@ -424,6 +432,7 @@ suite('Activation Manager', () => { interpreterPathService .setup((i) => i.onDidChange(typemoq.It.isAny())) .returns(() => typemoq.Mock.ofType().object); + languageServerActivation = mock(LanguageServerExtensionActivationService); managerTest = new ExtensionActivationManager( [instance(activationService1), instance(activationService2)], [singleActivationService.object], @@ -435,6 +444,7 @@ suite('Activation Manager', () => { instance(activeResourceService), instance(experiments), interpreterPathService.object, + instance(languageServerActivation), ); }); From 57f85a8acfc0b1742cbda8986406eee9b5404e22 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 24 Sep 2021 17:15:49 -0700 Subject: [PATCH 02/18] News entry --- news/1 Enhancements/17519.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 news/1 Enhancements/17519.md diff --git a/news/1 Enhancements/17519.md b/news/1 Enhancements/17519.md new file mode 100644 index 000000000000..6236ded39cd4 --- /dev/null +++ b/news/1 Enhancements/17519.md @@ -0,0 +1 @@ +Declare limited support when running in virtual workspaces by only supporting Pylance. From 2d6ea0ea465d05799d3d4d40e88fb1d0acccb912 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Tue, 9 Nov 2021 09:11:46 -0800 Subject: [PATCH 03/18] Trigger intelliSense analysis for all schemes of python code --- src/client/activation/common/analysisOptions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/activation/common/analysisOptions.ts b/src/client/activation/common/analysisOptions.ts index 48433be0f5b1..2eb9449834c5 100644 --- a/src/client/activation/common/analysisOptions.ts +++ b/src/client/activation/common/analysisOptions.ts @@ -3,7 +3,7 @@ import { Disposable, Event, EventEmitter, WorkspaceFolder } from 'vscode'; import { DocumentFilter, LanguageClientOptions, RevealOutputChannelOn } from 'vscode-languageclient/node'; -import { PYTHON, PYTHON_LANGUAGE } from '../../common/constants'; +import { PYTHON_LANGUAGE } from '../../common/constants'; import { IOutputChannel, Resource } from '../../common/types'; import { debounceSync } from '../../common/utils/decorators'; import { IEnvironmentVariablesProvider } from '../../common/variables/types'; @@ -51,7 +51,7 @@ export abstract class LanguageServerAnalysisOptionsBase implements ILanguageServ } protected getDocumentFilters(_workspaceFolder?: WorkspaceFolder): DocumentFilter[] { - return PYTHON; + return [{ language: PYTHON_LANGUAGE }]; } protected async getInitializationOptions(): Promise { From 7c27e438616753aea89f44ea059e2dd16cc4df32 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Tue, 9 Nov 2021 09:38:23 -0800 Subject: [PATCH 04/18] Also support Jedi in virtual workspaces --- news/1 Enhancements/17519.md | 2 +- package.json | 5 ++--- package.nls.json | 1 - src/client/activation/activationService.ts | 7 ------- src/client/common/utils/localize.ts | 4 ---- 5 files changed, 3 insertions(+), 16 deletions(-) diff --git a/news/1 Enhancements/17519.md b/news/1 Enhancements/17519.md index 6236ded39cd4..71a4d49110f4 100644 --- a/news/1 Enhancements/17519.md +++ b/news/1 Enhancements/17519.md @@ -1 +1 @@ -Declare limited support when running in virtual workspaces by only supporting Pylance. +Declare limited support when running in virtual workspaces by only supporting language servers. diff --git a/package.json b/package.json index 15aa61740bd3..903f94762c61 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,10 @@ }, "capabilities": { "untrustedWorkspaces": { - "supported": "limited", - "description": "Only intellisense with Pylance is supported. Cannot execute Python with untrusted files." + "supported": false }, "virtualWorkspaces": { - "supported": false, + "supported": "limited", "description": "Limited support on the web." } }, diff --git a/package.nls.json b/package.nls.json index 9e9de8c725e6..1e980bdaaa9c 100644 --- a/package.nls.json +++ b/package.nls.json @@ -180,7 +180,6 @@ "LanguageService.startingJedi": "Starting Jedi language server.", "LanguageService.startingNone": "Editor support is inactive since language server is set to None.", "LanguageService.reloadAfterLanguageServerChange": "Please reload the window switching between language servers.", - "LanguageService.virtualWorkspaceMessage": "Only Pylance is supported when running in virtual workspaces, setting language server to None.", "AttachProcess.unsupportedOS": "Operating system '{0}' not supported.", "AttachProcess.attachTitle": "Attach to process", "AttachProcess.selectProcessPlaceholder": "Select the process to attach to", diff --git a/src/client/activation/activationService.ts b/src/client/activation/activationService.ts index 3b8c31bae48e..94f6752a70bb 100644 --- a/src/client/activation/activationService.ts +++ b/src/client/activation/activationService.ts @@ -238,13 +238,6 @@ export class LanguageServerExtensionActivationService } this.sendTelemetryForChosenLanguageServer(serverType).ignoreErrors(); - - if (this.workspaceService.isVirtualWorkspace && serverType !== LanguageServerType.Node) { - // Only Node is supported when using virtual workspaces. - this.output.appendLine(LanguageService.virtualWorkspaceMessage()); - serverType = LanguageServerType.None; - } - await this.logStartup(serverType); let server = this.serviceContainer.get(ILanguageServerActivator, serverType); try { diff --git a/src/client/common/utils/localize.ts b/src/client/common/utils/localize.ts index ce821f065949..1b245a896f89 100644 --- a/src/client/common/utils/localize.ts +++ b/src/client/common/utils/localize.ts @@ -206,10 +206,6 @@ export namespace TensorBoard { export namespace LanguageService { export const startingPylance = localize('LanguageService.startingPylance', 'Starting Pylance language server.'); export const startingJedi = localize('LanguageService.startingJedi', 'Starting Jedi language server.'); - export const virtualWorkspaceMessage = localize( - 'LanguageService.virtualWorkspaceMessage', - 'Only Pylance is supported when running in virtual workspaces, setting language server to None.', - ); export const startingNone = localize( 'LanguageService.startingNone', 'Editor support is inactive since language server is set to None.', From 8079b3c1bdf1022f602afbe4ddb3acc91f583422 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Wed, 10 Nov 2021 06:18:19 -0800 Subject: [PATCH 05/18] Rebase with main --- src/client/extensionActivation.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/client/extensionActivation.ts b/src/client/extensionActivation.ts index 7a216b39d3ff..13b4f63e84a9 100644 --- a/src/client/extensionActivation.ts +++ b/src/client/extensionActivation.ts @@ -130,7 +130,6 @@ async function activateLegacy(ext: ExtensionState): Promise { // "initialize" "services" - serviceContainer.get(ILanguageServerExtension).register(); const disposables = serviceManager.get(IDisposableRegistry); const workspaceService = serviceContainer.get(IWorkspaceService); const cmdManager = serviceContainer.get(ICommandManager); From dc9cdd7df4fe903bb5547e42743a3034d2a5f839 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Wed, 10 Nov 2021 19:28:07 -0800 Subject: [PATCH 06/18] Oops --- src/client/activation/activationService.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/client/activation/activationService.ts b/src/client/activation/activationService.ts index 94f6752a70bb..edb6cd33aeca 100644 --- a/src/client/activation/activationService.ts +++ b/src/client/activation/activationService.ts @@ -243,9 +243,6 @@ export class LanguageServerExtensionActivationService try { await server.start(resource, interpreter); } catch (ex) { - if (this.workspaceService.isVirtualWorkspace) { - throw ex; - } if (serverType === LanguageServerType.Jedi) { throw ex; } From 628770d446b64b99cfea9dd1aec91e36f5cbbc20 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Wed, 10 Nov 2021 19:55:48 -0800 Subject: [PATCH 07/18] Only support known virtual workspace scheme --- src/client/activation/common/analysisOptions.ts | 4 ++-- src/client/common/constants.ts | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/activation/common/analysisOptions.ts b/src/client/activation/common/analysisOptions.ts index 2eb9449834c5..48433be0f5b1 100644 --- a/src/client/activation/common/analysisOptions.ts +++ b/src/client/activation/common/analysisOptions.ts @@ -3,7 +3,7 @@ import { Disposable, Event, EventEmitter, WorkspaceFolder } from 'vscode'; import { DocumentFilter, LanguageClientOptions, RevealOutputChannelOn } from 'vscode-languageclient/node'; -import { PYTHON_LANGUAGE } from '../../common/constants'; +import { PYTHON, PYTHON_LANGUAGE } from '../../common/constants'; import { IOutputChannel, Resource } from '../../common/types'; import { debounceSync } from '../../common/utils/decorators'; import { IEnvironmentVariablesProvider } from '../../common/variables/types'; @@ -51,7 +51,7 @@ export abstract class LanguageServerAnalysisOptionsBase implements ILanguageServ } protected getDocumentFilters(_workspaceFolder?: WorkspaceFolder): DocumentFilter[] { - return [{ language: PYTHON_LANGUAGE }]; + return PYTHON; } protected async getInitializationOptions(): Promise { diff --git a/src/client/common/constants.ts b/src/client/common/constants.ts index 7f615c998e22..c2e447c51c51 100644 --- a/src/client/common/constants.ts +++ b/src/client/common/constants.ts @@ -12,6 +12,7 @@ export const PYTHON = [ { scheme: 'vscode-notebook', language: PYTHON_LANGUAGE }, { scheme: NotebookCellScheme, language: PYTHON_LANGUAGE }, { scheme: InteractiveInputScheme, language: PYTHON_LANGUAGE }, + { scheme: 'vscode-vfs', language: PYTHON_LANGUAGE }, ]; export const PYTHON_NOTEBOOKS = [ From 0f8ecfcce0630280669db3adbcafc985cbc46b7f Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Wed, 10 Nov 2021 23:32:00 -0800 Subject: [PATCH 08/18] Look into all python schemes when in a virtual workspace --- .../activation/common/analysisOptions.ts | 11 ++++++++--- src/client/activation/jedi/analysisOptions.ts | 4 ++-- src/client/activation/node/analysisOptions.ts | 8 ++++++-- src/client/common/constants.ts | 1 - .../node/analysisOptions.unit.test.ts | 19 +++++++++++++++---- 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/client/activation/common/analysisOptions.ts b/src/client/activation/common/analysisOptions.ts index 48433be0f5b1..f2839a25399d 100644 --- a/src/client/activation/common/analysisOptions.ts +++ b/src/client/activation/common/analysisOptions.ts @@ -2,6 +2,7 @@ // Licensed under the MIT License. import { Disposable, Event, EventEmitter, WorkspaceFolder } from 'vscode'; import { DocumentFilter, LanguageClientOptions, RevealOutputChannelOn } from 'vscode-languageclient/node'; +import { IWorkspaceService } from '../../common/application/types'; import { PYTHON, PYTHON_LANGUAGE } from '../../common/constants'; import { IOutputChannel, Resource } from '../../common/types'; @@ -15,7 +16,10 @@ export abstract class LanguageServerAnalysisOptionsBase implements ILanguageServ protected readonly didChange = new EventEmitter(); private readonly output: IOutputChannel; - protected constructor(lsOutputChannel: ILanguageServerOutputChannel) { + protected constructor( + lsOutputChannel: ILanguageServerOutputChannel, + protected readonly workspace: IWorkspaceService, + ) { this.output = lsOutputChannel.channel; } @@ -51,7 +55,7 @@ export abstract class LanguageServerAnalysisOptionsBase implements ILanguageServ } protected getDocumentFilters(_workspaceFolder?: WorkspaceFolder): DocumentFilter[] { - return PYTHON; + return this.workspace.isVirtualWorkspace ? [{ language: PYTHON_LANGUAGE }] : PYTHON; } protected async getInitializationOptions(): Promise { @@ -66,8 +70,9 @@ export abstract class LanguageServerAnalysisOptionsWithEnv extends LanguageServe protected constructor( private readonly envVarsProvider: IEnvironmentVariablesProvider, lsOutputChannel: ILanguageServerOutputChannel, + workspace: IWorkspaceService, ) { - super(lsOutputChannel); + super(lsOutputChannel, workspace); } public async initialize(_resource: Resource, _interpreter: PythonEnvironment | undefined) { diff --git a/src/client/activation/jedi/analysisOptions.ts b/src/client/activation/jedi/analysisOptions.ts index 396dbbfe8c7e..924e8b79eb6d 100644 --- a/src/client/activation/jedi/analysisOptions.ts +++ b/src/client/activation/jedi/analysisOptions.ts @@ -21,9 +21,9 @@ export class JediLanguageServerAnalysisOptions extends LanguageServerAnalysisOpt @inject(IEnvironmentVariablesProvider) envVarsProvider: IEnvironmentVariablesProvider, @inject(ILanguageServerOutputChannel) lsOutputChannel: ILanguageServerOutputChannel, @inject(IConfigurationService) private readonly configurationService: IConfigurationService, - @inject(IWorkspaceService) private readonly workspace: IWorkspaceService, + @inject(IWorkspaceService) workspace: IWorkspaceService, ) { - super(envVarsProvider, lsOutputChannel); + super(envVarsProvider, lsOutputChannel, workspace); this.resource = undefined; } diff --git a/src/client/activation/node/analysisOptions.ts b/src/client/activation/node/analysisOptions.ts index c2aa885c8aac..2bde9f9cafbe 100644 --- a/src/client/activation/node/analysisOptions.ts +++ b/src/client/activation/node/analysisOptions.ts @@ -1,14 +1,18 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. import { inject, injectable } from 'inversify'; +import { IWorkspaceService } from '../../common/application/types'; import { LanguageServerAnalysisOptionsBase } from '../common/analysisOptions'; import { ILanguageServerOutputChannel } from '../types'; @injectable() export class NodeLanguageServerAnalysisOptions extends LanguageServerAnalysisOptionsBase { - constructor(@inject(ILanguageServerOutputChannel) lsOutputChannel: ILanguageServerOutputChannel) { - super(lsOutputChannel); + constructor( + @inject(ILanguageServerOutputChannel) lsOutputChannel: ILanguageServerOutputChannel, + @inject(IWorkspaceService) workspace: IWorkspaceService, + ) { + super(lsOutputChannel, workspace); } protected async getInitializationOptions() { diff --git a/src/client/common/constants.ts b/src/client/common/constants.ts index c2e447c51c51..7f615c998e22 100644 --- a/src/client/common/constants.ts +++ b/src/client/common/constants.ts @@ -12,7 +12,6 @@ export const PYTHON = [ { scheme: 'vscode-notebook', language: PYTHON_LANGUAGE }, { scheme: NotebookCellScheme, language: PYTHON_LANGUAGE }, { scheme: InteractiveInputScheme, language: PYTHON_LANGUAGE }, - { scheme: 'vscode-vfs', language: PYTHON_LANGUAGE }, ]; export const PYTHON_NOTEBOOKS = [ diff --git a/src/test/activation/node/analysisOptions.unit.test.ts b/src/test/activation/node/analysisOptions.unit.test.ts index 628282f051e0..3e14130c650e 100644 --- a/src/test/activation/node/analysisOptions.unit.test.ts +++ b/src/test/activation/node/analysisOptions.unit.test.ts @@ -1,13 +1,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { expect } from 'chai'; +import { assert, expect } from 'chai'; import * as typemoq from 'typemoq'; import { WorkspaceFolder } from 'vscode'; import { DocumentFilter } from 'vscode-languageclient/node'; import { NodeLanguageServerAnalysisOptions } from '../../../client/activation/node/analysisOptions'; import { ILanguageServerOutputChannel } from '../../../client/activation/types'; -import { PYTHON } from '../../../client/common/constants'; +import { IWorkspaceService } from '../../../client/common/application/types'; +import { PYTHON, PYTHON_LANGUAGE } from '../../../client/common/constants'; import { IOutputChannel } from '../../../client/common/types'; suite('Pylance Language Server - Analysis Options', () => { @@ -29,12 +30,15 @@ suite('Pylance Language Server - Analysis Options', () => { let analysisOptions: TestClass; let outputChannel: IOutputChannel; let lsOutputChannel: typemoq.IMock; + let workspace: typemoq.IMock; setup(() => { outputChannel = typemoq.Mock.ofType().object; + workspace = typemoq.Mock.ofType(); + workspace.setup((w) => w.isVirtualWorkspace).returns(() => false); lsOutputChannel = typemoq.Mock.ofType(); lsOutputChannel.setup((l) => l.channel).returns(() => outputChannel); - analysisOptions = new TestClass(lsOutputChannel.object); + analysisOptions = new TestClass(lsOutputChannel.object, workspace.object); }); test('Workspace folder is undefined', () => { @@ -42,11 +46,18 @@ suite('Pylance Language Server - Analysis Options', () => { expect(workspaceFolder).to.be.equal(undefined); }); - test('Document filter matches all python', () => { + test('Document filter matches expected python language schemes', () => { const filter = analysisOptions.getDocumentFilters(); expect(filter).to.be.equal(PYTHON); }); + test('Document filter matches all python language schemes when in virtual workspace', () => { + workspace.reset(); + workspace.setup((w) => w.isVirtualWorkspace).returns(() => true); + const filter = analysisOptions.getDocumentFilters(); + assert.deepEqual(filter, [{ language: PYTHON_LANGUAGE }]); + }); + test('Initialization options include experimentation capability', async () => { const options = await analysisOptions.getInitializationOptions(); expect(options?.experimentationSupport).to.be.equal(true); From 8f2fb74bf46b69a621fa76130b8e47d686385747 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Thu, 11 Nov 2021 06:17:43 -0800 Subject: [PATCH 09/18] Fix some tests --- src/client/extensionActivation.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/client/extensionActivation.ts b/src/client/extensionActivation.ts index 13b4f63e84a9..a36d22aecfa4 100644 --- a/src/client/extensionActivation.ts +++ b/src/client/extensionActivation.ts @@ -138,8 +138,6 @@ async function activateLegacy(ext: ExtensionState): Promise { const interpreterManager = serviceContainer.get(IInterpreterService); interpreterManager.initialize(); - serviceContainer.get(IApplicationDiagnostics).register(); - const outputChannel = serviceManager.get(IOutputChannel, STANDARD_OUTPUT_CHANNEL); disposables.push(cmdManager.registerCommand(Commands.ViewOutput, () => outputChannel.show())); cmdManager.executeCommand('setContext', 'python.vscode.channel', applicationEnv.channel).then(noop, noop); From 156f0076fa788a690acc715c4fbc88c08ff61e7e Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Thu, 11 Nov 2021 06:35:57 -0800 Subject: [PATCH 10/18] Fix mistake --- src/client/extensionActivation.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/client/extensionActivation.ts b/src/client/extensionActivation.ts index a36d22aecfa4..d3ad41dbf1d0 100644 --- a/src/client/extensionActivation.ts +++ b/src/client/extensionActivation.ts @@ -44,6 +44,9 @@ import { ActivationResult, ExtensionState } from './components'; import { Components } from './extensionInit'; import { setDefaultLanguageServer } from './activation/common/defaultlanguageServer'; import { getLoggingLevel } from './logging/settings'; +import { DebugService } from './common/application/debugService'; +import { DebugSessionEventDispatcher } from './debugger/extension/hooks/eventHandlerDispatcher'; +import { IDebugSessionEventHandlers } from './debugger/extension/hooks/types'; export async function activateComponents( // `ext` is passed to any extra activation funcs. @@ -135,6 +138,9 @@ async function activateLegacy(ext: ExtensionState): Promise { const cmdManager = serviceContainer.get(ICommandManager); languages.setLanguageConfiguration(PYTHON_LANGUAGE, getLanguageConfiguration()); if (!workspaceService.isVirtualWorkspace) { + const handlers = serviceManager.getAll(IDebugSessionEventHandlers); + const dispatcher = new DebugSessionEventDispatcher(handlers, DebugService.instance, disposables); + dispatcher.registerEventHandlers(); const interpreterManager = serviceContainer.get(IInterpreterService); interpreterManager.initialize(); From d2d66b5191170d84f6a9547b35deabd878363940 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Thu, 11 Nov 2021 09:30:09 -0800 Subject: [PATCH 11/18] Do not register Jupyter hooks when using virtual workspaces --- src/client/jupyter/jupyterIntegration.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/client/jupyter/jupyterIntegration.ts b/src/client/jupyter/jupyterIntegration.ts index 4fc5e7be6b4f..7d2229ff66cd 100644 --- a/src/client/jupyter/jupyterIntegration.ts +++ b/src/client/jupyter/jupyterIntegration.ts @@ -9,6 +9,7 @@ import { dirname } from 'path'; import { CancellationToken, Disposable, Event, Extension, Memento, Uri } from 'vscode'; import * as lsp from 'vscode-languageserver-protocol'; import { ILanguageServerCache, ILanguageServerConnection } from '../activation/types'; +import { IWorkspaceService } from '../common/application/types'; import { JUPYTER_EXTENSION_ID } from '../common/constants'; import { InterpreterUri, ModuleInstallFlags } from '../common/installer/types'; import { @@ -176,10 +177,14 @@ export class JupyterExtensionIntegration { @inject(IMemento) @named(GLOBAL_MEMENTO) private globalState: Memento, @inject(IInterpreterDisplay) private interpreterDisplay: IInterpreterDisplay, @inject(IComponentAdapter) private pyenvs: IComponentAdapter, + @inject(IWorkspaceService) private workspace: IWorkspaceService, ) {} public registerApi(jupyterExtensionApi: JupyterExtensionApi): JupyterExtensionApi | undefined { // Forward python parts + if (this.workspace.isVirtualWorkspace) { + return undefined; + } jupyterExtensionApi.registerPythonApi({ onDidChangeInterpreter: this.interpreterService.onDidChangeInterpreter, getActiveInterpreter: async (resource?: Uri) => this.interpreterService.getActiveInterpreter(resource), From cebb40748e6d3db7c8ca4b88440adb36de13d21e Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Thu, 11 Nov 2021 22:47:18 -0800 Subject: [PATCH 12/18] Nit --- src/client/activation/activationManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/activation/activationManager.ts b/src/client/activation/activationManager.ts index 9b998fa00eb7..6752165ed5d8 100644 --- a/src/client/activation/activationManager.ts +++ b/src/client/activation/activationManager.ts @@ -67,7 +67,7 @@ export class ExtensionActivationManager implements IExtensionActivationManager { await this.activateWorkspace(this.activeResourceService.getActiveResource()); } else { await Promise.all([ - Promise.all(this.singleActivationServices.map((item) => item.activate())), + ...this.singleActivationServices.map((item) => item.activate()), this.activateWorkspace(this.activeResourceService.getActiveResource()), ]); } From 6221b0c2f1c11fddc3c9e283b0cabcf2fd872243 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 12 Nov 2021 04:41:01 -0800 Subject: [PATCH 13/18] Only activate interpreter and language server component when in a virtual workspace --- src/client/activation/activationManager.ts | 41 ++++++++++--------- src/client/activation/activationService.ts | 17 ++++---- src/client/activation/serviceRegistry.ts | 2 - src/client/activation/types.ts | 11 +++-- src/client/extension.ts | 27 ++++-------- src/client/extensionActivation.ts | 15 ++----- .../interpreterSelector/commands/base.ts | 3 +- .../virtualEnvs/condaInheritEnvPrompt.ts | 3 +- .../virtualEnvs/virtualEnvPrompt.ts | 4 +- src/client/jupyter/jupyterIntegration.ts | 5 --- .../activation/activationManager.unit.test.ts | 12 +----- 11 files changed, 58 insertions(+), 82 deletions(-) diff --git a/src/client/activation/activationManager.ts b/src/client/activation/activationManager.ts index 6752165ed5d8..08a3e680590e 100644 --- a/src/client/activation/activationManager.ts +++ b/src/client/activation/activationManager.ts @@ -16,10 +16,10 @@ import { IInterpreterAutoSelectionService } from '../interpreter/autoSelection/t import { traceDecoratorError } from '../logging'; import { sendActivationTelemetry } from '../telemetry/envFileTelemetry'; import { + ComponentId, IExtensionActivationManager, IExtensionActivationService, IExtensionSingleActivationService, - ILanguageServerActivation, } from './types'; @injectable() @@ -44,7 +44,6 @@ export class ExtensionActivationManager implements IExtensionActivationManager { @inject(IActiveResourceService) private readonly activeResourceService: IActiveResourceService, @inject(IExperimentService) private readonly experiments: IExperimentService, @inject(IInterpreterPathService) private readonly interpreterPathService: IInterpreterPathService, - @inject(ILanguageServerActivation) private readonly languageServerActivation: ILanguageServerActivation, ) {} public dispose(): void { @@ -63,14 +62,14 @@ export class ExtensionActivationManager implements IExtensionActivationManager { // Activate all activation services together. - if (this.workspaceService.isVirtualWorkspace) { - await this.activateWorkspace(this.activeResourceService.getActiveResource()); - } else { - await Promise.all([ - ...this.singleActivationServices.map((item) => item.activate()), - this.activateWorkspace(this.activeResourceService.getActiveResource()), - ]); - } + const singleActivationServices = this.workspaceService.isVirtualWorkspace + ? this.singleActivationServices.filter((s) => s.componentId === ComponentId.interpreter) + : this.singleActivationServices; + + await Promise.all([ + ...singleActivationServices.map((item) => item.activate()), + this.activateWorkspace(this.activeResourceService.getActiveResource()), + ]); } @traceDecoratorError('Failed to activate a workspace') @@ -81,18 +80,20 @@ export class ExtensionActivationManager implements IExtensionActivationManager { } this.activatedWorkspaces.add(key); + if (this.experiments.inExperimentSync(DeprecatePythonPath.experiment)) { + await this.interpreterPathService.copyOldInterpreterStorageValuesToNew(resource); + } + await sendActivationTelemetry(this.fileSystem, this.workspaceService, resource); - if (this.workspaceService.isVirtualWorkspace) { - await this.languageServerActivation.activate(resource); - } else { - if (this.experiments.inExperimentSync(DeprecatePythonPath.experiment)) { - await this.interpreterPathService.copyOldInterpreterStorageValuesToNew(resource); - } - await this.autoSelection.autoSelectInterpreter(resource); - await Promise.all(this.activationServices.map((item) => item.activate(resource))); - await this.appDiagnostics.performPreStartupHealthCheck(resource); - } + await this.autoSelection.autoSelectInterpreter(resource); + const activationServices = this.workspaceService.isVirtualWorkspace + ? this.activationServices.filter( + (s) => s.componentId === ComponentId.interpreter || s.componentId === ComponentId.languageServer, + ) + : this.activationServices; + await Promise.all(activationServices.map((item) => item.activate(resource))); + await this.appDiagnostics.performPreStartupHealthCheck(resource); } public async initialize(): Promise { diff --git a/src/client/activation/activationService.ts b/src/client/activation/activationService.ts index edb6cd33aeca..410c1b2f9285 100644 --- a/src/client/activation/activationService.ts +++ b/src/client/activation/activationService.ts @@ -25,6 +25,7 @@ import { EventName } from '../telemetry/constants'; import { LanguageServerChangeHandler } from './common/languageServerChangeHandler'; import { RefCountedLanguageServer } from './refCountedLanguageServer'; import { + ComponentId, IExtensionActivationService, ILanguageServerActivator, ILanguageServerCache, @@ -49,13 +50,15 @@ export class LanguageServerExtensionActivationService private activatedServer?: IActivatedServer; + public readonly componentId? = ComponentId.languageServer; + private readonly workspaceService: IWorkspaceService; private readonly configurationService: IConfigurationService; private readonly output: OutputChannel; - private readonly interpreterService?: IInterpreterService; + private readonly interpreterService: IInterpreterService; private readonly languageServerChangeHandler: LanguageServerChangeHandler; @@ -67,18 +70,14 @@ export class LanguageServerExtensionActivationService ) { this.workspaceService = this.serviceContainer.get(IWorkspaceService); this.configurationService = this.serviceContainer.get(IConfigurationService); - if (!this.workspaceService.isVirtualWorkspace) { - this.interpreterService = this.serviceContainer.get(IInterpreterService); - } + this.interpreterService = this.serviceContainer.get(IInterpreterService); this.output = this.serviceContainer.get(IOutputChannel, STANDARD_OUTPUT_CHANNEL); const disposables = serviceContainer.get(IDisposableRegistry); disposables.push(this); disposables.push(this.workspaceService.onDidChangeConfiguration(this.onDidChangeConfiguration.bind(this))); disposables.push(this.workspaceService.onDidChangeWorkspaceFolders(this.onWorkspaceFoldersChanged, this)); - if (this.interpreterService) { - disposables.push(this.interpreterService.onDidChangeInterpreter(this.onDidChangeInterpreter.bind(this))); - } + disposables.push(this.interpreterService.onDidChangeInterpreter(this.onDidChangeInterpreter.bind(this))); this.languageServerChangeHandler = new LanguageServerChangeHandler( this.getCurrentLanguageServerType(), @@ -95,7 +94,7 @@ export class LanguageServerExtensionActivationService const stopWatch = new StopWatch(); // Get a new server and dispose of the old one (might be the same one) this.resource = resource; - const interpreter = await this.interpreterService?.getActiveInterpreter(resource); + const interpreter = await this.interpreterService.getActiveInterpreter(resource); const key = await this.getKey(resource, interpreter); // If we have an old server with a different key, then deactivate it as the @@ -307,7 +306,7 @@ export class LanguageServerExtensionActivationService resource, workspacePathNameForGlobalWorkspaces, ); - interpreter = interpreter || (await this.interpreterService?.getActiveInterpreter(resource)); + interpreter = interpreter || (await this.interpreterService.getActiveInterpreter(resource)); const interperterPortion = interpreter ? `${interpreter.path}-${interpreter.envName}` : ''; return `${resourcePortion}-${interperterPortion}`; } diff --git a/src/client/activation/serviceRegistry.ts b/src/client/activation/serviceRegistry.ts index c5df85de7c00..c865307d8aa2 100644 --- a/src/client/activation/serviceRegistry.ts +++ b/src/client/activation/serviceRegistry.ts @@ -22,7 +22,6 @@ import { IExtensionActivationService, IExtensionSingleActivationService, ILanguageClientFactory, - ILanguageServerActivation, ILanguageServerActivator, ILanguageServerAnalysisOptions, ILanguageServerCache, @@ -38,7 +37,6 @@ import { LoadLanguageServerExtension } from './common/loadLanguageServerExtensio export function registerTypes(serviceManager: IServiceManager, languageServerType: LanguageServerType): void { serviceManager.addSingleton(ILanguageServerCache, LanguageServerExtensionActivationService); serviceManager.addBinding(ILanguageServerCache, IExtensionActivationService); - serviceManager.addBinding(ILanguageServerCache, ILanguageServerActivation); serviceManager.add(IExtensionActivationManager, ExtensionActivationManager); serviceManager.add( ILanguageServerActivator, diff --git a/src/client/activation/types.ts b/src/client/activation/types.ts index 5c08ee0c1be4..402891ed030e 100644 --- a/src/client/activation/types.ts +++ b/src/client/activation/types.ts @@ -58,6 +58,7 @@ export const IExtensionActivationService = Symbol('IExtensionActivationService') * @interface IExtensionActivationService */ export interface IExtensionActivationService { + componentId?: ComponentId; activate(resource: Resource): Promise; } @@ -104,9 +105,6 @@ export interface ILanguageServerCache { get(resource: Resource, interpreter?: PythonEnvironment): Promise; } -export const ILanguageServerActivation = Symbol('ILanguageServerActivation'); -export interface ILanguageServerActivation extends IExtensionActivationService {} - export type FolderVersionPair = { path: string; version: SemVer }; export const ILanguageServerFolderService = Symbol('ILanguageServerFolderService'); @@ -171,6 +169,12 @@ export interface ILanguageServerOutputChannel { readonly channel: IOutputChannel; } +export enum ComponentId { + other = 0, + interpreter = 1, + languageServer = 2, +} + export const IExtensionSingleActivationService = Symbol('IExtensionSingleActivationService'); /** * Classes implementing this interface will have their `activate` methods @@ -181,5 +185,6 @@ export const IExtensionSingleActivationService = Symbol('IExtensionSingleActivat * @interface IExtensionSingleActivationService */ export interface IExtensionSingleActivationService { + componentId?: ComponentId; activate(): Promise; } diff --git a/src/client/extension.ts b/src/client/extension.ts index c6260d363fa8..c04dfb3c3c98 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -42,7 +42,6 @@ import { sendErrorTelemetry, sendStartupTelemetry } from './startupTelemetry'; import { IStartupDurations } from './types'; import { runAfterActivation } from './common/utils/runAfterActivation'; import { IInterpreterService } from './interpreter/contracts'; -import { WorkspaceService } from './common/application/workspace'; durations.codeLoadingTime = stopWatch.elapsedTime; @@ -70,12 +69,9 @@ export async function activate(context: IExtensionContext): Promise { if (activatedServiceContainer) { const workspaceService = activatedServiceContainer.get(IWorkspaceService); - if (!workspaceService.isVirtualWorkspace) { - const interpreterManager = activatedServiceContainer.get(IInterpreterService); - const workspaces = workspaceService.workspaceFolders ?? []; - await interpreterManager - .refresh(workspaces.length > 0 ? workspaces[0].uri : undefined) - .catch((ex) => traceError('Python Extension: interpreterManager.refresh', ex)); - } + const interpreterManager = activatedServiceContainer.get(IInterpreterService); + const workspaces = workspaceService.workspaceFolders ?? []; + await interpreterManager + .refresh(workspaces.length > 0 ? workspaces[0].uri : undefined) + .catch((ex) => traceError('Python Extension: interpreterManager.refresh', ex)); } runAfterActivation(); @@ -167,10 +161,7 @@ async function handleError(ex: Error, startupDurations: IStartupDurations) { ); traceError('extension activation failed', ex); - const workspace = new WorkspaceService(); - if (!workspace.isVirtualWorkspace) { - await sendErrorTelemetry(ex, startupDurations, activatedServiceContainer); - } + await sendErrorTelemetry(ex, startupDurations, activatedServiceContainer); } interface IAppShell { diff --git a/src/client/extensionActivation.ts b/src/client/extensionActivation.ts index d3ad41dbf1d0..fae6c717e5ff 100644 --- a/src/client/extensionActivation.ts +++ b/src/client/extensionActivation.ts @@ -70,11 +70,6 @@ export async function activateComponents( // https://github.com/microsoft/vscode-python/issues/15380 // These will go away eventually once everything is refactored into components. const legacyActivationResult = await activateLegacy(ext); - const workspaceService = ext.legacyIOC.serviceContainer.get(IWorkspaceService); - if (workspaceService.isVirtualWorkspace) { - // Nothing other than Pylance is activated when using virtual workspaces. - return [legacyActivationResult]; - } const promises: Promise[] = [ // More component activations will go here pythonEnvironments.activate(components.pythonEnvs, ext), @@ -122,8 +117,9 @@ async function activateLegacy(ext: ExtensionState): Promise { // directly queries VSCode API. setLoggingLevel(getLoggingLevel()); - // `IConfigurationService` may depend any of the registered types, so doing it after all registrations are finished. const configuration = serviceManager.get(IConfigurationService); + // Settings are dependent on Experiment service, so we need to initialize it after experiments are activated. + serviceContainer.get(IConfigurationService).getSettings().initialize(); const languageServerType = configuration.getSettings().languageServer; // Language feature registrations. @@ -137,12 +133,12 @@ async function activateLegacy(ext: ExtensionState): Promise { const workspaceService = serviceContainer.get(IWorkspaceService); const cmdManager = serviceContainer.get(ICommandManager); languages.setLanguageConfiguration(PYTHON_LANGUAGE, getLanguageConfiguration()); + const interpreterManager = serviceContainer.get(IInterpreterService); + interpreterManager.initialize(); if (!workspaceService.isVirtualWorkspace) { const handlers = serviceManager.getAll(IDebugSessionEventHandlers); const dispatcher = new DebugSessionEventDispatcher(handlers, DebugService.instance, disposables); dispatcher.registerEventHandlers(); - const interpreterManager = serviceContainer.get(IInterpreterService); - interpreterManager.initialize(); const outputChannel = serviceManager.get(IOutputChannel, STANDARD_OUTPUT_CHANNEL); disposables.push(cmdManager.registerCommand(Commands.ViewOutput, () => outputChannel.show())); @@ -194,9 +190,6 @@ async function activateLegacy(ext: ExtensionState): Promise { const manager = serviceContainer.get(IExtensionActivationManager); context.subscriptions.push(manager); - // Settings are dependent on Experiment service, so we need to initialize it after experiments are activated. - serviceContainer.get(IConfigurationService).getSettings().initialize(); - const activationPromise = manager.activate(); return { fullyReady: activationPromise }; diff --git a/src/client/interpreter/configuration/interpreterSelector/commands/base.ts b/src/client/interpreter/configuration/interpreterSelector/commands/base.ts index 618f698df35a..226677c36f62 100644 --- a/src/client/interpreter/configuration/interpreterSelector/commands/base.ts +++ b/src/client/interpreter/configuration/interpreterSelector/commands/base.ts @@ -6,7 +6,7 @@ import { injectable, unmanaged } from 'inversify'; import * as path from 'path'; import { ConfigurationTarget, Disposable, QuickPickItem, Uri } from 'vscode'; -import { IExtensionSingleActivationService } from '../../../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../../../activation/types'; import { IApplicationShell, ICommandManager, IWorkspaceService } from '../../../../common/application/types'; import { IDisposable, Resource } from '../../../../common/types'; import { Interpreters } from '../../../../common/utils/localize'; @@ -14,6 +14,7 @@ import { IPythonPathUpdaterServiceManager } from '../../types'; @injectable() export abstract class BaseInterpreterSelectorCommand implements IExtensionSingleActivationService, IDisposable { + public readonly componentId = ComponentId.interpreter; protected disposables: Disposable[] = []; constructor( @unmanaged() protected readonly pythonPathUpdaterService: IPythonPathUpdaterServiceManager, diff --git a/src/client/interpreter/virtualEnvs/condaInheritEnvPrompt.ts b/src/client/interpreter/virtualEnvs/condaInheritEnvPrompt.ts index 09f1ea32f10a..a5e84a21a43a 100644 --- a/src/client/interpreter/virtualEnvs/condaInheritEnvPrompt.ts +++ b/src/client/interpreter/virtualEnvs/condaInheritEnvPrompt.ts @@ -3,7 +3,7 @@ import { inject, injectable, optional } from 'inversify'; import { ConfigurationTarget, Uri } from 'vscode'; -import { IExtensionActivationService } from '../../activation/types'; +import { ComponentId, IExtensionActivationService } from '../../activation/types'; import { IApplicationShell, IWorkspaceService } from '../../common/application/types'; import { IPlatformService } from '../../common/platform/types'; import { IBrowserService, IPersistentStateFactory } from '../../common/types'; @@ -18,6 +18,7 @@ export const condaInheritEnvPromptKey = 'CONDA_INHERIT_ENV_PROMPT_KEY'; @injectable() export class CondaInheritEnvPrompt implements IExtensionActivationService { + public readonly componentId = ComponentId.interpreter; constructor( @inject(IInterpreterService) private readonly interpreterService: IInterpreterService, @inject(IWorkspaceService) private readonly workspaceService: IWorkspaceService, diff --git a/src/client/interpreter/virtualEnvs/virtualEnvPrompt.ts b/src/client/interpreter/virtualEnvs/virtualEnvPrompt.ts index 0f8223647c0a..45dcc4dc5c4e 100644 --- a/src/client/interpreter/virtualEnvs/virtualEnvPrompt.ts +++ b/src/client/interpreter/virtualEnvs/virtualEnvPrompt.ts @@ -3,7 +3,7 @@ import { inject, injectable } from 'inversify'; import { ConfigurationTarget, Disposable, Uri } from 'vscode'; -import { IExtensionActivationService } from '../../activation/types'; +import { ComponentId, IExtensionActivationService } from '../../activation/types'; import { IApplicationShell } from '../../common/application/types'; import { IDisposableRegistry, IPersistentStateFactory } from '../../common/types'; import { sleep } from '../../common/utils/async'; @@ -18,6 +18,8 @@ import { IComponentAdapter, IInterpreterHelper } from '../contracts'; const doNotDisplayPromptStateKey = 'MESSAGE_KEY_FOR_VIRTUAL_ENV'; @injectable() export class VirtualEnvironmentPrompt implements IExtensionActivationService { + public readonly componentId = ComponentId.interpreter; + constructor( @inject(IPersistentStateFactory) private readonly persistentStateFactory: IPersistentStateFactory, @inject(IInterpreterHelper) private readonly helper: IInterpreterHelper, diff --git a/src/client/jupyter/jupyterIntegration.ts b/src/client/jupyter/jupyterIntegration.ts index 7d2229ff66cd..4fc5e7be6b4f 100644 --- a/src/client/jupyter/jupyterIntegration.ts +++ b/src/client/jupyter/jupyterIntegration.ts @@ -9,7 +9,6 @@ import { dirname } from 'path'; import { CancellationToken, Disposable, Event, Extension, Memento, Uri } from 'vscode'; import * as lsp from 'vscode-languageserver-protocol'; import { ILanguageServerCache, ILanguageServerConnection } from '../activation/types'; -import { IWorkspaceService } from '../common/application/types'; import { JUPYTER_EXTENSION_ID } from '../common/constants'; import { InterpreterUri, ModuleInstallFlags } from '../common/installer/types'; import { @@ -177,14 +176,10 @@ export class JupyterExtensionIntegration { @inject(IMemento) @named(GLOBAL_MEMENTO) private globalState: Memento, @inject(IInterpreterDisplay) private interpreterDisplay: IInterpreterDisplay, @inject(IComponentAdapter) private pyenvs: IComponentAdapter, - @inject(IWorkspaceService) private workspace: IWorkspaceService, ) {} public registerApi(jupyterExtensionApi: JupyterExtensionApi): JupyterExtensionApi | undefined { // Forward python parts - if (this.workspace.isVirtualWorkspace) { - return undefined; - } jupyterExtensionApi.registerPythonApi({ onDidChangeInterpreter: this.interpreterService.onDidChangeInterpreter, getActiveInterpreter: async (resource?: Uri) => this.interpreterService.getActiveInterpreter(resource), diff --git a/src/test/activation/activationManager.unit.test.ts b/src/test/activation/activationManager.unit.test.ts index 47d12b5edecb..0f34208aed46 100644 --- a/src/test/activation/activationManager.unit.test.ts +++ b/src/test/activation/activationManager.unit.test.ts @@ -10,11 +10,7 @@ import * as typemoq from 'typemoq'; import { TextDocument, Uri, WorkspaceFolder } from 'vscode'; import { ExtensionActivationManager } from '../../client/activation/activationManager'; import { LanguageServerExtensionActivationService } from '../../client/activation/activationService'; -import { - IExtensionActivationService, - IExtensionSingleActivationService, - ILanguageServerActivation, -} from '../../client/activation/types'; +import { IExtensionActivationService, IExtensionSingleActivationService } from '../../client/activation/types'; import { IApplicationDiagnostics } from '../../client/application/types'; import { ActiveResourceService } from '../../client/common/application/activeResource'; import { IActiveResourceService, IDocumentManager, IWorkspaceService } from '../../client/common/application/types'; @@ -54,7 +50,6 @@ suite('Activation Manager', () => { let experiments: IExperimentService; let activationService1: IExtensionActivationService; let activationService2: IExtensionActivationService; - let languageServerActivation: IExtensionActivationService; let fileSystem: IFileSystem; setup(() => { experiments = mock(ExperimentService); @@ -66,7 +61,6 @@ suite('Activation Manager', () => { documentManager = typemoq.Mock.ofType(); activationService1 = mock(LanguageServerExtensionActivationService); activationService2 = mock(LanguageServerExtensionActivationService); - languageServerActivation = mock(LanguageServerExtensionActivationService); fileSystem = mock(FileSystem); interpreterPathService .setup((i) => i.onDidChange(typemoq.It.isAny())) @@ -82,7 +76,6 @@ suite('Activation Manager', () => { instance(activeResourceService), instance(experiments), interpreterPathService.object, - instance(languageServerActivation), ); sinon.stub(EnvFileTelemetry, 'sendActivationTelemetry').resolves(); @@ -411,7 +404,6 @@ suite('Activation Manager', () => { const resource = Uri.parse('a'); let interpreterPathService: typemoq.IMock; let experiments: IExperimentService; - let languageServerActivation: ILanguageServerActivation; setup(() => { experiments = mock(ExperimentService); @@ -432,7 +424,6 @@ suite('Activation Manager', () => { interpreterPathService .setup((i) => i.onDidChange(typemoq.It.isAny())) .returns(() => typemoq.Mock.ofType().object); - languageServerActivation = mock(LanguageServerExtensionActivationService); managerTest = new ExtensionActivationManager( [instance(activationService1), instance(activationService2)], [singleActivationService.object], @@ -444,7 +435,6 @@ suite('Activation Manager', () => { instance(activeResourceService), instance(experiments), interpreterPathService.object, - instance(languageServerActivation), ); }); From b801b1b6d4e7f7bade5c066ccd8214dd5e871d83 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 12 Nov 2021 05:29:30 -0800 Subject: [PATCH 14/18] Make component id a mandatory field in extension activation services --- src/client/activation/activationManager.ts | 8 +++++--- src/client/activation/activationService.ts | 2 +- .../activation/common/loadLanguageServerExtension.ts | 4 +++- src/client/activation/extensionSurvey.ts | 3 ++- src/client/activation/types.ts | 5 +++-- src/client/common/application/commands/reloadCommand.ts | 3 ++- .../common/application/commands/reportIssueCommand.ts | 4 +++- src/client/common/application/debugSessionTelemetry.ts | 3 ++- .../common/insidersBuild/insidersExtensionService.ts | 3 ++- src/client/common/persistentState.ts | 3 ++- src/client/debugger/extension/adapter/activator.ts | 3 ++- .../configuration/launch.json/completionProvider.ts | 3 ++- .../configuration/launch.json/interpreterPathCommand.ts | 3 ++- .../extension/configuration/launch.json/updaterService.ts | 3 ++- src/client/debugger/extension/debugCommands.ts | 4 +++- src/client/interpreter/display/progressDisplay.ts | 4 +++- src/client/providers/codeActionProvider/main.ts | 3 ++- src/client/providers/linterProvider.ts | 3 ++- src/client/telemetry/importTracker.ts | 4 +++- src/client/tensorBoard/nbextensionCodeLensProvider.ts | 4 +++- src/client/tensorBoard/tensorBoardFileWatcher.ts | 4 +++- .../tensorBoard/tensorBoardImportCodeLensProvider.ts | 4 +++- src/client/tensorBoard/tensorBoardSessionProvider.ts | 4 +++- src/client/tensorBoard/tensorBoardUsageTracker.ts | 4 +++- src/client/tensorBoard/terminalWatcher.ts | 4 +++- src/client/testing/common/updateTestSettings.ts | 3 ++- src/client/testing/main.ts | 3 ++- src/client/testing/testController/controller.ts | 4 +++- 28 files changed, 71 insertions(+), 31 deletions(-) diff --git a/src/client/activation/activationManager.ts b/src/client/activation/activationManager.ts index 08a3e680590e..32bf387d3389 100644 --- a/src/client/activation/activationManager.ts +++ b/src/client/activation/activationManager.ts @@ -63,7 +63,9 @@ export class ExtensionActivationManager implements IExtensionActivationManager { // Activate all activation services together. const singleActivationServices = this.workspaceService.isVirtualWorkspace - ? this.singleActivationServices.filter((s) => s.componentId === ComponentId.interpreter) + ? this.singleActivationServices.filter((s) => + [ComponentId.interpreter, ComponentId.languageServer, ComponentId.common].includes(s.componentId), + ) : this.singleActivationServices; await Promise.all([ @@ -88,8 +90,8 @@ export class ExtensionActivationManager implements IExtensionActivationManager { await this.autoSelection.autoSelectInterpreter(resource); const activationServices = this.workspaceService.isVirtualWorkspace - ? this.activationServices.filter( - (s) => s.componentId === ComponentId.interpreter || s.componentId === ComponentId.languageServer, + ? this.activationServices.filter((s) => + [ComponentId.interpreter, ComponentId.languageServer, ComponentId.common].includes(s.componentId), ) : this.activationServices; await Promise.all(activationServices.map((item) => item.activate(resource))); diff --git a/src/client/activation/activationService.ts b/src/client/activation/activationService.ts index 410c1b2f9285..1ffae430ad62 100644 --- a/src/client/activation/activationService.ts +++ b/src/client/activation/activationService.ts @@ -50,7 +50,7 @@ export class LanguageServerExtensionActivationService private activatedServer?: IActivatedServer; - public readonly componentId? = ComponentId.languageServer; + public readonly componentId = ComponentId.languageServer; private readonly workspaceService: IWorkspaceService; diff --git a/src/client/activation/common/loadLanguageServerExtension.ts b/src/client/activation/common/loadLanguageServerExtension.ts index e30decac14b7..170362692fa4 100644 --- a/src/client/activation/common/loadLanguageServerExtension.ts +++ b/src/client/activation/common/loadLanguageServerExtension.ts @@ -4,7 +4,7 @@ import { inject, injectable } from 'inversify'; import { ICommandManager } from '../../common/application/types'; import { IDisposableRegistry } from '../../common/types'; -import { IExtensionSingleActivationService } from '../types'; +import { ComponentId, IExtensionSingleActivationService } from '../types'; // This command is currently used by IntelliCode. This was used to // trigger MPLS. Since we no longer have MPLS we are going to set @@ -13,6 +13,8 @@ import { IExtensionSingleActivationService } from '../types'; @injectable() export class LoadLanguageServerExtension implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.languageServer; + constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, @inject(IDisposableRegistry) private readonly disposables: IDisposableRegistry, diff --git a/src/client/activation/extensionSurvey.ts b/src/client/activation/extensionSurvey.ts index 463f84e6e36c..b1638e007aec 100644 --- a/src/client/activation/extensionSurvey.ts +++ b/src/client/activation/extensionSurvey.ts @@ -15,7 +15,7 @@ import { Common, ExtensionSurveyBanner } from '../common/utils/localize'; import { traceDecoratorError } from '../logging'; import { sendTelemetryEvent } from '../telemetry'; import { EventName } from '../telemetry/constants'; -import { IExtensionSingleActivationService } from './types'; +import { ComponentId, IExtensionSingleActivationService } from './types'; // persistent state names, exported to make use of in testing export enum extensionSurveyStateKeys { @@ -28,6 +28,7 @@ const WAIT_TIME_TO_SHOW_SURVEY = 1000 * 60 * 60 * 3; // 3 hours @injectable() export class ExtensionSurveyPrompt implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.common; constructor( @inject(IApplicationShell) private appShell: IApplicationShell, @inject(IBrowserService) private browserService: IBrowserService, diff --git a/src/client/activation/types.ts b/src/client/activation/types.ts index 402891ed030e..18c3c4559af5 100644 --- a/src/client/activation/types.ts +++ b/src/client/activation/types.ts @@ -58,7 +58,7 @@ export const IExtensionActivationService = Symbol('IExtensionActivationService') * @interface IExtensionActivationService */ export interface IExtensionActivationService { - componentId?: ComponentId; + componentId: ComponentId; activate(resource: Resource): Promise; } @@ -173,6 +173,7 @@ export enum ComponentId { other = 0, interpreter = 1, languageServer = 2, + common = 3, } export const IExtensionSingleActivationService = Symbol('IExtensionSingleActivationService'); @@ -185,6 +186,6 @@ export const IExtensionSingleActivationService = Symbol('IExtensionSingleActivat * @interface IExtensionSingleActivationService */ export interface IExtensionSingleActivationService { - componentId?: ComponentId; + componentId: ComponentId; activate(): Promise; } diff --git a/src/client/common/application/commands/reloadCommand.ts b/src/client/common/application/commands/reloadCommand.ts index 312cb674e7df..6c7e350cae8a 100644 --- a/src/client/common/application/commands/reloadCommand.ts +++ b/src/client/common/application/commands/reloadCommand.ts @@ -4,7 +4,7 @@ 'use strict'; import { inject, injectable } from 'inversify'; -import { IExtensionSingleActivationService } from '../../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../../activation/types'; import { Common } from '../../utils/localize'; import { noop } from '../../utils/misc'; import { IApplicationShell, ICommandManager } from '../types'; @@ -14,6 +14,7 @@ import { IApplicationShell, ICommandManager } from '../types'; */ @injectable() export class ReloadVSCodeCommandHandler implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.common; constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, @inject(IApplicationShell) private readonly appShell: IApplicationShell, diff --git a/src/client/common/application/commands/reportIssueCommand.ts b/src/client/common/application/commands/reportIssueCommand.ts index 5ba5bdbd50ba..61083670cc2d 100644 --- a/src/client/common/application/commands/reportIssueCommand.ts +++ b/src/client/common/application/commands/reportIssueCommand.ts @@ -7,7 +7,7 @@ import * as fs from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; import { inject, injectable } from 'inversify'; -import { IExtensionSingleActivationService } from '../../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../../activation/types'; import { ICommandManager, IWorkspaceService } from '../types'; import { EXTENSION_ROOT_DIR } from '../../../constants'; import { IInterpreterService } from '../../../interpreter/contracts'; @@ -22,6 +22,8 @@ import { EnvironmentType } from '../../../pythonEnvironments/info'; */ @injectable() export class ReportIssueCommandHandler implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.common; + constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, @inject(IWorkspaceService) private readonly workspaceService: IWorkspaceService, diff --git a/src/client/common/application/debugSessionTelemetry.ts b/src/client/common/application/debugSessionTelemetry.ts index 5e4c67258988..031f7247facc 100644 --- a/src/client/common/application/debugSessionTelemetry.ts +++ b/src/client/common/application/debugSessionTelemetry.ts @@ -5,7 +5,7 @@ import { inject, injectable } from 'inversify'; import { DebugAdapterTracker, DebugAdapterTrackerFactory, DebugSession, ProviderResult } from 'vscode'; import { DebugProtocol } from 'vscode-debugprotocol'; -import { IExtensionSingleActivationService } from '../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../activation/types'; import { AttachRequestArguments, ConsoleType, LaunchRequestArguments, TriggerType } from '../../debugger/types'; import { sendTelemetryEvent } from '../../telemetry'; import { EventName } from '../../telemetry/constants'; @@ -62,6 +62,7 @@ class TelemetryTracker implements DebugAdapterTracker { @injectable() export class DebugSessionTelemetry implements DebugAdapterTrackerFactory, IExtensionSingleActivationService { + public readonly componentId = ComponentId.common; constructor( @inject(IDisposableRegistry) disposableRegistry: IDisposableRegistry, @inject(IDebugService) debugService: IDebugService, diff --git a/src/client/common/insidersBuild/insidersExtensionService.ts b/src/client/common/insidersBuild/insidersExtensionService.ts index 6a4d01f2c8e9..57df8c6b9aaa 100644 --- a/src/client/common/insidersBuild/insidersExtensionService.ts +++ b/src/client/common/insidersBuild/insidersExtensionService.ts @@ -6,7 +6,7 @@ import '../extensions'; import { inject, injectable, named } from 'inversify'; -import { IExtensionSingleActivationService } from '../../../client/activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../../client/activation/types'; import { IServiceContainer } from '../../ioc/types'; import { IApplicationEnvironment, ICommandManager } from '../application/types'; import { Commands, isTestExecution } from '../constants'; @@ -19,6 +19,7 @@ import { traceDecoratorError } from '../../logging'; @injectable() export class InsidersExtensionService implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.common; constructor( @inject(IExtensionChannelService) private readonly extensionChannelService: IExtensionChannelService, @inject(IInsiderExtensionPrompt) private readonly insidersPrompt: IInsiderExtensionPrompt, diff --git a/src/client/common/persistentState.ts b/src/client/common/persistentState.ts index 188a9b42c1d6..af6acfd31542 100644 --- a/src/client/common/persistentState.ts +++ b/src/client/common/persistentState.ts @@ -5,7 +5,7 @@ import { inject, injectable, named } from 'inversify'; import { Memento } from 'vscode'; -import { IExtensionSingleActivationService } from '../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; import { traceError, traceVerbose } from '../logging'; import { ICommandManager } from './application/types'; import { Commands } from './constants'; @@ -63,6 +63,7 @@ export type KeysStorage = { key: string; defaultValue: unknown }; @injectable() export class PersistentStateFactory implements IPersistentStateFactory, IExtensionSingleActivationService { + public readonly componentId = ComponentId.common; public readonly _globalKeysStorage = new PersistentState( this.globalState, GLOBAL_PERSISTENT_KEYS, diff --git a/src/client/debugger/extension/adapter/activator.ts b/src/client/debugger/extension/adapter/activator.ts index c7618c7ee146..9c3559880056 100644 --- a/src/client/debugger/extension/adapter/activator.ts +++ b/src/client/debugger/extension/adapter/activator.ts @@ -4,7 +4,7 @@ 'use strict'; import { inject, injectable } from 'inversify'; -import { IExtensionSingleActivationService } from '../../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../../activation/types'; import { IDebugService } from '../../../common/application/types'; import { IDisposableRegistry } from '../../../common/types'; import { DebuggerTypeName } from '../../constants'; @@ -13,6 +13,7 @@ import { IDebugAdapterDescriptorFactory, IDebugSessionLoggingFactory, IOutdatedD @injectable() export class DebugAdapterActivator implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; constructor( @inject(IDebugService) private readonly debugService: IDebugService, @inject(IDebugAdapterDescriptorFactory) private descriptorFactory: IDebugAdapterDescriptorFactory, diff --git a/src/client/debugger/extension/configuration/launch.json/completionProvider.ts b/src/client/debugger/extension/configuration/launch.json/completionProvider.ts index 73f062184670..7d229b9617e1 100644 --- a/src/client/debugger/extension/configuration/launch.json/completionProvider.ts +++ b/src/client/debugger/extension/configuration/launch.json/completionProvider.ts @@ -15,7 +15,7 @@ import { SnippetString, TextDocument, } from 'vscode'; -import { IExtensionSingleActivationService } from '../../../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../../../activation/types'; import { ILanguageService } from '../../../../common/application/types'; import { IDisposableRegistry } from '../../../../common/types'; import { DebugConfigStrings } from '../../../../common/utils/localize'; @@ -28,6 +28,7 @@ enum JsonLanguages { @injectable() export class LaunchJsonCompletionProvider implements CompletionItemProvider, IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; constructor( @inject(ILanguageService) private readonly languageService: ILanguageService, @inject(IDisposableRegistry) private readonly disposableRegistry: IDisposableRegistry, diff --git a/src/client/debugger/extension/configuration/launch.json/interpreterPathCommand.ts b/src/client/debugger/extension/configuration/launch.json/interpreterPathCommand.ts index d74d7779c8ff..fb230b9e2cfc 100644 --- a/src/client/debugger/extension/configuration/launch.json/interpreterPathCommand.ts +++ b/src/client/debugger/extension/configuration/launch.json/interpreterPathCommand.ts @@ -5,13 +5,14 @@ import { inject, injectable } from 'inversify'; import { Uri } from 'vscode'; -import { IExtensionSingleActivationService } from '../../../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../../../activation/types'; import { ICommandManager } from '../../../../common/application/types'; import { Commands } from '../../../../common/constants'; import { IConfigurationService, IDisposable, IDisposableRegistry } from '../../../../common/types'; @injectable() export class InterpreterPathCommand implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, @inject(IConfigurationService) private readonly configurationService: IConfigurationService, diff --git a/src/client/debugger/extension/configuration/launch.json/updaterService.ts b/src/client/debugger/extension/configuration/launch.json/updaterService.ts index bd91ca2f20c0..dc53af678a28 100644 --- a/src/client/debugger/extension/configuration/launch.json/updaterService.ts +++ b/src/client/debugger/extension/configuration/launch.json/updaterService.ts @@ -6,7 +6,7 @@ import { inject, injectable } from 'inversify'; import { createScanner, parse, SyntaxKind } from 'jsonc-parser'; import { CancellationToken, DebugConfiguration, Position, Range, TextDocument, WorkspaceEdit } from 'vscode'; -import { IExtensionSingleActivationService } from '../../../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../../../activation/types'; import { ICommandManager, IDocumentManager, IWorkspaceService } from '../../../../common/application/types'; import { IDisposableRegistry } from '../../../../common/types'; import { noop } from '../../../../common/utils/misc'; @@ -146,6 +146,7 @@ export class LaunchJsonUpdaterServiceHelper { @injectable() export class LaunchJsonUpdaterService implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, @inject(IDisposableRegistry) private readonly disposableRegistry: IDisposableRegistry, diff --git a/src/client/debugger/extension/debugCommands.ts b/src/client/debugger/extension/debugCommands.ts index 5d0e3ab7fbcc..3a4a35a43e61 100644 --- a/src/client/debugger/extension/debugCommands.ts +++ b/src/client/debugger/extension/debugCommands.ts @@ -4,7 +4,7 @@ import * as path from 'path'; import { inject, injectable } from 'inversify'; import { DebugConfiguration, Uri } from 'vscode'; -import { IExtensionSingleActivationService } from '../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../activation/types'; import { ICommandManager, IDebugService } from '../../common/application/types'; import { Commands } from '../../common/constants'; import { IDisposableRegistry } from '../../common/types'; @@ -15,6 +15,8 @@ import { DebugPurpose, LaunchRequestArguments } from '../types'; @injectable() export class DebugCommands implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; + constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, @inject(IDebugService) private readonly debugService: IDebugService, diff --git a/src/client/interpreter/display/progressDisplay.ts b/src/client/interpreter/display/progressDisplay.ts index d273b94801ac..ff1a092647a9 100644 --- a/src/client/interpreter/display/progressDisplay.ts +++ b/src/client/interpreter/display/progressDisplay.ts @@ -5,7 +5,7 @@ import { inject, injectable } from 'inversify'; import { Disposable, ProgressLocation, ProgressOptions } from 'vscode'; -import { IExtensionSingleActivationService } from '../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../activation/types'; import { IApplicationShell } from '../../common/application/types'; import { IDisposableRegistry } from '../../common/types'; import { createDeferred, Deferred } from '../../common/utils/async'; @@ -16,6 +16,8 @@ import { IComponentAdapter } from '../contracts'; // The parts of IComponentAdapter used here. @injectable() export class InterpreterLocatorProgressStatubarHandler implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.interpreter; + private deferred: Deferred | undefined; private isFirstTimeLoadingInterpreters = true; diff --git a/src/client/providers/codeActionProvider/main.ts b/src/client/providers/codeActionProvider/main.ts index b543d3a8baa5..aa57794bff48 100644 --- a/src/client/providers/codeActionProvider/main.ts +++ b/src/client/providers/codeActionProvider/main.ts @@ -3,12 +3,13 @@ import { inject, injectable } from 'inversify'; import * as vscodeTypes from 'vscode'; -import { IExtensionSingleActivationService } from '../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../activation/types'; import { IDisposableRegistry } from '../../common/types'; import { LaunchJsonCodeActionProvider } from './launchJsonCodeActionProvider'; @injectable() export class CodeActionProviderService implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; constructor(@inject(IDisposableRegistry) private disposableRegistry: IDisposableRegistry) {} public async activate(): Promise { const vscode = require('vscode') as typeof vscodeTypes; diff --git a/src/client/providers/linterProvider.ts b/src/client/providers/linterProvider.ts index 8be6be069154..eaf153151fd8 100644 --- a/src/client/providers/linterProvider.ts +++ b/src/client/providers/linterProvider.ts @@ -6,7 +6,7 @@ import { inject, injectable } from 'inversify'; import * as path from 'path'; import { ConfigurationChangeEvent, Disposable, TextDocument, Uri, workspace } from 'vscode'; -import { IExtensionActivationService } from '../activation/types'; +import { ComponentId, IExtensionActivationService } from '../activation/types'; import { IDocumentManager, IWorkspaceService } from '../common/application/types'; import { isTestExecution } from '../common/constants'; import '../common/extensions'; @@ -18,6 +18,7 @@ import { ILinterManager, ILintingEngine } from '../linters/types'; @injectable() export class LinterProvider implements IExtensionActivationService, Disposable { + public readonly componentId = ComponentId.other; private interpreterService: IInterpreterService; private documents: IDocumentManager; private configuration: IConfigurationService; diff --git a/src/client/telemetry/importTracker.ts b/src/client/telemetry/importTracker.ts index defa79b1ac02..727165da40ff 100644 --- a/src/client/telemetry/importTracker.ts +++ b/src/client/telemetry/importTracker.ts @@ -8,7 +8,7 @@ import * as path from 'path'; import { clearTimeout, setTimeout } from 'timers'; import { TextDocument } from 'vscode'; import { captureTelemetry, sendTelemetryEvent } from '.'; -import { IExtensionSingleActivationService } from '../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; import { IDocumentManager } from '../common/application/types'; import { isTestExecution } from '../common/constants'; import '../common/extensions'; @@ -47,6 +47,8 @@ const testExecution = isTestExecution(); @injectable() export class ImportTracker implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.common; + private pendingChecks = new Map(); private static sentMatches: Set = new Set(); diff --git a/src/client/tensorBoard/nbextensionCodeLensProvider.ts b/src/client/tensorBoard/nbextensionCodeLensProvider.ts index 1c477ab4a70a..d2a8c422fca6 100644 --- a/src/client/tensorBoard/nbextensionCodeLensProvider.ts +++ b/src/client/tensorBoard/nbextensionCodeLensProvider.ts @@ -4,7 +4,7 @@ import { inject, injectable } from 'inversify'; import { once } from 'lodash'; import { CancellationToken, CodeLens, Command, languages, Position, Range, TextDocument } from 'vscode'; -import { IExtensionSingleActivationService } from '../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; import { Commands, NotebookCellScheme, PYTHON_LANGUAGE } from '../common/constants'; import { NativeTensorBoard } from '../common/experiments/groups'; import { IDisposableRegistry, IExperimentService } from '../common/types'; @@ -16,6 +16,8 @@ import { containsNotebookExtension } from './helpers'; @injectable() export class TensorBoardNbextensionCodeLensProvider implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; + private sendTelemetryOnce = once( sendTelemetryEvent.bind(this, EventName.TENSORBOARD_ENTRYPOINT_SHOWN, undefined, { trigger: TensorBoardEntrypointTrigger.nbextension, diff --git a/src/client/tensorBoard/tensorBoardFileWatcher.ts b/src/client/tensorBoard/tensorBoardFileWatcher.ts index 4070e481fec3..040f1cc53ec9 100644 --- a/src/client/tensorBoard/tensorBoardFileWatcher.ts +++ b/src/client/tensorBoard/tensorBoardFileWatcher.ts @@ -3,7 +3,7 @@ import { inject, injectable } from 'inversify'; import { FileSystemWatcher, RelativePattern, WorkspaceFolder, WorkspaceFoldersChangeEvent } from 'vscode'; -import { IExtensionSingleActivationService } from '../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; import { IWorkspaceService } from '../common/application/types'; import { NativeTensorBoard } from '../common/experiments/groups'; import { IDisposableRegistry, IExperimentService } from '../common/types'; @@ -13,6 +13,8 @@ import { TensorBoardPrompt } from './tensorBoardPrompt'; @injectable() export class TensorBoardFileWatcher implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; + private fileSystemWatchers = new Map(); private globPatterns = ['*tfevents*', '*/*tfevents*', '*/*/*tfevents*']; diff --git a/src/client/tensorBoard/tensorBoardImportCodeLensProvider.ts b/src/client/tensorBoard/tensorBoardImportCodeLensProvider.ts index 81324feba6eb..16d59460c5ae 100644 --- a/src/client/tensorBoard/tensorBoardImportCodeLensProvider.ts +++ b/src/client/tensorBoard/tensorBoardImportCodeLensProvider.ts @@ -4,7 +4,7 @@ import { inject, injectable } from 'inversify'; import { once } from 'lodash'; import { CancellationToken, CodeLens, Command, languages, Position, Range, TextDocument } from 'vscode'; -import { IExtensionSingleActivationService } from '../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; import { Commands, PYTHON } from '../common/constants'; import { NativeTensorBoard } from '../common/experiments/groups'; import { IDisposableRegistry, IExperimentService } from '../common/types'; @@ -16,6 +16,8 @@ import { containsTensorBoardImport } from './helpers'; @injectable() export class TensorBoardImportCodeLensProvider implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; + private sendTelemetryOnce = once( sendTelemetryEvent.bind(this, EventName.TENSORBOARD_ENTRYPOINT_SHOWN, undefined, { trigger: TensorBoardEntrypointTrigger.fileimport, diff --git a/src/client/tensorBoard/tensorBoardSessionProvider.ts b/src/client/tensorBoard/tensorBoardSessionProvider.ts index 348c2910271d..d9aad6aa1580 100644 --- a/src/client/tensorBoard/tensorBoardSessionProvider.ts +++ b/src/client/tensorBoard/tensorBoardSessionProvider.ts @@ -3,7 +3,7 @@ import { inject, injectable } from 'inversify'; import { ViewColumn } from 'vscode'; -import { IExtensionSingleActivationService } from '../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; import { IApplicationShell, ICommandManager, IWorkspaceService } from '../common/application/types'; import { Commands } from '../common/constants'; import { ContextKey } from '../common/contextKey'; @@ -29,6 +29,8 @@ const PREFERRED_VIEWGROUP = 'PythonTensorBoardWebviewPreferredViewGroup'; @injectable() export class TensorBoardSessionProvider implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; + private knownSessions: TensorBoardSession[] = []; private preferredViewGroupMemento: IPersistentState; diff --git a/src/client/tensorBoard/tensorBoardUsageTracker.ts b/src/client/tensorBoard/tensorBoardUsageTracker.ts index 90f6ef7e9b32..42547c2516cb 100644 --- a/src/client/tensorBoard/tensorBoardUsageTracker.ts +++ b/src/client/tensorBoard/tensorBoardUsageTracker.ts @@ -4,7 +4,7 @@ import { inject, injectable } from 'inversify'; import * as path from 'path'; import { TextEditor } from 'vscode'; -import { IExtensionSingleActivationService } from '../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; import { IDocumentManager } from '../common/application/types'; import { isTestExecution } from '../common/constants'; import { NativeTensorBoard } from '../common/experiments/groups'; @@ -20,6 +20,8 @@ const testExecution = isTestExecution(); // contains a valid TensorBoard import. @injectable() export class TensorBoardUsageTracker implements IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; + constructor( @inject(IDocumentManager) private documentManager: IDocumentManager, @inject(IDisposableRegistry) private disposables: IDisposableRegistry, diff --git a/src/client/tensorBoard/terminalWatcher.ts b/src/client/tensorBoard/terminalWatcher.ts index 22412bfc0f9e..7403273391dc 100644 --- a/src/client/tensorBoard/terminalWatcher.ts +++ b/src/client/tensorBoard/terminalWatcher.ts @@ -1,6 +1,6 @@ import { inject, injectable } from 'inversify'; import { window } from 'vscode'; -import { IExtensionSingleActivationService } from '../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; import { IDisposable, IDisposableRegistry } from '../common/types'; import { sendTelemetryEvent } from '../telemetry'; import { EventName } from '../telemetry/constants'; @@ -8,6 +8,8 @@ import { EventName } from '../telemetry/constants'; // Every 5 min look, through active terminals to see if any are running `tensorboard` @injectable() export class TerminalWatcher implements IExtensionSingleActivationService, IDisposable { + public readonly componentId = ComponentId.other; + private handle: NodeJS.Timeout | undefined; constructor(@inject(IDisposableRegistry) private disposables: IDisposableRegistry) {} diff --git a/src/client/testing/common/updateTestSettings.ts b/src/client/testing/common/updateTestSettings.ts index 0fb65d56e3a3..a4ad3269fd4f 100644 --- a/src/client/testing/common/updateTestSettings.ts +++ b/src/client/testing/common/updateTestSettings.ts @@ -6,7 +6,7 @@ import { inject, injectable } from 'inversify'; import { applyEdits, findNodeAtLocation, getNodeValue, ModificationOptions, modify, parseTree } from 'jsonc-parser'; import * as path from 'path'; -import { IExtensionActivationService, LanguageServerType } from '../../activation/types'; +import { ComponentId, IExtensionActivationService, LanguageServerType } from '../../activation/types'; import { IApplicationEnvironment, IWorkspaceService } from '../../common/application/types'; import '../../common/extensions'; import { IFileSystem } from '../../common/platform/types'; @@ -17,6 +17,7 @@ import { traceDecoratorError, traceError } from '../../logging'; // TODO: rename the class since it is not used just for test settings @injectable() export class UpdateTestSettingService implements IExtensionActivationService { + public readonly componentId = ComponentId.other; constructor( @inject(IFileSystem) private readonly fs: IFileSystem, @inject(IApplicationEnvironment) private readonly application: IApplicationEnvironment, diff --git a/src/client/testing/main.ts b/src/client/testing/main.ts index bc4d69412a4e..31e8ae69499f 100644 --- a/src/client/testing/main.ts +++ b/src/client/testing/main.ts @@ -14,7 +14,7 @@ import { selectTestWorkspace } from './common/testUtils'; import { TestSettingsPropertyNames } from './configuration/types'; import { ITestConfigurationService, ITestsHelper } from './common/types'; import { ITestingService } from './types'; -import { IExtensionActivationService } from '../activation/types'; +import { ComponentId, IExtensionActivationService } from '../activation/types'; import { ITestController } from './testController/common/types'; import { DelayedTrigger, IDelayedTrigger } from '../common/utils/delayTrigger'; import { ExtensionContextKey } from '../common/application/contextKeys'; @@ -35,6 +35,7 @@ export class TestingService implements ITestingService { @injectable() export class UnitTestManagementService implements IExtensionActivationService { private activatedOnce: boolean = false; + public readonly componentId = ComponentId.other; private readonly disposableRegistry: Disposable[]; private workspaceService: IWorkspaceService; private context: IContextKeyManager; diff --git a/src/client/testing/testController/controller.ts b/src/client/testing/testController/controller.ts index bacdc8718337..60a9c3ea34db 100644 --- a/src/client/testing/testController/controller.ts +++ b/src/client/testing/testController/controller.ts @@ -16,7 +16,7 @@ import { Uri, EventEmitter, } from 'vscode'; -import { IExtensionSingleActivationService } from '../../activation/types'; +import { ComponentId, IExtensionSingleActivationService } from '../../activation/types'; import { IWorkspaceService } from '../../common/application/types'; import { IConfigurationService, IDisposableRegistry, Resource } from '../../common/types'; import { DelayedTrigger, IDelayedTrigger } from '../../common/utils/delayTrigger'; @@ -29,6 +29,8 @@ import { ITestController, ITestFrameworkController, TestRefreshOptions } from '. @injectable() export class PythonTestController implements ITestController, IExtensionSingleActivationService { + public readonly componentId = ComponentId.other; + private readonly testController: TestController; private readonly refreshData: IDelayedTrigger; From 58376ef4ec694283309ebef95cce52b5c76d8570 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 12 Nov 2021 07:21:57 -0800 Subject: [PATCH 15/18] Refactor --- src/client/activation/activationManager.ts | 24 ++++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/client/activation/activationManager.ts b/src/client/activation/activationManager.ts index 32bf387d3389..4a5fca2660c5 100644 --- a/src/client/activation/activationManager.ts +++ b/src/client/activation/activationManager.ts @@ -30,6 +30,8 @@ export class ExtensionActivationManager implements IExtensionActivationManager { private readonly disposables: IDisposable[] = []; + private readonly componentsToActivate: ComponentId[] | undefined; + private docOpenedHandler?: IDisposable; constructor( @@ -44,7 +46,11 @@ export class ExtensionActivationManager implements IExtensionActivationManager { @inject(IActiveResourceService) private readonly activeResourceService: IActiveResourceService, @inject(IExperimentService) private readonly experiments: IExperimentService, @inject(IInterpreterPathService) private readonly interpreterPathService: IInterpreterPathService, - ) {} + ) { + this.componentsToActivate = this.workspaceService.isVirtualWorkspace + ? [ComponentId.interpreter, ComponentId.languageServer, ComponentId.common] + : undefined; + } public dispose(): void { while (this.disposables.length > 0) { @@ -62,11 +68,9 @@ export class ExtensionActivationManager implements IExtensionActivationManager { // Activate all activation services together. - const singleActivationServices = this.workspaceService.isVirtualWorkspace - ? this.singleActivationServices.filter((s) => - [ComponentId.interpreter, ComponentId.languageServer, ComponentId.common].includes(s.componentId), - ) - : this.singleActivationServices; + const singleActivationServices = this.singleActivationServices.filter((s) => + this.componentsToActivate ? this.componentsToActivate.includes(s.componentId) : true, + ); await Promise.all([ ...singleActivationServices.map((item) => item.activate()), @@ -89,11 +93,9 @@ export class ExtensionActivationManager implements IExtensionActivationManager { await sendActivationTelemetry(this.fileSystem, this.workspaceService, resource); await this.autoSelection.autoSelectInterpreter(resource); - const activationServices = this.workspaceService.isVirtualWorkspace - ? this.activationServices.filter((s) => - [ComponentId.interpreter, ComponentId.languageServer, ComponentId.common].includes(s.componentId), - ) - : this.activationServices; + const activationServices = this.activationServices.filter((s) => + this.componentsToActivate ? this.componentsToActivate.includes(s.componentId) : true, + ); await Promise.all(activationServices.map((item) => item.activate(resource))); await this.appDiagnostics.performPreStartupHealthCheck(resource); } From 8f08a8e09b0f536d557662ec7779d1c192d28aad Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 12 Nov 2021 23:45:55 -0800 Subject: [PATCH 16/18] Use supported workspace types instead of component id --- src/client/activation/activationManager.ts | 31 +++++++------------ src/client/activation/activationService.ts | 3 +- .../common/loadLanguageServerExtension.ts | 4 +-- src/client/activation/extensionSurvey.ts | 4 +-- src/client/activation/types.ts | 11 ++----- .../application/commands/reloadCommand.ts | 4 +-- .../commands/reportIssueCommand.ts | 4 +-- .../application/debugSessionTelemetry.ts | 4 +-- .../insidersBuild/insidersExtensionService.ts | 4 +-- src/client/common/persistentState.ts | 4 +-- .../debugger/extension/adapter/activator.ts | 4 +-- .../launch.json/completionProvider.ts | 4 +-- .../launch.json/interpreterPathCommand.ts | 4 +-- .../launch.json/updaterService.ts | 4 +-- .../debugger/extension/debugCommands.ts | 4 +-- .../interpreterSelector/commands/base.ts | 4 +-- .../interpreter/display/progressDisplay.ts | 4 +-- .../virtualEnvs/condaInheritEnvPrompt.ts | 4 +-- .../virtualEnvs/virtualEnvPrompt.ts | 4 +-- .../providers/codeActionProvider/main.ts | 4 +-- src/client/providers/linterProvider.ts | 4 +-- src/client/telemetry/importTracker.ts | 4 +-- .../nbextensionCodeLensProvider.ts | 4 +-- .../tensorBoard/tensorBoardFileWatcher.ts | 4 +-- .../tensorBoardImportCodeLensProvider.ts | 4 +-- .../tensorBoard/tensorBoardSessionProvider.ts | 4 +-- .../tensorBoard/tensorBoardUsageTracker.ts | 4 +-- src/client/tensorBoard/terminalWatcher.ts | 4 +-- .../testing/common/updateTestSettings.ts | 4 +-- src/client/testing/main.ts | 4 +-- .../testing/testController/controller.ts | 4 +-- 31 files changed, 70 insertions(+), 87 deletions(-) diff --git a/src/client/activation/activationManager.ts b/src/client/activation/activationManager.ts index 4a5fca2660c5..20f51d33d57f 100644 --- a/src/client/activation/activationManager.ts +++ b/src/client/activation/activationManager.ts @@ -15,12 +15,7 @@ import { Deferred } from '../common/utils/async'; import { IInterpreterAutoSelectionService } from '../interpreter/autoSelection/types'; import { traceDecoratorError } from '../logging'; import { sendActivationTelemetry } from '../telemetry/envFileTelemetry'; -import { - ComponentId, - IExtensionActivationManager, - IExtensionActivationService, - IExtensionSingleActivationService, -} from './types'; +import { IExtensionActivationManager, IExtensionActivationService, IExtensionSingleActivationService } from './types'; @injectable() export class ExtensionActivationManager implements IExtensionActivationManager { @@ -30,8 +25,6 @@ export class ExtensionActivationManager implements IExtensionActivationManager { private readonly disposables: IDisposable[] = []; - private readonly componentsToActivate: ComponentId[] | undefined; - private docOpenedHandler?: IDisposable; constructor( @@ -47,9 +40,14 @@ export class ExtensionActivationManager implements IExtensionActivationManager { @inject(IExperimentService) private readonly experiments: IExperimentService, @inject(IInterpreterPathService) private readonly interpreterPathService: IInterpreterPathService, ) { - this.componentsToActivate = this.workspaceService.isVirtualWorkspace - ? [ComponentId.interpreter, ComponentId.languageServer, ComponentId.common] - : undefined; + if (this.workspaceService.isVirtualWorkspace) { + this.activationServices = this.activationServices.filter( + (service) => service.supportedWorkspaceTypes.virtualWorkspace, + ); + this.singleActivationServices = this.singleActivationServices.filter( + (service) => service.supportedWorkspaceTypes.virtualWorkspace, + ); + } } public dispose(): void { @@ -68,12 +66,8 @@ export class ExtensionActivationManager implements IExtensionActivationManager { // Activate all activation services together. - const singleActivationServices = this.singleActivationServices.filter((s) => - this.componentsToActivate ? this.componentsToActivate.includes(s.componentId) : true, - ); - await Promise.all([ - ...singleActivationServices.map((item) => item.activate()), + ...this.singleActivationServices.map((item) => item.activate()), this.activateWorkspace(this.activeResourceService.getActiveResource()), ]); } @@ -93,10 +87,7 @@ export class ExtensionActivationManager implements IExtensionActivationManager { await sendActivationTelemetry(this.fileSystem, this.workspaceService, resource); await this.autoSelection.autoSelectInterpreter(resource); - const activationServices = this.activationServices.filter((s) => - this.componentsToActivate ? this.componentsToActivate.includes(s.componentId) : true, - ); - await Promise.all(activationServices.map((item) => item.activate(resource))); + await Promise.all(this.activationServices.map((item) => item.activate(resource))); await this.appDiagnostics.performPreStartupHealthCheck(resource); } diff --git a/src/client/activation/activationService.ts b/src/client/activation/activationService.ts index 1ffae430ad62..d8189412c90b 100644 --- a/src/client/activation/activationService.ts +++ b/src/client/activation/activationService.ts @@ -25,7 +25,6 @@ import { EventName } from '../telemetry/constants'; import { LanguageServerChangeHandler } from './common/languageServerChangeHandler'; import { RefCountedLanguageServer } from './refCountedLanguageServer'; import { - ComponentId, IExtensionActivationService, ILanguageServerActivator, ILanguageServerCache, @@ -50,7 +49,7 @@ export class LanguageServerExtensionActivationService private activatedServer?: IActivatedServer; - public readonly componentId = ComponentId.languageServer; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: true, virtualWorkspace: true }; private readonly workspaceService: IWorkspaceService; diff --git a/src/client/activation/common/loadLanguageServerExtension.ts b/src/client/activation/common/loadLanguageServerExtension.ts index 170362692fa4..87fa5d9e6213 100644 --- a/src/client/activation/common/loadLanguageServerExtension.ts +++ b/src/client/activation/common/loadLanguageServerExtension.ts @@ -4,7 +4,7 @@ import { inject, injectable } from 'inversify'; import { ICommandManager } from '../../common/application/types'; import { IDisposableRegistry } from '../../common/types'; -import { ComponentId, IExtensionSingleActivationService } from '../types'; +import { IExtensionSingleActivationService } from '../types'; // This command is currently used by IntelliCode. This was used to // trigger MPLS. Since we no longer have MPLS we are going to set @@ -13,7 +13,7 @@ import { ComponentId, IExtensionSingleActivationService } from '../types'; @injectable() export class LoadLanguageServerExtension implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.languageServer; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: true, virtualWorkspace: true }; constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, diff --git a/src/client/activation/extensionSurvey.ts b/src/client/activation/extensionSurvey.ts index b1638e007aec..885893e9f54e 100644 --- a/src/client/activation/extensionSurvey.ts +++ b/src/client/activation/extensionSurvey.ts @@ -15,7 +15,7 @@ import { Common, ExtensionSurveyBanner } from '../common/utils/localize'; import { traceDecoratorError } from '../logging'; import { sendTelemetryEvent } from '../telemetry'; import { EventName } from '../telemetry/constants'; -import { ComponentId, IExtensionSingleActivationService } from './types'; +import { IExtensionSingleActivationService } from './types'; // persistent state names, exported to make use of in testing export enum extensionSurveyStateKeys { @@ -28,7 +28,7 @@ const WAIT_TIME_TO_SHOW_SURVEY = 1000 * 60 * 60 * 3; // 3 hours @injectable() export class ExtensionSurveyPrompt implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.common; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true }; constructor( @inject(IApplicationShell) private appShell: IApplicationShell, @inject(IBrowserService) private browserService: IBrowserService, diff --git a/src/client/activation/types.ts b/src/client/activation/types.ts index 18c3c4559af5..e90b8b8e88ee 100644 --- a/src/client/activation/types.ts +++ b/src/client/activation/types.ts @@ -58,7 +58,7 @@ export const IExtensionActivationService = Symbol('IExtensionActivationService') * @interface IExtensionActivationService */ export interface IExtensionActivationService { - componentId: ComponentId; + supportedWorkspaceTypes: { untrustedWorkspace: boolean; virtualWorkspace: boolean }; activate(resource: Resource): Promise; } @@ -169,13 +169,6 @@ export interface ILanguageServerOutputChannel { readonly channel: IOutputChannel; } -export enum ComponentId { - other = 0, - interpreter = 1, - languageServer = 2, - common = 3, -} - export const IExtensionSingleActivationService = Symbol('IExtensionSingleActivationService'); /** * Classes implementing this interface will have their `activate` methods @@ -186,6 +179,6 @@ export const IExtensionSingleActivationService = Symbol('IExtensionSingleActivat * @interface IExtensionSingleActivationService */ export interface IExtensionSingleActivationService { - componentId: ComponentId; + supportedWorkspaceTypes: { untrustedWorkspace: boolean; virtualWorkspace: boolean }; activate(): Promise; } diff --git a/src/client/common/application/commands/reloadCommand.ts b/src/client/common/application/commands/reloadCommand.ts index 6c7e350cae8a..fa07f212c5db 100644 --- a/src/client/common/application/commands/reloadCommand.ts +++ b/src/client/common/application/commands/reloadCommand.ts @@ -4,7 +4,7 @@ 'use strict'; import { inject, injectable } from 'inversify'; -import { ComponentId, IExtensionSingleActivationService } from '../../../activation/types'; +import { IExtensionSingleActivationService } from '../../../activation/types'; import { Common } from '../../utils/localize'; import { noop } from '../../utils/misc'; import { IApplicationShell, ICommandManager } from '../types'; @@ -14,7 +14,7 @@ import { IApplicationShell, ICommandManager } from '../types'; */ @injectable() export class ReloadVSCodeCommandHandler implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.common; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true }; constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, @inject(IApplicationShell) private readonly appShell: IApplicationShell, diff --git a/src/client/common/application/commands/reportIssueCommand.ts b/src/client/common/application/commands/reportIssueCommand.ts index 61083670cc2d..18c95f669d78 100644 --- a/src/client/common/application/commands/reportIssueCommand.ts +++ b/src/client/common/application/commands/reportIssueCommand.ts @@ -7,7 +7,7 @@ import * as fs from 'fs-extra'; import * as os from 'os'; import * as path from 'path'; import { inject, injectable } from 'inversify'; -import { ComponentId, IExtensionSingleActivationService } from '../../../activation/types'; +import { IExtensionSingleActivationService } from '../../../activation/types'; import { ICommandManager, IWorkspaceService } from '../types'; import { EXTENSION_ROOT_DIR } from '../../../constants'; import { IInterpreterService } from '../../../interpreter/contracts'; @@ -22,7 +22,7 @@ import { EnvironmentType } from '../../../pythonEnvironments/info'; */ @injectable() export class ReportIssueCommandHandler implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.common; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true }; constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, diff --git a/src/client/common/application/debugSessionTelemetry.ts b/src/client/common/application/debugSessionTelemetry.ts index 031f7247facc..2b1dd7f38917 100644 --- a/src/client/common/application/debugSessionTelemetry.ts +++ b/src/client/common/application/debugSessionTelemetry.ts @@ -5,7 +5,7 @@ import { inject, injectable } from 'inversify'; import { DebugAdapterTracker, DebugAdapterTrackerFactory, DebugSession, ProviderResult } from 'vscode'; import { DebugProtocol } from 'vscode-debugprotocol'; -import { ComponentId, IExtensionSingleActivationService } from '../../activation/types'; +import { IExtensionSingleActivationService } from '../../activation/types'; import { AttachRequestArguments, ConsoleType, LaunchRequestArguments, TriggerType } from '../../debugger/types'; import { sendTelemetryEvent } from '../../telemetry'; import { EventName } from '../../telemetry/constants'; @@ -62,7 +62,7 @@ class TelemetryTracker implements DebugAdapterTracker { @injectable() export class DebugSessionTelemetry implements DebugAdapterTrackerFactory, IExtensionSingleActivationService { - public readonly componentId = ComponentId.common; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true }; constructor( @inject(IDisposableRegistry) disposableRegistry: IDisposableRegistry, @inject(IDebugService) debugService: IDebugService, diff --git a/src/client/common/insidersBuild/insidersExtensionService.ts b/src/client/common/insidersBuild/insidersExtensionService.ts index 57df8c6b9aaa..4d9d91d4a1ca 100644 --- a/src/client/common/insidersBuild/insidersExtensionService.ts +++ b/src/client/common/insidersBuild/insidersExtensionService.ts @@ -6,7 +6,7 @@ import '../extensions'; import { inject, injectable, named } from 'inversify'; -import { ComponentId, IExtensionSingleActivationService } from '../../../client/activation/types'; +import { IExtensionSingleActivationService } from '../../../client/activation/types'; import { IServiceContainer } from '../../ioc/types'; import { IApplicationEnvironment, ICommandManager } from '../application/types'; import { Commands, isTestExecution } from '../constants'; @@ -19,7 +19,7 @@ import { traceDecoratorError } from '../../logging'; @injectable() export class InsidersExtensionService implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.common; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true }; constructor( @inject(IExtensionChannelService) private readonly extensionChannelService: IExtensionChannelService, @inject(IInsiderExtensionPrompt) private readonly insidersPrompt: IInsiderExtensionPrompt, diff --git a/src/client/common/persistentState.ts b/src/client/common/persistentState.ts index af6acfd31542..c72e3ab59e21 100644 --- a/src/client/common/persistentState.ts +++ b/src/client/common/persistentState.ts @@ -5,7 +5,7 @@ import { inject, injectable, named } from 'inversify'; import { Memento } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; +import { IExtensionSingleActivationService } from '../activation/types'; import { traceError, traceVerbose } from '../logging'; import { ICommandManager } from './application/types'; import { Commands } from './constants'; @@ -63,7 +63,7 @@ export type KeysStorage = { key: string; defaultValue: unknown }; @injectable() export class PersistentStateFactory implements IPersistentStateFactory, IExtensionSingleActivationService { - public readonly componentId = ComponentId.common; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true }; public readonly _globalKeysStorage = new PersistentState( this.globalState, GLOBAL_PERSISTENT_KEYS, diff --git a/src/client/debugger/extension/adapter/activator.ts b/src/client/debugger/extension/adapter/activator.ts index 9c3559880056..e46d673ea60c 100644 --- a/src/client/debugger/extension/adapter/activator.ts +++ b/src/client/debugger/extension/adapter/activator.ts @@ -4,7 +4,7 @@ 'use strict'; import { inject, injectable } from 'inversify'; -import { ComponentId, IExtensionSingleActivationService } from '../../../activation/types'; +import { IExtensionSingleActivationService } from '../../../activation/types'; import { IDebugService } from '../../../common/application/types'; import { IDisposableRegistry } from '../../../common/types'; import { DebuggerTypeName } from '../../constants'; @@ -13,7 +13,7 @@ import { IDebugAdapterDescriptorFactory, IDebugSessionLoggingFactory, IOutdatedD @injectable() export class DebugAdapterActivator implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; constructor( @inject(IDebugService) private readonly debugService: IDebugService, @inject(IDebugAdapterDescriptorFactory) private descriptorFactory: IDebugAdapterDescriptorFactory, diff --git a/src/client/debugger/extension/configuration/launch.json/completionProvider.ts b/src/client/debugger/extension/configuration/launch.json/completionProvider.ts index 7d229b9617e1..da6595c5bb2a 100644 --- a/src/client/debugger/extension/configuration/launch.json/completionProvider.ts +++ b/src/client/debugger/extension/configuration/launch.json/completionProvider.ts @@ -15,7 +15,7 @@ import { SnippetString, TextDocument, } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../../../../activation/types'; +import { IExtensionSingleActivationService } from '../../../../activation/types'; import { ILanguageService } from '../../../../common/application/types'; import { IDisposableRegistry } from '../../../../common/types'; import { DebugConfigStrings } from '../../../../common/utils/localize'; @@ -28,7 +28,7 @@ enum JsonLanguages { @injectable() export class LaunchJsonCompletionProvider implements CompletionItemProvider, IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; constructor( @inject(ILanguageService) private readonly languageService: ILanguageService, @inject(IDisposableRegistry) private readonly disposableRegistry: IDisposableRegistry, diff --git a/src/client/debugger/extension/configuration/launch.json/interpreterPathCommand.ts b/src/client/debugger/extension/configuration/launch.json/interpreterPathCommand.ts index fb230b9e2cfc..1c0354dd23f5 100644 --- a/src/client/debugger/extension/configuration/launch.json/interpreterPathCommand.ts +++ b/src/client/debugger/extension/configuration/launch.json/interpreterPathCommand.ts @@ -5,14 +5,14 @@ import { inject, injectable } from 'inversify'; import { Uri } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../../../../activation/types'; +import { IExtensionSingleActivationService } from '../../../../activation/types'; import { ICommandManager } from '../../../../common/application/types'; import { Commands } from '../../../../common/constants'; import { IConfigurationService, IDisposable, IDisposableRegistry } from '../../../../common/types'; @injectable() export class InterpreterPathCommand implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, @inject(IConfigurationService) private readonly configurationService: IConfigurationService, diff --git a/src/client/debugger/extension/configuration/launch.json/updaterService.ts b/src/client/debugger/extension/configuration/launch.json/updaterService.ts index dc53af678a28..a40076f497fb 100644 --- a/src/client/debugger/extension/configuration/launch.json/updaterService.ts +++ b/src/client/debugger/extension/configuration/launch.json/updaterService.ts @@ -6,7 +6,7 @@ import { inject, injectable } from 'inversify'; import { createScanner, parse, SyntaxKind } from 'jsonc-parser'; import { CancellationToken, DebugConfiguration, Position, Range, TextDocument, WorkspaceEdit } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../../../../activation/types'; +import { IExtensionSingleActivationService } from '../../../../activation/types'; import { ICommandManager, IDocumentManager, IWorkspaceService } from '../../../../common/application/types'; import { IDisposableRegistry } from '../../../../common/types'; import { noop } from '../../../../common/utils/misc'; @@ -146,7 +146,7 @@ export class LaunchJsonUpdaterServiceHelper { @injectable() export class LaunchJsonUpdaterService implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, @inject(IDisposableRegistry) private readonly disposableRegistry: IDisposableRegistry, diff --git a/src/client/debugger/extension/debugCommands.ts b/src/client/debugger/extension/debugCommands.ts index 3a4a35a43e61..071f246879ca 100644 --- a/src/client/debugger/extension/debugCommands.ts +++ b/src/client/debugger/extension/debugCommands.ts @@ -4,7 +4,7 @@ import * as path from 'path'; import { inject, injectable } from 'inversify'; import { DebugConfiguration, Uri } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../../activation/types'; +import { IExtensionSingleActivationService } from '../../activation/types'; import { ICommandManager, IDebugService } from '../../common/application/types'; import { Commands } from '../../common/constants'; import { IDisposableRegistry } from '../../common/types'; @@ -15,7 +15,7 @@ import { DebugPurpose, LaunchRequestArguments } from '../types'; @injectable() export class DebugCommands implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; constructor( @inject(ICommandManager) private readonly commandManager: ICommandManager, diff --git a/src/client/interpreter/configuration/interpreterSelector/commands/base.ts b/src/client/interpreter/configuration/interpreterSelector/commands/base.ts index 226677c36f62..7ecafae3a04c 100644 --- a/src/client/interpreter/configuration/interpreterSelector/commands/base.ts +++ b/src/client/interpreter/configuration/interpreterSelector/commands/base.ts @@ -6,7 +6,7 @@ import { injectable, unmanaged } from 'inversify'; import * as path from 'path'; import { ConfigurationTarget, Disposable, QuickPickItem, Uri } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../../../../activation/types'; +import { IExtensionSingleActivationService } from '../../../../activation/types'; import { IApplicationShell, ICommandManager, IWorkspaceService } from '../../../../common/application/types'; import { IDisposable, Resource } from '../../../../common/types'; import { Interpreters } from '../../../../common/utils/localize'; @@ -14,7 +14,7 @@ import { IPythonPathUpdaterServiceManager } from '../../types'; @injectable() export abstract class BaseInterpreterSelectorCommand implements IExtensionSingleActivationService, IDisposable { - public readonly componentId = ComponentId.interpreter; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true }; protected disposables: Disposable[] = []; constructor( @unmanaged() protected readonly pythonPathUpdaterService: IPythonPathUpdaterServiceManager, diff --git a/src/client/interpreter/display/progressDisplay.ts b/src/client/interpreter/display/progressDisplay.ts index ff1a092647a9..d641ae70d2c7 100644 --- a/src/client/interpreter/display/progressDisplay.ts +++ b/src/client/interpreter/display/progressDisplay.ts @@ -5,7 +5,7 @@ import { inject, injectable } from 'inversify'; import { Disposable, ProgressLocation, ProgressOptions } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../../activation/types'; +import { IExtensionSingleActivationService } from '../../activation/types'; import { IApplicationShell } from '../../common/application/types'; import { IDisposableRegistry } from '../../common/types'; import { createDeferred, Deferred } from '../../common/utils/async'; @@ -16,7 +16,7 @@ import { IComponentAdapter } from '../contracts'; // The parts of IComponentAdapter used here. @injectable() export class InterpreterLocatorProgressStatubarHandler implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.interpreter; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true }; private deferred: Deferred | undefined; diff --git a/src/client/interpreter/virtualEnvs/condaInheritEnvPrompt.ts b/src/client/interpreter/virtualEnvs/condaInheritEnvPrompt.ts index a5e84a21a43a..c842d5b2c45e 100644 --- a/src/client/interpreter/virtualEnvs/condaInheritEnvPrompt.ts +++ b/src/client/interpreter/virtualEnvs/condaInheritEnvPrompt.ts @@ -3,7 +3,7 @@ import { inject, injectable, optional } from 'inversify'; import { ConfigurationTarget, Uri } from 'vscode'; -import { ComponentId, IExtensionActivationService } from '../../activation/types'; +import { IExtensionActivationService } from '../../activation/types'; import { IApplicationShell, IWorkspaceService } from '../../common/application/types'; import { IPlatformService } from '../../common/platform/types'; import { IBrowserService, IPersistentStateFactory } from '../../common/types'; @@ -18,7 +18,7 @@ export const condaInheritEnvPromptKey = 'CONDA_INHERIT_ENV_PROMPT_KEY'; @injectable() export class CondaInheritEnvPrompt implements IExtensionActivationService { - public readonly componentId = ComponentId.interpreter; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true }; constructor( @inject(IInterpreterService) private readonly interpreterService: IInterpreterService, @inject(IWorkspaceService) private readonly workspaceService: IWorkspaceService, diff --git a/src/client/interpreter/virtualEnvs/virtualEnvPrompt.ts b/src/client/interpreter/virtualEnvs/virtualEnvPrompt.ts index 45dcc4dc5c4e..914a639e0314 100644 --- a/src/client/interpreter/virtualEnvs/virtualEnvPrompt.ts +++ b/src/client/interpreter/virtualEnvs/virtualEnvPrompt.ts @@ -3,7 +3,7 @@ import { inject, injectable } from 'inversify'; import { ConfigurationTarget, Disposable, Uri } from 'vscode'; -import { ComponentId, IExtensionActivationService } from '../../activation/types'; +import { IExtensionActivationService } from '../../activation/types'; import { IApplicationShell } from '../../common/application/types'; import { IDisposableRegistry, IPersistentStateFactory } from '../../common/types'; import { sleep } from '../../common/utils/async'; @@ -18,7 +18,7 @@ import { IComponentAdapter, IInterpreterHelper } from '../contracts'; const doNotDisplayPromptStateKey = 'MESSAGE_KEY_FOR_VIRTUAL_ENV'; @injectable() export class VirtualEnvironmentPrompt implements IExtensionActivationService { - public readonly componentId = ComponentId.interpreter; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true }; constructor( @inject(IPersistentStateFactory) private readonly persistentStateFactory: IPersistentStateFactory, diff --git a/src/client/providers/codeActionProvider/main.ts b/src/client/providers/codeActionProvider/main.ts index aa57794bff48..5e3b502a4a03 100644 --- a/src/client/providers/codeActionProvider/main.ts +++ b/src/client/providers/codeActionProvider/main.ts @@ -3,13 +3,13 @@ import { inject, injectable } from 'inversify'; import * as vscodeTypes from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../../activation/types'; +import { IExtensionSingleActivationService } from '../../activation/types'; import { IDisposableRegistry } from '../../common/types'; import { LaunchJsonCodeActionProvider } from './launchJsonCodeActionProvider'; @injectable() export class CodeActionProviderService implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; constructor(@inject(IDisposableRegistry) private disposableRegistry: IDisposableRegistry) {} public async activate(): Promise { const vscode = require('vscode') as typeof vscodeTypes; diff --git a/src/client/providers/linterProvider.ts b/src/client/providers/linterProvider.ts index eaf153151fd8..a694e0a891ad 100644 --- a/src/client/providers/linterProvider.ts +++ b/src/client/providers/linterProvider.ts @@ -6,7 +6,7 @@ import { inject, injectable } from 'inversify'; import * as path from 'path'; import { ConfigurationChangeEvent, Disposable, TextDocument, Uri, workspace } from 'vscode'; -import { ComponentId, IExtensionActivationService } from '../activation/types'; +import { IExtensionActivationService } from '../activation/types'; import { IDocumentManager, IWorkspaceService } from '../common/application/types'; import { isTestExecution } from '../common/constants'; import '../common/extensions'; @@ -18,7 +18,7 @@ import { ILinterManager, ILintingEngine } from '../linters/types'; @injectable() export class LinterProvider implements IExtensionActivationService, Disposable { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; private interpreterService: IInterpreterService; private documents: IDocumentManager; private configuration: IConfigurationService; diff --git a/src/client/telemetry/importTracker.ts b/src/client/telemetry/importTracker.ts index 727165da40ff..39f278bef9bb 100644 --- a/src/client/telemetry/importTracker.ts +++ b/src/client/telemetry/importTracker.ts @@ -8,7 +8,7 @@ import * as path from 'path'; import { clearTimeout, setTimeout } from 'timers'; import { TextDocument } from 'vscode'; import { captureTelemetry, sendTelemetryEvent } from '.'; -import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; +import { IExtensionSingleActivationService } from '../activation/types'; import { IDocumentManager } from '../common/application/types'; import { isTestExecution } from '../common/constants'; import '../common/extensions'; @@ -47,7 +47,7 @@ const testExecution = isTestExecution(); @injectable() export class ImportTracker implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.common; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: true }; private pendingChecks = new Map(); diff --git a/src/client/tensorBoard/nbextensionCodeLensProvider.ts b/src/client/tensorBoard/nbextensionCodeLensProvider.ts index d2a8c422fca6..986e1c74457f 100644 --- a/src/client/tensorBoard/nbextensionCodeLensProvider.ts +++ b/src/client/tensorBoard/nbextensionCodeLensProvider.ts @@ -4,7 +4,7 @@ import { inject, injectable } from 'inversify'; import { once } from 'lodash'; import { CancellationToken, CodeLens, Command, languages, Position, Range, TextDocument } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; +import { IExtensionSingleActivationService } from '../activation/types'; import { Commands, NotebookCellScheme, PYTHON_LANGUAGE } from '../common/constants'; import { NativeTensorBoard } from '../common/experiments/groups'; import { IDisposableRegistry, IExperimentService } from '../common/types'; @@ -16,7 +16,7 @@ import { containsNotebookExtension } from './helpers'; @injectable() export class TensorBoardNbextensionCodeLensProvider implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; private sendTelemetryOnce = once( sendTelemetryEvent.bind(this, EventName.TENSORBOARD_ENTRYPOINT_SHOWN, undefined, { diff --git a/src/client/tensorBoard/tensorBoardFileWatcher.ts b/src/client/tensorBoard/tensorBoardFileWatcher.ts index 040f1cc53ec9..e35a021db321 100644 --- a/src/client/tensorBoard/tensorBoardFileWatcher.ts +++ b/src/client/tensorBoard/tensorBoardFileWatcher.ts @@ -3,7 +3,7 @@ import { inject, injectable } from 'inversify'; import { FileSystemWatcher, RelativePattern, WorkspaceFolder, WorkspaceFoldersChangeEvent } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; +import { IExtensionSingleActivationService } from '../activation/types'; import { IWorkspaceService } from '../common/application/types'; import { NativeTensorBoard } from '../common/experiments/groups'; import { IDisposableRegistry, IExperimentService } from '../common/types'; @@ -13,7 +13,7 @@ import { TensorBoardPrompt } from './tensorBoardPrompt'; @injectable() export class TensorBoardFileWatcher implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; private fileSystemWatchers = new Map(); diff --git a/src/client/tensorBoard/tensorBoardImportCodeLensProvider.ts b/src/client/tensorBoard/tensorBoardImportCodeLensProvider.ts index 16d59460c5ae..6ad000dfdd7d 100644 --- a/src/client/tensorBoard/tensorBoardImportCodeLensProvider.ts +++ b/src/client/tensorBoard/tensorBoardImportCodeLensProvider.ts @@ -4,7 +4,7 @@ import { inject, injectable } from 'inversify'; import { once } from 'lodash'; import { CancellationToken, CodeLens, Command, languages, Position, Range, TextDocument } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; +import { IExtensionSingleActivationService } from '../activation/types'; import { Commands, PYTHON } from '../common/constants'; import { NativeTensorBoard } from '../common/experiments/groups'; import { IDisposableRegistry, IExperimentService } from '../common/types'; @@ -16,7 +16,7 @@ import { containsTensorBoardImport } from './helpers'; @injectable() export class TensorBoardImportCodeLensProvider implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; private sendTelemetryOnce = once( sendTelemetryEvent.bind(this, EventName.TENSORBOARD_ENTRYPOINT_SHOWN, undefined, { diff --git a/src/client/tensorBoard/tensorBoardSessionProvider.ts b/src/client/tensorBoard/tensorBoardSessionProvider.ts index d9aad6aa1580..bc4b9d1130e8 100644 --- a/src/client/tensorBoard/tensorBoardSessionProvider.ts +++ b/src/client/tensorBoard/tensorBoardSessionProvider.ts @@ -3,7 +3,7 @@ import { inject, injectable } from 'inversify'; import { ViewColumn } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; +import { IExtensionSingleActivationService } from '../activation/types'; import { IApplicationShell, ICommandManager, IWorkspaceService } from '../common/application/types'; import { Commands } from '../common/constants'; import { ContextKey } from '../common/contextKey'; @@ -29,7 +29,7 @@ const PREFERRED_VIEWGROUP = 'PythonTensorBoardWebviewPreferredViewGroup'; @injectable() export class TensorBoardSessionProvider implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; private knownSessions: TensorBoardSession[] = []; diff --git a/src/client/tensorBoard/tensorBoardUsageTracker.ts b/src/client/tensorBoard/tensorBoardUsageTracker.ts index 42547c2516cb..423be8868e30 100644 --- a/src/client/tensorBoard/tensorBoardUsageTracker.ts +++ b/src/client/tensorBoard/tensorBoardUsageTracker.ts @@ -4,7 +4,7 @@ import { inject, injectable } from 'inversify'; import * as path from 'path'; import { TextEditor } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; +import { IExtensionSingleActivationService } from '../activation/types'; import { IDocumentManager } from '../common/application/types'; import { isTestExecution } from '../common/constants'; import { NativeTensorBoard } from '../common/experiments/groups'; @@ -20,7 +20,7 @@ const testExecution = isTestExecution(); // contains a valid TensorBoard import. @injectable() export class TensorBoardUsageTracker implements IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; constructor( @inject(IDocumentManager) private documentManager: IDocumentManager, diff --git a/src/client/tensorBoard/terminalWatcher.ts b/src/client/tensorBoard/terminalWatcher.ts index 7403273391dc..5aadc12dc4c0 100644 --- a/src/client/tensorBoard/terminalWatcher.ts +++ b/src/client/tensorBoard/terminalWatcher.ts @@ -1,6 +1,6 @@ import { inject, injectable } from 'inversify'; import { window } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../activation/types'; +import { IExtensionSingleActivationService } from '../activation/types'; import { IDisposable, IDisposableRegistry } from '../common/types'; import { sendTelemetryEvent } from '../telemetry'; import { EventName } from '../telemetry/constants'; @@ -8,7 +8,7 @@ import { EventName } from '../telemetry/constants'; // Every 5 min look, through active terminals to see if any are running `tensorboard` @injectable() export class TerminalWatcher implements IExtensionSingleActivationService, IDisposable { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; private handle: NodeJS.Timeout | undefined; diff --git a/src/client/testing/common/updateTestSettings.ts b/src/client/testing/common/updateTestSettings.ts index a4ad3269fd4f..c7dd5b182373 100644 --- a/src/client/testing/common/updateTestSettings.ts +++ b/src/client/testing/common/updateTestSettings.ts @@ -6,7 +6,7 @@ import { inject, injectable } from 'inversify'; import { applyEdits, findNodeAtLocation, getNodeValue, ModificationOptions, modify, parseTree } from 'jsonc-parser'; import * as path from 'path'; -import { ComponentId, IExtensionActivationService, LanguageServerType } from '../../activation/types'; +import { IExtensionActivationService, LanguageServerType } from '../../activation/types'; import { IApplicationEnvironment, IWorkspaceService } from '../../common/application/types'; import '../../common/extensions'; import { IFileSystem } from '../../common/platform/types'; @@ -17,7 +17,7 @@ import { traceDecoratorError, traceError } from '../../logging'; // TODO: rename the class since it is not used just for test settings @injectable() export class UpdateTestSettingService implements IExtensionActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; constructor( @inject(IFileSystem) private readonly fs: IFileSystem, @inject(IApplicationEnvironment) private readonly application: IApplicationEnvironment, diff --git a/src/client/testing/main.ts b/src/client/testing/main.ts index 31e8ae69499f..482538a38789 100644 --- a/src/client/testing/main.ts +++ b/src/client/testing/main.ts @@ -14,7 +14,7 @@ import { selectTestWorkspace } from './common/testUtils'; import { TestSettingsPropertyNames } from './configuration/types'; import { ITestConfigurationService, ITestsHelper } from './common/types'; import { ITestingService } from './types'; -import { ComponentId, IExtensionActivationService } from '../activation/types'; +import { IExtensionActivationService } from '../activation/types'; import { ITestController } from './testController/common/types'; import { DelayedTrigger, IDelayedTrigger } from '../common/utils/delayTrigger'; import { ExtensionContextKey } from '../common/application/contextKeys'; @@ -35,7 +35,7 @@ export class TestingService implements ITestingService { @injectable() export class UnitTestManagementService implements IExtensionActivationService { private activatedOnce: boolean = false; - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; private readonly disposableRegistry: Disposable[]; private workspaceService: IWorkspaceService; private context: IContextKeyManager; diff --git a/src/client/testing/testController/controller.ts b/src/client/testing/testController/controller.ts index 60a9c3ea34db..91d0f4427a10 100644 --- a/src/client/testing/testController/controller.ts +++ b/src/client/testing/testController/controller.ts @@ -16,7 +16,7 @@ import { Uri, EventEmitter, } from 'vscode'; -import { ComponentId, IExtensionSingleActivationService } from '../../activation/types'; +import { IExtensionSingleActivationService } from '../../activation/types'; import { IWorkspaceService } from '../../common/application/types'; import { IConfigurationService, IDisposableRegistry, Resource } from '../../common/types'; import { DelayedTrigger, IDelayedTrigger } from '../../common/utils/delayTrigger'; @@ -29,7 +29,7 @@ import { ITestController, ITestFrameworkController, TestRefreshOptions } from '. @injectable() export class PythonTestController implements ITestController, IExtensionSingleActivationService { - public readonly componentId = ComponentId.other; + public readonly supportedWorkspaceTypes = { untrustedWorkspace: false, virtualWorkspace: false }; private readonly testController: TestController; From 7ba6dd87193556153a15f4c5bed55ac51321ced7 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Fri, 12 Nov 2021 23:50:23 -0800 Subject: [PATCH 17/18] Fix lint --- .../extension/configuration/launch.json/updaterService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/debugger/extension/configuration/launch.json/updaterService.ts b/src/client/debugger/extension/configuration/launch.json/updaterService.ts index a40076f497fb..232d068cc47b 100644 --- a/src/client/debugger/extension/configuration/launch.json/updaterService.ts +++ b/src/client/debugger/extension/configuration/launch.json/updaterService.ts @@ -6,7 +6,7 @@ import { inject, injectable } from 'inversify'; import { createScanner, parse, SyntaxKind } from 'jsonc-parser'; import { CancellationToken, DebugConfiguration, Position, Range, TextDocument, WorkspaceEdit } from 'vscode'; -import { IExtensionSingleActivationService } from '../../../../activation/types'; +import { IExtensionSingleActivationService } from '../../../../activation/types'; import { ICommandManager, IDocumentManager, IWorkspaceService } from '../../../../common/application/types'; import { IDisposableRegistry } from '../../../../common/types'; import { noop } from '../../../../common/utils/misc'; From ef6f0a0874353ae1c463625cb2a095bf514e44f1 Mon Sep 17 00:00:00 2001 From: Kartik Raj Date: Tue, 16 Nov 2021 05:04:10 -0800 Subject: [PATCH 18/18] Code reviwes --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 903f94762c61..ceb16847f634 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, "virtualWorkspaces": { "supported": "limited", - "description": "Limited support on the web." + "description": "Only Partial IntelliSense supported." } }, "languageServerVersion": "0.5.30",