From b11a544371a031013b205b5c931d15f3df9ebb6b Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 12:13:50 -0600 Subject: [PATCH 01/31] Add an IOC proxy for PythonInterpreterLocatorService. --- .../discovery/locators/index.ts | 7 ++-- src/client/pythonEnvironments/legacyIOC.ts | 35 +++++++++++++++++-- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/index.ts b/src/client/pythonEnvironments/discovery/locators/index.ts index 4b2a5188c235..40591b183d5c 100644 --- a/src/client/pythonEnvironments/discovery/locators/index.ts +++ b/src/client/pythonEnvironments/discovery/locators/index.ts @@ -1,8 +1,7 @@ -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import { Disposable, Event, EventEmitter, Uri } from 'vscode'; import { traceDecorators } from '../../../common/logger'; import { IPlatformService } from '../../../common/platform/types'; -import { IDisposableRegistry } from '../../../common/types'; import { createDeferred, Deferred } from '../../../common/utils/async'; import { OSType } from '../../../common/utils/platform'; import { @@ -28,8 +27,7 @@ const flatten = require('lodash/flatten') as typeof import('lodash/flatten'); /** * Facilitates locating Python interpreters. */ -@injectable() -export class PythonInterpreterLocatorService implements IInterpreterLocatorService { +export class PythonInterpreterLocatorService { public didTriggerInterpreterSuggestions: boolean; private readonly disposables: Disposable[] = []; @@ -39,7 +37,6 @@ export class PythonInterpreterLocatorService implements IInterpreterLocatorServi constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) { this._hasInterpreters = createDeferred(); - serviceContainer.get(IDisposableRegistry).push(this); this.platform = serviceContainer.get(IPlatformService); this.interpreterLocatorHelper = serviceContainer.get(IInterpreterLocatorHelper); this.didTriggerInterpreterSuggestions = false; diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 5f4517bc7a21..ead4f542beb7 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -1,6 +1,11 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// tslint:disable:no-use-before-declare + +import { inject, injectable } from 'inversify'; +import { Disposable, Event, Uri } from 'vscode'; +import { IDisposableRegistry } from '../common/types'; import { CONDA_ENV_FILE_SERVICE, CONDA_ENV_SERVICE, @@ -21,7 +26,7 @@ import { WORKSPACE_VIRTUAL_ENV_SERVICE } from '../interpreter/contracts'; import { IPipEnvServiceHelper, IPythonInPathCommandProvider } from '../interpreter/locators/types'; -import { IServiceManager } from '../ioc/types'; +import { IServiceContainer, IServiceManager } from '../ioc/types'; import { PythonInterpreterLocatorService } from './discovery/locators'; import { InterpreterLocatorHelper } from './discovery/locators/helpers'; import { InterpreterLocatorProgressService } from './discovery/locators/progressService'; @@ -46,12 +51,14 @@ import { WorkspaceVirtualEnvService } from './discovery/locators/services/workspaceVirtualEnvService'; import { WorkspaceVirtualEnvWatcherService } from './discovery/locators/services/workspaceVirtualEnvWatcherService'; +import { GetInterpreterLocatorOptions } from './discovery/locators/types'; +import { PythonInterpreter } from './info'; export function registerForIOC(serviceManager: IServiceManager) { serviceManager.addSingleton(IInterpreterLocatorHelper, InterpreterLocatorHelper); serviceManager.addSingleton( IInterpreterLocatorService, - PythonInterpreterLocatorService, + PythonInterpreterLocatorServiceProxy, INTERPRETER_LOCATOR_SERVICE ); serviceManager.addSingleton( @@ -129,3 +136,27 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton(IInterpreterWatcherBuilder, InterpreterWatcherBuilder); } + +@injectable() +class PythonInterpreterLocatorServiceProxy implements IInterpreterLocatorService { + private readonly impl: IInterpreterLocatorService; + constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { + this.impl = new PythonInterpreterLocatorService(serviceContainer); + serviceContainer.get(IDisposableRegistry).push(this.impl); + } + public dispose() { + this.impl.dispose(); + } + public get onLocating(): Event> { + return this.impl.onLocating; + } + public get hasInterpreters(): Promise { + return this.impl.hasInterpreters; + } + public get didTriggerInterpreterSuggestions(): boolean | undefined { + return this.impl.didTriggerInterpreterSuggestions; + } + public async getInterpreters(resource?: Uri, options?: GetInterpreterLocatorOptions): Promise { + return this.impl.getInterpreters(resource, options); + } +} From 519e3cdc10d2b102232543b8ba51746e0025ac36 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 12:19:16 -0600 Subject: [PATCH 02/31] Add an IOC proxy for InterpreterLocatorHelper. --- .../discovery/locators/helpers.ts | 6 ++---- src/client/pythonEnvironments/legacyIOC.ts | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/helpers.ts b/src/client/pythonEnvironments/discovery/locators/helpers.ts index 2d543840dc65..f1d259671b46 100644 --- a/src/client/pythonEnvironments/discovery/locators/helpers.ts +++ b/src/client/pythonEnvironments/discovery/locators/helpers.ts @@ -1,10 +1,9 @@ import * as fsapi from 'fs-extra'; -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import * as path from 'path'; import { traceError } from '../../../common/logger'; import { IS_WINDOWS } from '../../../common/platform/constants'; import { IFileSystem } from '../../../common/platform/types'; -import { IInterpreterLocatorHelper } from '../../../interpreter/contracts'; import { IPipEnvServiceHelper } from '../../../interpreter/locators/types'; import { InterpreterType, PythonInterpreter } from '../../info'; @@ -26,8 +25,7 @@ export async function lookForInterpretersInDirectory(pathToCheck: string, _: IFi } } -@injectable() -export class InterpreterLocatorHelper implements IInterpreterLocatorHelper { +export class InterpreterLocatorHelper { constructor( @inject(IFileSystem) private readonly fs: IFileSystem, @inject(IPipEnvServiceHelper) private readonly pipEnvServiceHelper: IPipEnvServiceHelper diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index ead4f542beb7..c41a71feee3a 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -5,6 +5,7 @@ import { inject, injectable } from 'inversify'; import { Disposable, Event, Uri } from 'vscode'; +import { IFileSystem } from '../common/platform/types'; import { IDisposableRegistry } from '../common/types'; import { CONDA_ENV_FILE_SERVICE, @@ -55,7 +56,7 @@ import { GetInterpreterLocatorOptions } from './discovery/locators/types'; import { PythonInterpreter } from './info'; export function registerForIOC(serviceManager: IServiceManager) { - serviceManager.addSingleton(IInterpreterLocatorHelper, InterpreterLocatorHelper); + serviceManager.addSingleton(IInterpreterLocatorHelper, InterpreterLocatorHelperProxy); serviceManager.addSingleton( IInterpreterLocatorService, PythonInterpreterLocatorServiceProxy, @@ -160,3 +161,17 @@ class PythonInterpreterLocatorServiceProxy implements IInterpreterLocatorService return this.impl.getInterpreters(resource, options); } } + +@injectable() +class InterpreterLocatorHelperProxy implements IInterpreterLocatorHelper { + private readonly impl: IInterpreterLocatorHelper; + constructor( + @inject(IFileSystem) fs: IFileSystem, + @inject(IPipEnvServiceHelper) pipEnvServiceHelper: IPipEnvServiceHelper + ) { + this.impl = new InterpreterLocatorHelper(fs, pipEnvServiceHelper); + } + public async mergeInterpreters(interpreters: PythonInterpreter[]): Promise { + return this.impl.mergeInterpreters(interpreters); + } +} From f822802e9f429ff9366f137019ac3aec338c52b0 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 12:23:39 -0600 Subject: [PATCH 03/31] Add an IOC proxy for InterpreterLocatorProgressService. --- .../discovery/locators/progressService.ts | 7 +++--- src/client/pythonEnvironments/legacyIOC.ts | 23 ++++++++++++++++++- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/progressService.ts b/src/client/pythonEnvironments/discovery/locators/progressService.ts index ed6a48f282f0..37ad078060cf 100644 --- a/src/client/pythonEnvironments/discovery/locators/progressService.ts +++ b/src/client/pythonEnvironments/discovery/locators/progressService.ts @@ -3,18 +3,17 @@ 'use strict'; -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import { Disposable, Event, EventEmitter } from 'vscode'; import { traceDecorators } from '../../../common/logger'; import { IDisposableRegistry } from '../../../common/types'; import { createDeferredFrom, Deferred } from '../../../common/utils/async'; import { noop } from '../../../common/utils/misc'; -import { IInterpreterLocatorProgressService, IInterpreterLocatorService } from '../../../interpreter/contracts'; +import { IInterpreterLocatorService } from '../../../interpreter/contracts'; import { IServiceContainer } from '../../../ioc/types'; import { PythonInterpreter } from '../../info'; -@injectable() -export class InterpreterLocatorProgressService implements IInterpreterLocatorProgressService { +export class InterpreterLocatorProgressService { private deferreds: Deferred[] = []; private readonly refreshing = new EventEmitter(); private readonly refreshed = new EventEmitter(); diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index c41a71feee3a..4ff605321409 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -64,7 +64,7 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton( IInterpreterLocatorProgressService, - InterpreterLocatorProgressService + InterpreterLocatorProgressServiceProxy ); serviceManager.addSingleton( IInterpreterLocatorService, @@ -175,3 +175,24 @@ class InterpreterLocatorHelperProxy implements IInterpreterLocatorHelper { return this.impl.mergeInterpreters(interpreters); } } + +@injectable() +class InterpreterLocatorProgressServiceProxy implements IInterpreterLocatorProgressService { + private readonly impl: IInterpreterLocatorProgressService; + constructor( + @inject(IServiceContainer) serviceContainer: IServiceContainer, + @inject(IDisposableRegistry) disposables: Disposable[] + ) { + this.impl = new InterpreterLocatorProgressService(serviceContainer, disposables); + } + + public get onRefreshing(): Event { + return this.impl.onRefreshing; + } + public get onRefreshed(): Event { + return this.impl.onRefreshed; + } + public register(): void { + this.impl.register(); + } +} From d5be551aa0e5dc0d80e25a60d37d2c7425e8018d Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:01:26 -0600 Subject: [PATCH 04/31] Add an IOC proxy for InterpreterHashProviderFactory. --- src/client/interpreter/helpers.ts | 3 +- src/client/interpreter/interpreterService.ts | 3 +- src/client/interpreter/locators/types.ts | 1 + .../locators/services/hashProviderFactory.ts | 11 ++--- src/client/pythonEnvironments/legacyIOC.ts | 41 +++++++++++++++---- .../locators/hasProviderFactory.unit.test.ts | 6 +-- .../pythonEnvironments/legacyIOC.unit.test.ts | 10 +++-- 7 files changed, 50 insertions(+), 25 deletions(-) diff --git a/src/client/interpreter/helpers.ts b/src/client/interpreter/helpers.ts index 030c54f98f6c..1eb9c8ccd18d 100644 --- a/src/client/interpreter/helpers.ts +++ b/src/client/interpreter/helpers.ts @@ -7,7 +7,6 @@ import { IPythonExecutionFactory } from '../common/process/types'; import { IPersistentStateFactory, Resource } from '../common/types'; import { IServiceContainer } from '../ioc/types'; import { isMacDefaultPythonPath } from '../pythonEnvironments/discovery'; -import { InterpeterHashProviderFactory } from '../pythonEnvironments/discovery/locators/services/hashProviderFactory'; import { getInterpreterTypeName, InterpreterInformation, @@ -49,7 +48,7 @@ export class InterpreterHelper implements IInterpreterHelper { private readonly persistentFactory: IPersistentStateFactory; constructor( @inject(IServiceContainer) private serviceContainer: IServiceContainer, - @inject(InterpeterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory + @inject(IInterpreterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory ) { this.persistentFactory = this.serviceContainer.get(IPersistentStateFactory); } diff --git a/src/client/interpreter/interpreterService.ts b/src/client/interpreter/interpreterService.ts index 2304c6b587cc..d268ec8a58f1 100644 --- a/src/client/interpreter/interpreterService.ts +++ b/src/client/interpreter/interpreterService.ts @@ -20,7 +20,6 @@ import { } from '../common/types'; import { sleep } from '../common/utils/async'; import { IServiceContainer } from '../ioc/types'; -import { InterpeterHashProviderFactory } from '../pythonEnvironments/discovery/locators/services/hashProviderFactory'; import { InterpreterType, PythonInterpreter } from '../pythonEnvironments/info'; import { captureTelemetry } from '../telemetry'; import { EventName } from '../telemetry/constants'; @@ -70,7 +69,7 @@ export class InterpreterService implements Disposable, IInterpreterService { constructor( @inject(IServiceContainer) private serviceContainer: IServiceContainer, - @inject(InterpeterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory + @inject(IInterpreterHashProviderFactory) private readonly hashProviderFactory: IInterpreterHashProviderFactory ) { this.locator = serviceContainer.get( IInterpreterLocatorService, diff --git a/src/client/interpreter/locators/types.ts b/src/client/interpreter/locators/types.ts index f39589800074..7bd524bedb9a 100644 --- a/src/client/interpreter/locators/types.ts +++ b/src/client/interpreter/locators/types.ts @@ -15,6 +15,7 @@ export interface IPipEnvServiceHelper { trackWorkspaceFolder(pythonPath: string, workspaceFolder: Uri): Promise; } +export const IInterpreterHashProviderFactory = Symbol('IInterpreterHashProviderFactory'); /** * Factory to create a hash provider. * Getting the hash of an interpreter can vary based on the type of the interpreter. diff --git a/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts b/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts index 31d012e7422a..b58fd3696fc2 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts @@ -3,19 +3,14 @@ 'use strict'; -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import { Uri } from 'vscode'; import { IConfigurationService } from '../../../../common/types'; -import { - IInterpreterHashProvider, - IInterpreterHashProviderFactory, - IWindowsStoreInterpreter -} from '../../../../interpreter/locators/types'; +import { IInterpreterHashProvider, IWindowsStoreInterpreter } from '../../../../interpreter/locators/types'; import { InterpreterHashProvider } from './hashProvider'; import { WindowsStoreInterpreter } from './windowsStoreInterpreter'; -@injectable() -export class InterpeterHashProviderFactory implements IInterpreterHashProviderFactory { +export class InterpreterHashProviderFactory { constructor( @inject(IConfigurationService) private readonly configService: IConfigurationService, @inject(WindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter, diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 4ff605321409..4ce1203b9ac7 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -1,12 +1,12 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// tslint:disable:no-use-before-declare +// tslint:disable:no-use-before-declare max-classes-per-file import { inject, injectable } from 'inversify'; import { Disposable, Event, Uri } from 'vscode'; import { IFileSystem } from '../common/platform/types'; -import { IDisposableRegistry } from '../common/types'; +import { IConfigurationService, IDisposableRegistry } from '../common/types'; import { CONDA_ENV_FILE_SERVICE, CONDA_ENV_SERVICE, @@ -26,7 +26,13 @@ import { WINDOWS_REGISTRY_SERVICE, WORKSPACE_VIRTUAL_ENV_SERVICE } from '../interpreter/contracts'; -import { IPipEnvServiceHelper, IPythonInPathCommandProvider } from '../interpreter/locators/types'; +import { + IInterpreterHashProvider, + IInterpreterHashProviderFactory, + IPipEnvServiceHelper, + IPythonInPathCommandProvider, + IWindowsStoreInterpreter +} from '../interpreter/locators/types'; import { IServiceContainer, IServiceManager } from '../ioc/types'; import { PythonInterpreterLocatorService } from './discovery/locators'; import { InterpreterLocatorHelper } from './discovery/locators/helpers'; @@ -40,7 +46,7 @@ import { GlobalVirtualEnvService } from './discovery/locators/services/globalVirtualEnvService'; import { InterpreterHashProvider } from './discovery/locators/services/hashProvider'; -import { InterpeterHashProviderFactory } from './discovery/locators/services/hashProviderFactory'; +import { InterpreterHashProviderFactory } from './discovery/locators/services/hashProviderFactory'; import { InterpreterWatcherBuilder } from './discovery/locators/services/interpreterWatcherBuilder'; import { KnownPathsService, KnownSearchPathsForInterpreters } from './discovery/locators/services/KnownPathsService'; import { PipEnvService } from './discovery/locators/services/pipEnvService'; @@ -117,9 +123,9 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton(WindowsStoreInterpreter, WindowsStoreInterpreter); serviceManager.addSingleton(InterpreterHashProvider, InterpreterHashProvider); - serviceManager.addSingleton( - InterpeterHashProviderFactory, - InterpeterHashProviderFactory + serviceManager.addSingleton( + IInterpreterHashProviderFactory, + InterpreterHashProviderFactoryProxy ); serviceManager.addSingleton( IVirtualEnvironmentsSearchPathProvider, @@ -196,3 +202,24 @@ class InterpreterLocatorProgressServiceProxy implements IInterpreterLocatorProgr this.impl.register(); } } + +@injectable() +class InterpreterHashProviderFactoryProxy implements IInterpreterHashProviderFactory { + private readonly impl: IInterpreterHashProviderFactory; + constructor( + @inject(IConfigurationService) configService: IConfigurationService, + @inject(WindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter, + @inject(WindowsStoreInterpreter) windowsStoreHashProvider: IInterpreterHashProvider, + @inject(InterpreterHashProvider) hashProvider: IInterpreterHashProvider + ) { + this.impl = new InterpreterHashProviderFactory( + configService, + windowsStoreInterpreter, + windowsStoreHashProvider, + hashProvider + ); + } + public async create(options: { pythonPath: string } | { resource: Uri }): Promise { + return this.impl.create(options); + } +} diff --git a/src/test/pythonEnvironments/discovery/locators/hasProviderFactory.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/hasProviderFactory.unit.test.ts index 69ae6b318efa..465c0c039f32 100644 --- a/src/test/pythonEnvironments/discovery/locators/hasProviderFactory.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/hasProviderFactory.unit.test.ts @@ -13,7 +13,7 @@ import { ConfigurationService } from '../../../../client/common/configuration/se import { IConfigurationService } from '../../../../client/common/types'; import { IInterpreterHashProvider } from '../../../../client/interpreter/locators/types'; import { InterpreterHashProvider } from '../../../../client/pythonEnvironments/discovery/locators/services/hashProvider'; -import { InterpeterHashProviderFactory } from '../../../../client/pythonEnvironments/discovery/locators/services/hashProviderFactory'; +import { InterpreterHashProviderFactory } from '../../../../client/pythonEnvironments/discovery/locators/services/hashProviderFactory'; import { WindowsStoreInterpreter } from '../../../../client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter'; use(chaiAsPromised); @@ -22,14 +22,14 @@ suite('Interpretersx - Interpreter Hash Provider Factory', () => { let configService: IConfigurationService; let windowsStoreInterpreter: WindowsStoreInterpreter; let standardHashProvider: IInterpreterHashProvider; - let factory: InterpeterHashProviderFactory; + let factory: InterpreterHashProviderFactory; setup(() => { configService = mock(ConfigurationService); windowsStoreInterpreter = mock(WindowsStoreInterpreter); standardHashProvider = mock(InterpreterHashProvider); const windowsStoreInstance = instance(windowsStoreInterpreter); (windowsStoreInstance as any).then = undefined; - factory = new InterpeterHashProviderFactory( + factory = new InterpreterHashProviderFactory( instance(configService), windowsStoreInstance, windowsStoreInstance, diff --git a/src/test/pythonEnvironments/legacyIOC.unit.test.ts b/src/test/pythonEnvironments/legacyIOC.unit.test.ts index 218830370632..90910a730d8f 100644 --- a/src/test/pythonEnvironments/legacyIOC.unit.test.ts +++ b/src/test/pythonEnvironments/legacyIOC.unit.test.ts @@ -25,7 +25,11 @@ import { WINDOWS_REGISTRY_SERVICE, WORKSPACE_VIRTUAL_ENV_SERVICE } from '../../client/interpreter/contracts'; -import { IPipEnvServiceHelper, IPythonInPathCommandProvider } from '../../client/interpreter/locators/types'; +import { + IInterpreterHashProviderFactory, + IPipEnvServiceHelper, + IPythonInPathCommandProvider +} from '../../client/interpreter/locators/types'; import { ServiceManager } from '../../client/ioc/serviceManager'; import { PythonInterpreterLocatorService } from '../../client/pythonEnvironments/discovery/locators'; import { InterpreterLocatorHelper } from '../../client/pythonEnvironments/discovery/locators/helpers'; @@ -42,7 +46,7 @@ import { GlobalVirtualEnvService } from '../../client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService'; import { InterpreterHashProvider } from '../../client/pythonEnvironments/discovery/locators/services/hashProvider'; -import { InterpeterHashProviderFactory } from '../../client/pythonEnvironments/discovery/locators/services/hashProviderFactory'; +import { InterpreterHashProviderFactory } from '../../client/pythonEnvironments/discovery/locators/services/hashProviderFactory'; import { InterpreterWatcherBuilder } from '../../client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder'; import { KnownPathsService, @@ -91,7 +95,7 @@ suite('Interpreters - Service Registry', () => { [WindowsStoreInterpreter, WindowsStoreInterpreter], [InterpreterHashProvider, InterpreterHashProvider], - [InterpeterHashProviderFactory, InterpeterHashProviderFactory] + [IInterpreterHashProviderFactory, InterpreterHashProviderFactory] ].forEach((mapping) => { verify(serviceManager.addSingleton.apply(serviceManager, mapping as any)).once(); }); From 1525b186eed8d072c4f15881dba0a44d307cf08c Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:12:51 -0600 Subject: [PATCH 05/31] Factor out BaseLocatorServiceProxy. --- src/client/pythonEnvironments/legacyIOC.ts | 52 ++++++++++++---------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 4ce1203b9ac7..a291a44c6d37 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -144,30 +144,6 @@ export function registerForIOC(serviceManager: IServiceManager) { serviceManager.addSingleton(IInterpreterWatcherBuilder, InterpreterWatcherBuilder); } -@injectable() -class PythonInterpreterLocatorServiceProxy implements IInterpreterLocatorService { - private readonly impl: IInterpreterLocatorService; - constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { - this.impl = new PythonInterpreterLocatorService(serviceContainer); - serviceContainer.get(IDisposableRegistry).push(this.impl); - } - public dispose() { - this.impl.dispose(); - } - public get onLocating(): Event> { - return this.impl.onLocating; - } - public get hasInterpreters(): Promise { - return this.impl.hasInterpreters; - } - public get didTriggerInterpreterSuggestions(): boolean | undefined { - return this.impl.didTriggerInterpreterSuggestions; - } - public async getInterpreters(resource?: Uri, options?: GetInterpreterLocatorOptions): Promise { - return this.impl.getInterpreters(resource, options); - } -} - @injectable() class InterpreterLocatorHelperProxy implements IInterpreterLocatorHelper { private readonly impl: IInterpreterLocatorHelper; @@ -223,3 +199,31 @@ class InterpreterHashProviderFactoryProxy implements IInterpreterHashProviderFac return this.impl.create(options); } } + +@injectable() +class BaseLocatorServiceProxy implements IInterpreterLocatorService { + constructor(protected readonly impl: IInterpreterLocatorService) {} + public dispose() { + this.impl.dispose(); + } + public get onLocating(): Event> { + return this.impl.onLocating; + } + public get hasInterpreters(): Promise { + return this.impl.hasInterpreters; + } + public get didTriggerInterpreterSuggestions(): boolean | undefined { + return this.impl.didTriggerInterpreterSuggestions; + } + public async getInterpreters(resource?: Uri, options?: GetInterpreterLocatorOptions): Promise { + return this.impl.getInterpreters(resource, options); + } +} + +@injectable() +class PythonInterpreterLocatorServiceProxy extends BaseLocatorServiceProxy { + constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { + super(new PythonInterpreterLocatorService(serviceContainer)); + serviceContainer.get(IDisposableRegistry).push(this.impl); + } +} From 0efaf92e85c1589dc02962abc24e9133bedb5993 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:15:59 -0600 Subject: [PATCH 06/31] Add an IOC proxy for CondaEnvFileService. --- .../locators/services/condaEnvFileService.ts | 3 +-- src/client/pythonEnvironments/legacyIOC.ts | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts b/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts index 6b76a95f567d..2af93d0d7f08 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaEnvFileService.ts @@ -8,7 +8,7 @@ * More details: https://github.com/microsoft/vscode-python/issues/8886 */ -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { traceError } from '../../../../common/logger'; @@ -22,7 +22,6 @@ import { AnacondaCompanyName } from './conda'; /** * Locate conda env interpreters based on the "conda environments file". */ -@injectable() export class CondaEnvFileService extends CacheableLocatorService { constructor( @inject(IInterpreterHelper) private helperService: IInterpreterHelper, diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index a291a44c6d37..ef9a966a08c7 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -13,6 +13,7 @@ import { CURRENT_PATH_SERVICE, GLOBAL_VIRTUAL_ENV_SERVICE, ICondaService, + IInterpreterHelper, IInterpreterLocatorHelper, IInterpreterLocatorProgressService, IInterpreterLocatorService, @@ -74,7 +75,7 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton( IInterpreterLocatorService, - CondaEnvFileService, + CondaEnvFileServiceProxy, CONDA_ENV_FILE_SERVICE ); serviceManager.addSingleton( @@ -227,3 +228,15 @@ class PythonInterpreterLocatorServiceProxy extends BaseLocatorServiceProxy { serviceContainer.get(IDisposableRegistry).push(this.impl); } } + +@injectable() +class CondaEnvFileServiceProxy extends BaseLocatorServiceProxy { + constructor( + @inject(IInterpreterHelper) helperService: IInterpreterHelper, + @inject(ICondaService) condaService: ICondaService, + @inject(IFileSystem) fileSystem: IFileSystem, + @inject(IServiceContainer) serviceContainer: IServiceContainer + ) { + super(new CondaEnvFileService(helperService, condaService, fileSystem, serviceContainer)); + } +} From b327c2f68799914665eb9a9627dcf69eaed8a2f5 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:19:09 -0600 Subject: [PATCH 07/31] Add an IOC proxy for CondaEnvService. --- .../discovery/locators/services/condaEnvService.ts | 3 +-- src/client/pythonEnvironments/legacyIOC.ts | 14 +++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts index 54e5d01100b8..0c9f232ea19a 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaEnvService.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import { Uri } from 'vscode'; import { traceError } from '../../../../common/logger'; import { IFileSystem } from '../../../../common/platform/types'; @@ -14,7 +14,6 @@ import { parseCondaInfo } from './conda'; /** * Locates conda env interpreters based on the conda service's info. */ -@injectable() export class CondaEnvService extends CacheableLocatorService { constructor( @inject(ICondaService) private condaService: ICondaService, diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index ef9a966a08c7..9a50e67201d4 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -80,7 +80,7 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton( IInterpreterLocatorService, - CondaEnvService, + CondaEnvServiceProxy, CONDA_ENV_SERVICE ); serviceManager.addSingleton( @@ -240,3 +240,15 @@ class CondaEnvFileServiceProxy extends BaseLocatorServiceProxy { super(new CondaEnvFileService(helperService, condaService, fileSystem, serviceContainer)); } } + +@injectable() +class CondaEnvServiceProxy extends BaseLocatorServiceProxy { + constructor( + @inject(ICondaService) condaService: ICondaService, + @inject(IInterpreterHelper) helper: IInterpreterHelper, + @inject(IServiceContainer) serviceContainer: IServiceContainer, + @inject(IFileSystem) fileSystem: IFileSystem + ) { + super(new CondaEnvService(condaService, helper, serviceContainer, fileSystem)); + } +} From 657d1c145ef097ce00430b251d47e823a7ead924 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:23:08 -0600 Subject: [PATCH 08/31] Add an IOC proxy for CurrentPathService. --- .../locators/services/currentPathService.ts | 1 - src/client/pythonEnvironments/legacyIOC.ts | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts b/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts index e0d523abf19f..7dc8ff65ebfa 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts @@ -19,7 +19,6 @@ import { CacheableLocatorService } from './cacheableLocatorService'; * If no interpreter is configured then it falls back to the system * Python (3 then 2). */ -@injectable() export class CurrentPathService extends CacheableLocatorService { private readonly fs: IFileSystem; diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 9a50e67201d4..9805ed80686b 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -6,6 +6,7 @@ import { inject, injectable } from 'inversify'; import { Disposable, Event, Uri } from 'vscode'; import { IFileSystem } from '../common/platform/types'; +import { IProcessServiceFactory } from '../common/process/types'; import { IConfigurationService, IDisposableRegistry } from '../common/types'; import { CONDA_ENV_FILE_SERVICE, @@ -85,7 +86,7 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton( IInterpreterLocatorService, - CurrentPathService, + CurrentPathServiceProxy, CURRENT_PATH_SERVICE ); serviceManager.addSingleton( @@ -252,3 +253,15 @@ class CondaEnvServiceProxy extends BaseLocatorServiceProxy { super(new CondaEnvService(condaService, helper, serviceContainer, fileSystem)); } } + +@injectable() +class CurrentPathServiceProxy extends BaseLocatorServiceProxy { + constructor( + @inject(IInterpreterHelper) helper: IInterpreterHelper, + @inject(IProcessServiceFactory) processServiceFactory: IProcessServiceFactory, + @inject(IPythonInPathCommandProvider) pythonCommandProvider: IPythonInPathCommandProvider, + @inject(IServiceContainer) serviceContainer: IServiceContainer + ) { + super(new CurrentPathService(helper, processServiceFactory, pythonCommandProvider, serviceContainer)); + } +} From 937d1528549dc978fc5431264298c88e40e59531 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:26:53 -0600 Subject: [PATCH 09/31] Add an IOC proxy for GlobalVirtualEnvService. --- .../locators/services/globalVirtualEnvService.ts | 1 - src/client/pythonEnvironments/legacyIOC.ts | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts index 5324c35d35dc..e6d4bf6ca23a 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts @@ -16,7 +16,6 @@ import { BaseVirtualEnvService } from './baseVirtualEnvService'; // tslint:disable-next-line:no-require-imports no-var-requires const untildify: (value: string) => string = require('untildify'); -@injectable() export class GlobalVirtualEnvService extends BaseVirtualEnvService { public constructor( @inject(IVirtualEnvironmentsSearchPathProvider) diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 9805ed80686b..892ff312cc78 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -3,7 +3,7 @@ // tslint:disable:no-use-before-declare max-classes-per-file -import { inject, injectable } from 'inversify'; +import { inject, injectable, named } from 'inversify'; import { Disposable, Event, Uri } from 'vscode'; import { IFileSystem } from '../common/platform/types'; import { IProcessServiceFactory } from '../common/process/types'; @@ -91,7 +91,7 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton( IInterpreterLocatorService, - GlobalVirtualEnvService, + GlobalVirtualEnvServiceProxy, GLOBAL_VIRTUAL_ENV_SERVICE ); serviceManager.addSingleton( @@ -265,3 +265,15 @@ class CurrentPathServiceProxy extends BaseLocatorServiceProxy { super(new CurrentPathService(helper, processServiceFactory, pythonCommandProvider, serviceContainer)); } } + +@injectable() +class GlobalVirtualEnvServiceProxy extends BaseLocatorServiceProxy { + public constructor( + @inject(IVirtualEnvironmentsSearchPathProvider) + @named('global') + globalVirtualEnvPathProvider: IVirtualEnvironmentsSearchPathProvider, + @inject(IServiceContainer) serviceContainer: IServiceContainer + ) { + super(new GlobalVirtualEnvService(globalVirtualEnvPathProvider, serviceContainer)); + } +} From c5a184841c6d704ba21b2c2b1db2a6b96337d18c Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:30:23 -0600 Subject: [PATCH 10/31] Add an IOC proxy for WorkspaceVirtualEnvService. --- .../services/workspaceVirtualEnvService.ts | 1 - src/client/pythonEnvironments/legacyIOC.ts | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts index 8f1d75b4ebc0..ecb9766705c6 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts @@ -19,7 +19,6 @@ import { import { IServiceContainer } from '../../../../ioc/types'; import { BaseVirtualEnvService } from './baseVirtualEnvService'; -@injectable() export class WorkspaceVirtualEnvService extends BaseVirtualEnvService { public constructor( @inject(IVirtualEnvironmentsSearchPathProvider) diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 892ff312cc78..06fe18cd4801 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -96,7 +96,7 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton( IInterpreterLocatorService, - WorkspaceVirtualEnvService, + WorkspaceVirtualEnvServiceProxy, WORKSPACE_VIRTUAL_ENV_SERVICE ); serviceManager.addSingleton(IInterpreterLocatorService, PipEnvService, PIPENV_SERVICE); @@ -277,3 +277,16 @@ class GlobalVirtualEnvServiceProxy extends BaseLocatorServiceProxy { super(new GlobalVirtualEnvService(globalVirtualEnvPathProvider, serviceContainer)); } } + +@injectable() +class WorkspaceVirtualEnvServiceProxy extends BaseLocatorServiceProxy { + public constructor( + @inject(IVirtualEnvironmentsSearchPathProvider) + @named('workspace') + workspaceVirtualEnvPathProvider: IVirtualEnvironmentsSearchPathProvider, + @inject(IServiceContainer) serviceContainer: IServiceContainer, + @inject(IInterpreterWatcherBuilder) builder: IInterpreterWatcherBuilder + ) { + super(new WorkspaceVirtualEnvService(workspaceVirtualEnvPathProvider, serviceContainer, builder)); + } +} From 549821b6911f658fe3e40e800167cb070247a208 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:31:25 -0600 Subject: [PATCH 11/31] Drop @injectable from BaseVirtualEnvService. --- .../locators/services/baseVirtualEnvService.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts index 8838659ca14f..a7a68da26e3a 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/baseVirtualEnvService.ts @@ -1,6 +1,5 @@ // tslint:disable:no-unnecessary-callback-wrapper no-require-imports no-var-requires -import { injectable, unmanaged } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { traceError } from '../../../../common/logger'; @@ -13,16 +12,15 @@ import { lookForInterpretersInDirectory } from '../helpers'; import { CacheableLocatorService } from './cacheableLocatorService'; const flatten = require('lodash/flatten') as typeof import('lodash/flatten'); -@injectable() export class BaseVirtualEnvService extends CacheableLocatorService { private readonly virtualEnvMgr: IVirtualEnvironmentManager; private readonly helper: IInterpreterHelper; private readonly fileSystem: IFileSystem; public constructor( - @unmanaged() private searchPathsProvider: IVirtualEnvironmentsSearchPathProvider, - @unmanaged() serviceContainer: IServiceContainer, - @unmanaged() name: string, - @unmanaged() cachePerWorkspace: boolean = false + private searchPathsProvider: IVirtualEnvironmentsSearchPathProvider, + serviceContainer: IServiceContainer, + name: string, + cachePerWorkspace: boolean = false ) { super(name, serviceContainer, cachePerWorkspace); this.virtualEnvMgr = serviceContainer.get(IVirtualEnvironmentManager); From fffdade70530d401a9f09cf0864fffef1848fa60 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:36:05 -0600 Subject: [PATCH 12/31] Add an IOC proxy for KnownPathsService. --- .../locators/services/KnownPathsService.ts | 1 - src/client/pythonEnvironments/legacyIOC.ts | 13 ++++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts b/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts index 367bef9de946..7894a35cc953 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts @@ -14,7 +14,6 @@ const flatten = require('lodash/flatten') as typeof import('lodash/flatten'); /** * Locates "known" paths. */ -@injectable() export class KnownPathsService extends CacheableLocatorService { public constructor( @inject(IKnownSearchPathsForInterpreters) private knownSearchPaths: IKnownSearchPathsForInterpreters, diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 06fe18cd4801..3a76f6f2fbbf 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -108,7 +108,7 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton( IInterpreterLocatorService, - KnownPathsService, + KnownPathsServiceProxy, KNOWN_PATH_SERVICE ); serviceManager.addSingleton(ICondaService, CondaService); @@ -290,3 +290,14 @@ class WorkspaceVirtualEnvServiceProxy extends BaseLocatorServiceProxy { super(new WorkspaceVirtualEnvService(workspaceVirtualEnvPathProvider, serviceContainer, builder)); } } + +@injectable() +class KnownPathsServiceProxy extends BaseLocatorServiceProxy { + public constructor( + @inject(IKnownSearchPathsForInterpreters) knownSearchPaths: IKnownSearchPathsForInterpreters, + @inject(IInterpreterHelper) helper: IInterpreterHelper, + @inject(IServiceContainer) serviceContainer: IServiceContainer + ) { + super(new KnownPathsService(knownSearchPaths, helper, serviceContainer)); + } +} From b4443d417d3bb92b290729c4efdab906d6d3fd49 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:44:48 -0600 Subject: [PATCH 13/31] Add an IOC proxy for PipEnvService. --- .../discovery/locators/services/pipEnvService.ts | 3 +-- src/client/pythonEnvironments/legacyIOC.ts | 13 ++++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/pipEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/pipEnvService.ts index 79dba15b6729..cb03dca08734 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/pipEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/pipEnvService.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { IApplicationShell, IWorkspaceService } from '../../../../common/application/types'; @@ -21,7 +21,6 @@ import { CacheableLocatorService } from './cacheableLocatorService'; const pipEnvFileNameVariable = 'PIPENV_PIPFILE'; -@injectable() export class PipEnvService extends CacheableLocatorService implements IPipEnvService { private readonly helper: IInterpreterHelper; private readonly processServiceFactory: IProcessServiceFactory; diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 3a76f6f2fbbf..7d383376d730 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -99,7 +99,11 @@ export function registerForIOC(serviceManager: IServiceManager) { WorkspaceVirtualEnvServiceProxy, WORKSPACE_VIRTUAL_ENV_SERVICE ); - serviceManager.addSingleton(IInterpreterLocatorService, PipEnvService, PIPENV_SERVICE); + serviceManager.addSingleton( + IInterpreterLocatorService, + PipEnvServiceProxy, + PIPENV_SERVICE + ); serviceManager.addSingleton( IInterpreterLocatorService, @@ -301,3 +305,10 @@ class KnownPathsServiceProxy extends BaseLocatorServiceProxy { super(new KnownPathsService(knownSearchPaths, helper, serviceContainer)); } } + +@injectable() +class PipEnvServiceProxy extends BaseLocatorServiceProxy { + constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { + super(new PipEnvService(serviceContainer)); + } +} From a30882c5b74b83fd9d39204f6e757a743145d007 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:52:20 -0600 Subject: [PATCH 14/31] Add an IOC proxy for WindowsRegistryService. --- .../locators/services/windowsRegistryService.ts | 3 +-- src/client/pythonEnvironments/legacyIOC.ts | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts b/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts index 4cc062982ebb..f007a3cdf94b 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts @@ -1,6 +1,6 @@ // tslint:disable:no-require-imports no-var-requires underscore-consistent-invocation -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { traceError } from '../../../../common/logger'; @@ -32,7 +32,6 @@ type CompanyInterpreter = { arch?: Architecture; }; -@injectable() export class WindowsRegistryService extends CacheableLocatorService { private readonly pathUtils: IPathUtils; private readonly fs: IFileSystem; diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 7d383376d730..98a569871a5f 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -5,7 +5,7 @@ import { inject, injectable, named } from 'inversify'; import { Disposable, Event, Uri } from 'vscode'; -import { IFileSystem } from '../common/platform/types'; +import { IFileSystem, IPlatformService, IRegistry } from '../common/platform/types'; import { IProcessServiceFactory } from '../common/process/types'; import { IConfigurationService, IDisposableRegistry } from '../common/types'; import { @@ -107,7 +107,7 @@ export function registerForIOC(serviceManager: IServiceManager) { serviceManager.addSingleton( IInterpreterLocatorService, - WindowsRegistryService, + WindowsRegistryServiceProxy, WINDOWS_REGISTRY_SERVICE ); serviceManager.addSingleton( @@ -312,3 +312,15 @@ class PipEnvServiceProxy extends BaseLocatorServiceProxy { super(new PipEnvService(serviceContainer)); } } + +@injectable() +class WindowsRegistryServiceProxy extends BaseLocatorServiceProxy { + constructor( + @inject(IRegistry) registry: IRegistry, + @inject(IPlatformService) platform: IPlatformService, + @inject(IServiceContainer) serviceContainer: IServiceContainer, + @inject(WindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter + ) { + super(new WindowsRegistryService(registry, platform, serviceContainer, windowsStoreInterpreter)); + } +} From af2a75ed6c753d2ab4c79b02816818f8739a07b4 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 13:53:16 -0600 Subject: [PATCH 15/31] Drop @injectable from CacheableLocatorService. --- .../locators/services/cacheableLocatorService.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/cacheableLocatorService.ts b/src/client/pythonEnvironments/discovery/locators/services/cacheableLocatorService.ts index 8bcd4b96136c..50883258cbbf 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/cacheableLocatorService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/cacheableLocatorService.ts @@ -3,7 +3,6 @@ // tslint:disable:no-any -import { injectable, unmanaged } from 'inversify'; import * as md5 from 'md5'; import { Disposable, Event, EventEmitter, Uri } from 'vscode'; import { IWorkspaceService } from '../../../../common/application/types'; @@ -60,7 +59,6 @@ export class CacheableLocatorPromiseCache { } } -@injectable() export abstract class CacheableLocatorService implements IInterpreterLocatorService { protected readonly _hasInterpreters: Deferred; private readonly promisesPerResource = new CacheableLocatorPromiseCache(); @@ -70,9 +68,9 @@ export abstract class CacheableLocatorService implements IInterpreterLocatorServ private _didTriggerInterpreterSuggestions: boolean; constructor( - @unmanaged() private readonly name: string, - @unmanaged() protected readonly serviceContainer: IServiceContainer, - @unmanaged() private cachePerWorkspace: boolean = false + private readonly name: string, + protected readonly serviceContainer: IServiceContainer, + private cachePerWorkspace: boolean = false ) { this._hasInterpreters = createDeferred(); this.cacheKeyPrefix = `INTERPRETERS_CACHE_v3_${name}`; From de735ebe587bc3703ab12ef0bdd88d5c3c426dec Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 14:01:28 -0600 Subject: [PATCH 16/31] Add an IOC proxy for InterpreterHashProvider. --- src/client/interpreter/locators/types.ts | 1 + .../discovery/locators/services/hashProvider.ts | 6 ++---- .../locators/services/hashProviderFactory.ts | 3 +-- src/client/pythonEnvironments/legacyIOC.ts | 15 +++++++++++++-- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/client/interpreter/locators/types.ts b/src/client/interpreter/locators/types.ts index 7bd524bedb9a..61892a93ea38 100644 --- a/src/client/interpreter/locators/types.ts +++ b/src/client/interpreter/locators/types.ts @@ -27,6 +27,7 @@ export interface IInterpreterHashProviderFactory { create(options: { pythonPath: string } | { resource: Uri }): Promise; } +export const IInterpreterHashProvider = Symbol('IInterpreterHashProvider'); /** * Provides the ability to get the has of a given interpreter. * diff --git a/src/client/pythonEnvironments/discovery/locators/services/hashProvider.ts b/src/client/pythonEnvironments/discovery/locators/services/hashProvider.ts index 453ecddd4c10..50aa5f604bf6 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/hashProvider.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/hashProvider.ts @@ -3,12 +3,10 @@ 'use strict'; -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import { IFileSystem } from '../../../../common/platform/types'; -import { IInterpreterHashProvider } from '../../../../interpreter/locators/types'; -@injectable() -export class InterpreterHashProvider implements IInterpreterHashProvider { +export class InterpreterHashProvider { constructor(@inject(IFileSystem) private readonly fs: IFileSystem) {} public async getInterpreterHash(pythonPath: string): Promise { return this.fs.getFileHash(pythonPath); diff --git a/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts b/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts index b58fd3696fc2..7261863e1a51 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts @@ -7,7 +7,6 @@ import { inject } from 'inversify'; import { Uri } from 'vscode'; import { IConfigurationService } from '../../../../common/types'; import { IInterpreterHashProvider, IWindowsStoreInterpreter } from '../../../../interpreter/locators/types'; -import { InterpreterHashProvider } from './hashProvider'; import { WindowsStoreInterpreter } from './windowsStoreInterpreter'; export class InterpreterHashProviderFactory { @@ -15,7 +14,7 @@ export class InterpreterHashProviderFactory { @inject(IConfigurationService) private readonly configService: IConfigurationService, @inject(WindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter, @inject(WindowsStoreInterpreter) private readonly windowsStoreHashProvider: IInterpreterHashProvider, - @inject(InterpreterHashProvider) private readonly hashProvider: IInterpreterHashProvider + @inject(IInterpreterHashProvider) private readonly hashProvider: IInterpreterHashProvider ) {} public async create(options: { pythonPath: string } | { resource: Uri }): Promise { diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 98a569871a5f..9741a8cb0e6d 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -128,7 +128,7 @@ export function registerForIOC(serviceManager: IServiceManager) { WORKSPACE_VIRTUAL_ENV_SERVICE ); serviceManager.addSingleton(WindowsStoreInterpreter, WindowsStoreInterpreter); - serviceManager.addSingleton(InterpreterHashProvider, InterpreterHashProvider); + serviceManager.addSingleton(IInterpreterHashProvider, InterpreterHashProviderProxy); serviceManager.addSingleton( IInterpreterHashProviderFactory, InterpreterHashProviderFactoryProxy @@ -192,7 +192,7 @@ class InterpreterHashProviderFactoryProxy implements IInterpreterHashProviderFac @inject(IConfigurationService) configService: IConfigurationService, @inject(WindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter, @inject(WindowsStoreInterpreter) windowsStoreHashProvider: IInterpreterHashProvider, - @inject(InterpreterHashProvider) hashProvider: IInterpreterHashProvider + @inject(IInterpreterHashProvider) hashProvider: IInterpreterHashProvider ) { this.impl = new InterpreterHashProviderFactory( configService, @@ -324,3 +324,14 @@ class WindowsRegistryServiceProxy extends BaseLocatorServiceProxy { super(new WindowsRegistryService(registry, platform, serviceContainer, windowsStoreInterpreter)); } } + +@injectable() +class InterpreterHashProviderProxy implements IInterpreterHashProvider { + private readonly impl: IInterpreterHashProvider; + constructor(@inject(IFileSystem) fs: IFileSystem) { + this.impl = new InterpreterHashProvider(fs); + } + public async getInterpreterHash(pythonPath: string): Promise { + return this.impl.getInterpreterHash(pythonPath); + } +} From 37f879e461a7415ac7e10c5839020580f0115455 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 14:21:02 -0600 Subject: [PATCH 17/31] Add an IOC proxy for WindowsStoreInterpreter. --- .../common/process/pythonExecutionFactory.ts | 3 +- src/client/interpreter/locators/types.ts | 4 +++ .../locators/services/hashProviderFactory.ts | 11 ++++--- .../services/windowsRegistryService.ts | 3 +- .../services/windowsStoreInterpreter.ts | 6 ++-- src/client/pythonEnvironments/legacyIOC.ts | 33 ++++++++++++++++--- 6 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/client/common/process/pythonExecutionFactory.ts b/src/client/common/process/pythonExecutionFactory.ts index 3242070a8aab..81a1bb89d968 100644 --- a/src/client/common/process/pythonExecutionFactory.ts +++ b/src/client/common/process/pythonExecutionFactory.ts @@ -10,7 +10,6 @@ import { ICondaService, IInterpreterService } from '../../interpreter/contracts' import { IWindowsStoreInterpreter } from '../../interpreter/locators/types'; import { IServiceContainer } from '../../ioc/types'; import { CondaEnvironmentInfo } from '../../pythonEnvironments/discovery/locators/services/conda'; -import { WindowsStoreInterpreter } from '../../pythonEnvironments/discovery/locators/services/windowsStoreInterpreter'; import { sendTelemetryEvent } from '../../telemetry'; import { EventName } from '../../telemetry/constants'; import { traceError } from '../logger'; @@ -51,7 +50,7 @@ export class PythonExecutionFactory implements IPythonExecutionFactory { @inject(IConfigurationService) private readonly configService: IConfigurationService, @inject(ICondaService) private readonly condaService: ICondaService, @inject(IBufferDecoder) private readonly decoder: IBufferDecoder, - @inject(WindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter, + @inject(IWindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter, @inject(IPlatformService) private readonly platformService: IPlatformService ) { // Acquire other objects here so that if we are called during dispose they are available. diff --git a/src/client/interpreter/locators/types.ts b/src/client/interpreter/locators/types.ts index 61892a93ea38..6b36fba8eb94 100644 --- a/src/client/interpreter/locators/types.ts +++ b/src/client/interpreter/locators/types.ts @@ -46,6 +46,10 @@ export interface IInterpreterHashProvider { getInterpreterHash(pythonPath: string): Promise; } +export const IWindowsStoreHashProvider = Symbol('IWindowStoreHashProvider'); +export interface IWindowsStoreHashProvider extends IInterpreterHashProvider {} + +export const IWindowsStoreInterpreter = Symbol('IWindowsStoreInterpreter'); export interface IWindowsStoreInterpreter { /** * Whether this is a Windows Store/App Interpreter. diff --git a/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts b/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts index 7261863e1a51..32092b15aee0 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/hashProviderFactory.ts @@ -6,14 +6,17 @@ import { inject } from 'inversify'; import { Uri } from 'vscode'; import { IConfigurationService } from '../../../../common/types'; -import { IInterpreterHashProvider, IWindowsStoreInterpreter } from '../../../../interpreter/locators/types'; -import { WindowsStoreInterpreter } from './windowsStoreInterpreter'; +import { + IInterpreterHashProvider, + IWindowsStoreHashProvider, + IWindowsStoreInterpreter +} from '../../../../interpreter/locators/types'; export class InterpreterHashProviderFactory { constructor( @inject(IConfigurationService) private readonly configService: IConfigurationService, - @inject(WindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter, - @inject(WindowsStoreInterpreter) private readonly windowsStoreHashProvider: IInterpreterHashProvider, + @inject(IWindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter, + @inject(IWindowsStoreHashProvider) private readonly windowsStoreHashProvider: IWindowsStoreHashProvider, @inject(IInterpreterHashProvider) private readonly hashProvider: IInterpreterHashProvider ) {} diff --git a/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts b/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts index f007a3cdf94b..2c145c12f5d5 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/windowsRegistryService.ts @@ -14,7 +14,6 @@ import { InterpreterType, PythonInterpreter } from '../../../info'; import { parsePythonVersion } from '../../../info/pythonVersion'; import { CacheableLocatorService } from './cacheableLocatorService'; import { AnacondaCompanyName, AnacondaCompanyNames } from './conda'; -import { WindowsStoreInterpreter } from './windowsStoreInterpreter'; const flatten = require('lodash/flatten') as typeof import('lodash/flatten'); // tslint:disable-next-line:variable-name @@ -39,7 +38,7 @@ export class WindowsRegistryService extends CacheableLocatorService { @inject(IRegistry) private registry: IRegistry, @inject(IPlatformService) private readonly platform: IPlatformService, @inject(IServiceContainer) serviceContainer: IServiceContainer, - @inject(WindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter + @inject(IWindowsStoreInterpreter) private readonly windowsStoreInterpreter: IWindowsStoreInterpreter ) { super('WindowsRegistryService', serviceContainer); this.pathUtils = serviceContainer.get(IPathUtils); diff --git a/src/client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter.ts b/src/client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter.ts index e28a3c320ff5..0943552b999b 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter.ts @@ -3,13 +3,12 @@ 'use strict'; -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import * as path from 'path'; import { traceDecorators } from '../../../../common/logger'; import { IFileSystem } from '../../../../common/platform/types'; import { IPythonExecutionFactory } from '../../../../common/process/types'; import { IPersistentStateFactory } from '../../../../common/types'; -import { IInterpreterHashProvider, IWindowsStoreInterpreter } from '../../../../interpreter/locators/types'; import { IServiceContainer } from '../../../../ioc/types'; /** @@ -54,8 +53,7 @@ export function isRestrictedWindowsStoreInterpreterPath(pythonPath: string): boo * @implements {IWindowsStoreInterpreter} * @implements {IInterpreterHashProvider} */ -@injectable() -export class WindowsStoreInterpreter implements IWindowsStoreInterpreter, IInterpreterHashProvider { +export class WindowsStoreInterpreter { constructor( @inject(IServiceContainer) private readonly serviceContainer: IServiceContainer, @inject(IPersistentStateFactory) private readonly persistentFactory: IPersistentStateFactory, diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 9741a8cb0e6d..8610995ab727 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -7,7 +7,7 @@ import { inject, injectable, named } from 'inversify'; import { Disposable, Event, Uri } from 'vscode'; import { IFileSystem, IPlatformService, IRegistry } from '../common/platform/types'; import { IProcessServiceFactory } from '../common/process/types'; -import { IConfigurationService, IDisposableRegistry } from '../common/types'; +import { IConfigurationService, IDisposableRegistry, IPersistentStateFactory } from '../common/types'; import { CONDA_ENV_FILE_SERVICE, CONDA_ENV_SERVICE, @@ -33,6 +33,7 @@ import { IInterpreterHashProviderFactory, IPipEnvServiceHelper, IPythonInPathCommandProvider, + IWindowsStoreHashProvider, IWindowsStoreInterpreter } from '../interpreter/locators/types'; import { IServiceContainer, IServiceManager } from '../ioc/types'; @@ -127,7 +128,8 @@ export function registerForIOC(serviceManager: IServiceManager) { WorkspaceVirtualEnvWatcherService, WORKSPACE_VIRTUAL_ENV_SERVICE ); - serviceManager.addSingleton(WindowsStoreInterpreter, WindowsStoreInterpreter); + serviceManager.addSingleton(IWindowsStoreInterpreter, WindowsStoreInterpreterProxy); + serviceManager.addSingleton(IWindowsStoreHashProvider, WindowsStoreInterpreterProxy); serviceManager.addSingleton(IInterpreterHashProvider, InterpreterHashProviderProxy); serviceManager.addSingleton( IInterpreterHashProviderFactory, @@ -190,8 +192,8 @@ class InterpreterHashProviderFactoryProxy implements IInterpreterHashProviderFac private readonly impl: IInterpreterHashProviderFactory; constructor( @inject(IConfigurationService) configService: IConfigurationService, - @inject(WindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter, - @inject(WindowsStoreInterpreter) windowsStoreHashProvider: IInterpreterHashProvider, + @inject(IWindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter, + @inject(IWindowsStoreHashProvider) windowsStoreHashProvider: IWindowsStoreHashProvider, @inject(IInterpreterHashProvider) hashProvider: IInterpreterHashProvider ) { this.impl = new InterpreterHashProviderFactory( @@ -319,7 +321,7 @@ class WindowsRegistryServiceProxy extends BaseLocatorServiceProxy { @inject(IRegistry) registry: IRegistry, @inject(IPlatformService) platform: IPlatformService, @inject(IServiceContainer) serviceContainer: IServiceContainer, - @inject(WindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter + @inject(IWindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter ) { super(new WindowsRegistryService(registry, platform, serviceContainer, windowsStoreInterpreter)); } @@ -335,3 +337,24 @@ class InterpreterHashProviderProxy implements IInterpreterHashProvider { return this.impl.getInterpreterHash(pythonPath); } } + +@injectable() +class WindowsStoreInterpreterProxy implements IWindowsStoreInterpreter, IWindowsStoreHashProvider { + private readonly impl: IWindowsStoreInterpreter & IWindowsStoreHashProvider; + constructor( + @inject(IServiceContainer) serviceContainer: IServiceContainer, + @inject(IPersistentStateFactory) persistentFactory: IPersistentStateFactory, + @inject(IFileSystem) fs: IFileSystem + ) { + this.impl = new WindowsStoreInterpreter(serviceContainer, persistentFactory, fs); + } + public isWindowsStoreInterpreter(pythonPath: string): boolean { + return this.impl.isWindowsStoreInterpreter(pythonPath); + } + public isHiddenInterpreter(pythonPath: string): boolean { + return this.impl.isHiddenInterpreter(pythonPath); + } + public async getInterpreterHash(pythonPath: string): Promise { + return this.impl.getInterpreterHash(pythonPath); + } +} From 0d7a990400c24675ac3a779205d67c8ee6f66589 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 14:25:13 -0600 Subject: [PATCH 18/31] Group the hash-related classes. --- src/client/pythonEnvironments/legacyIOC.ts | 64 +++++++++++----------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 8610995ab727..8843db0c2e99 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -208,6 +208,38 @@ class InterpreterHashProviderFactoryProxy implements IInterpreterHashProviderFac } } +@injectable() +class InterpreterHashProviderProxy implements IInterpreterHashProvider { + private readonly impl: IInterpreterHashProvider; + constructor(@inject(IFileSystem) fs: IFileSystem) { + this.impl = new InterpreterHashProvider(fs); + } + public async getInterpreterHash(pythonPath: string): Promise { + return this.impl.getInterpreterHash(pythonPath); + } +} + +@injectable() +class WindowsStoreInterpreterProxy implements IWindowsStoreInterpreter, IWindowsStoreHashProvider { + private readonly impl: IWindowsStoreInterpreter & IWindowsStoreHashProvider; + constructor( + @inject(IServiceContainer) serviceContainer: IServiceContainer, + @inject(IPersistentStateFactory) persistentFactory: IPersistentStateFactory, + @inject(IFileSystem) fs: IFileSystem + ) { + this.impl = new WindowsStoreInterpreter(serviceContainer, persistentFactory, fs); + } + public isWindowsStoreInterpreter(pythonPath: string): boolean { + return this.impl.isWindowsStoreInterpreter(pythonPath); + } + public isHiddenInterpreter(pythonPath: string): boolean { + return this.impl.isHiddenInterpreter(pythonPath); + } + public async getInterpreterHash(pythonPath: string): Promise { + return this.impl.getInterpreterHash(pythonPath); + } +} + @injectable() class BaseLocatorServiceProxy implements IInterpreterLocatorService { constructor(protected readonly impl: IInterpreterLocatorService) {} @@ -326,35 +358,3 @@ class WindowsRegistryServiceProxy extends BaseLocatorServiceProxy { super(new WindowsRegistryService(registry, platform, serviceContainer, windowsStoreInterpreter)); } } - -@injectable() -class InterpreterHashProviderProxy implements IInterpreterHashProvider { - private readonly impl: IInterpreterHashProvider; - constructor(@inject(IFileSystem) fs: IFileSystem) { - this.impl = new InterpreterHashProvider(fs); - } - public async getInterpreterHash(pythonPath: string): Promise { - return this.impl.getInterpreterHash(pythonPath); - } -} - -@injectable() -class WindowsStoreInterpreterProxy implements IWindowsStoreInterpreter, IWindowsStoreHashProvider { - private readonly impl: IWindowsStoreInterpreter & IWindowsStoreHashProvider; - constructor( - @inject(IServiceContainer) serviceContainer: IServiceContainer, - @inject(IPersistentStateFactory) persistentFactory: IPersistentStateFactory, - @inject(IFileSystem) fs: IFileSystem - ) { - this.impl = new WindowsStoreInterpreter(serviceContainer, persistentFactory, fs); - } - public isWindowsStoreInterpreter(pythonPath: string): boolean { - return this.impl.isWindowsStoreInterpreter(pythonPath); - } - public isHiddenInterpreter(pythonPath: string): boolean { - return this.impl.isHiddenInterpreter(pythonPath); - } - public async getInterpreterHash(pythonPath: string): Promise { - return this.impl.getInterpreterHash(pythonPath); - } -} From 0ba480e336eb474415e95e74b127cdf40536a438 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 14:27:51 -0600 Subject: [PATCH 19/31] Add an IOC proxy for PythonInPathCommandProvider. --- .../locators/services/currentPathService.ts | 5 ++--- src/client/pythonEnvironments/legacyIOC.ts | 13 ++++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts b/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts index 7dc8ff65ebfa..849b318cb981 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/currentPathService.ts @@ -1,5 +1,5 @@ // tslint:disable:no-require-imports no-var-requires underscore-consistent-invocation no-unnecessary-callback-wrapper -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import { Uri } from 'vscode'; import { traceError, traceInfo } from '../../../../common/logger'; import { IFileSystem, IPlatformService } from '../../../../common/platform/types'; @@ -124,8 +124,7 @@ export class CurrentPathService extends CacheableLocatorService { } } -@injectable() -export class PythonInPathCommandProvider implements IPythonInPathCommandProvider { +export class PythonInPathCommandProvider { constructor(@inject(IPlatformService) private readonly platform: IPlatformService) {} public getCommands(): { command: string; args?: string[] }[] { const paths = ['python3.7', 'python3.6', 'python3', 'python2', 'python'].map((item) => { diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 8843db0c2e99..5bbdd73cb38b 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -120,7 +120,7 @@ export function registerForIOC(serviceManager: IServiceManager) { serviceManager.addSingleton(IPipEnvServiceHelper, PipEnvServiceHelper); serviceManager.addSingleton( IPythonInPathCommandProvider, - PythonInPathCommandProvider + PythonInPathCommandProviderProxy ); serviceManager.add( @@ -240,6 +240,17 @@ class WindowsStoreInterpreterProxy implements IWindowsStoreInterpreter, IWindows } } +@injectable() +class PythonInPathCommandProviderProxy implements IPythonInPathCommandProvider { + private readonly impl: IPythonInPathCommandProvider; + constructor(@inject(IPlatformService) platform: IPlatformService) { + this.impl = new PythonInPathCommandProvider(platform); + } + public getCommands(): { command: string; args?: string[] }[] { + return this.impl.getCommands(); + } +} + @injectable() class BaseLocatorServiceProxy implements IInterpreterLocatorService { constructor(protected readonly impl: IInterpreterLocatorService) {} From 464564ff1414018d0a827bdc2fe634af2b962752 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 14:32:59 -0600 Subject: [PATCH 20/31] Add an IOC proxy for KnownSearchPathsForInterpreters. --- .../locators/services/KnownPathsService.ts | 5 ++--- src/client/pythonEnvironments/legacyIOC.ts | 13 ++++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts b/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts index 7894a35cc953..d0dd4d9b3f7e 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/KnownPathsService.ts @@ -1,5 +1,5 @@ // tslint:disable:no-require-imports no-var-requires no-unnecessary-callback-wrapper -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { IFileSystem, IPlatformService } from '../../../../common/platform/types'; @@ -83,8 +83,7 @@ export class KnownPathsService extends CacheableLocatorService { } } -@injectable() -export class KnownSearchPathsForInterpreters implements IKnownSearchPathsForInterpreters { +export class KnownSearchPathsForInterpreters { constructor(@inject(IServiceContainer) private readonly serviceContainer: IServiceContainer) {} /** * Return the paths where Python interpreters might be found. diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 5bbdd73cb38b..230de130f2a9 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -147,7 +147,7 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton( IKnownSearchPathsForInterpreters, - KnownSearchPathsForInterpreters + KnownSearchPathsForInterpretersProxy ); serviceManager.addSingleton(IInterpreterWatcherBuilder, InterpreterWatcherBuilder); } @@ -251,6 +251,17 @@ class PythonInPathCommandProviderProxy implements IPythonInPathCommandProvider { } } +@injectable() +class KnownSearchPathsForInterpretersProxy implements IKnownSearchPathsForInterpreters { + private readonly impl: IKnownSearchPathsForInterpreters; + constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { + this.impl = new KnownSearchPathsForInterpreters(serviceContainer); + } + public getSearchPaths(): string[] { + return this.impl.getSearchPaths(); + } +} + @injectable() class BaseLocatorServiceProxy implements IInterpreterLocatorService { constructor(protected readonly impl: IInterpreterLocatorService) {} From 6acd67f8d7b665112be62941b53fd10cf5e8114a Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 14:38:50 -0600 Subject: [PATCH 21/31] Add an IOC proxy for WorkspaceVirtualEnvironmentsSearchPathProvider. --- .../locators/services/workspaceVirtualEnvService.ts | 5 ++--- src/client/pythonEnvironments/legacyIOC.ts | 13 ++++++++++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts index ecb9766705c6..62e3fb4edaa8 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService.ts @@ -5,7 +5,7 @@ // tslint:disable:no-require-imports -import { inject, injectable, named } from 'inversify'; +import { inject, named } from 'inversify'; import * as path from 'path'; import untildify = require('untildify'); import { Uri } from 'vscode'; @@ -34,8 +34,7 @@ export class WorkspaceVirtualEnvService extends BaseVirtualEnvService { } } -@injectable() -export class WorkspaceVirtualEnvironmentsSearchPathProvider implements IVirtualEnvironmentsSearchPathProvider { +export class WorkspaceVirtualEnvironmentsSearchPathProvider { public constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) {} public async getSearchPaths(resource?: Uri): Promise { const configService = this.serviceContainer.get(IConfigurationService); diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 230de130f2a9..acf262619557 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -142,7 +142,7 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton( IVirtualEnvironmentsSearchPathProvider, - WorkspaceVirtualEnvironmentsSearchPathProvider, + WorkspaceVirtualEnvironmentsSearchPathProviderProxy, 'workspace' ); serviceManager.addSingleton( @@ -262,6 +262,17 @@ class KnownSearchPathsForInterpretersProxy implements IKnownSearchPathsForInterp } } +@injectable() +class WorkspaceVirtualEnvironmentsSearchPathProviderProxy implements IVirtualEnvironmentsSearchPathProvider { + private readonly impl: IVirtualEnvironmentsSearchPathProvider; + public constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { + this.impl = new WorkspaceVirtualEnvironmentsSearchPathProvider(serviceContainer); + } + public async getSearchPaths(resource?: Uri): Promise { + return this.impl.getSearchPaths(resource); + } +} + @injectable() class BaseLocatorServiceProxy implements IInterpreterLocatorService { constructor(protected readonly impl: IInterpreterLocatorService) {} From 4b99446f910df4c59d5dd6cebbb5ea9fef715f8d Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 14:43:20 -0600 Subject: [PATCH 22/31] Add an IOC proxy for PipEnvServiceHelper. --- .../locators/services/pipEnvServiceHelper.ts | 4 ++-- src/client/pythonEnvironments/legacyIOC.ts | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/pipEnvServiceHelper.ts b/src/client/pythonEnvironments/discovery/locators/services/pipEnvServiceHelper.ts index 87fef788f867..262c1dfbb446 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/pipEnvServiceHelper.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/pipEnvServiceHelper.ts @@ -3,7 +3,7 @@ 'use strict'; -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import * as path from 'path'; import { Uri } from 'vscode'; import { IFileSystem } from '../../../../common/platform/types'; @@ -11,7 +11,7 @@ import { IPersistentState, IPersistentStateFactory } from '../../../../common/ty import { IPipEnvServiceHelper } from '../../../../interpreter/locators/types'; type PipEnvInformation = { pythonPath: string; workspaceFolder: string; envName: string }; -@injectable() + export class PipEnvServiceHelper implements IPipEnvServiceHelper { private initialized = false; private readonly state: IPersistentState>; diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index acf262619557..e8a9a431e4be 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -117,7 +117,7 @@ export function registerForIOC(serviceManager: IServiceManager) { KNOWN_PATH_SERVICE ); serviceManager.addSingleton(ICondaService, CondaService); - serviceManager.addSingleton(IPipEnvServiceHelper, PipEnvServiceHelper); + serviceManager.addSingleton(IPipEnvServiceHelper, PipEnvServiceHelperProxy); serviceManager.addSingleton( IPythonInPathCommandProvider, PythonInPathCommandProviderProxy @@ -273,6 +273,23 @@ class WorkspaceVirtualEnvironmentsSearchPathProviderProxy implements IVirtualEnv } } +@injectable() +class PipEnvServiceHelperProxy implements IPipEnvServiceHelper { + private readonly impl: IPipEnvServiceHelper; + constructor( + @inject(IPersistentStateFactory) statefactory: IPersistentStateFactory, + @inject(IFileSystem) fs: IFileSystem + ) { + this.impl = new PipEnvServiceHelper(statefactory, fs); + } + public async getPipEnvInfo(pythonPath: string): Promise<{ workspaceFolder: Uri; envName: string } | undefined> { + return this.impl.getPipEnvInfo(pythonPath); + } + public async trackWorkspaceFolder(pythonPath: string, workspaceFolder: Uri): Promise { + return this.impl.trackWorkspaceFolder(pythonPath, workspaceFolder); + } +} + @injectable() class BaseLocatorServiceProxy implements IInterpreterLocatorService { constructor(protected readonly impl: IInterpreterLocatorService) {} From 8d4f537e80f0e999badcc5f1f68c97cb748469a3 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 14:48:20 -0600 Subject: [PATCH 23/31] Add an IOC proxy for GlobalVirtualEnvironmentsSearchPathProvider. --- .../locators/services/globalVirtualEnvService.ts | 5 ++--- src/client/pythonEnvironments/legacyIOC.ts | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts index e6d4bf6ca23a..205f3f54fb53 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService.ts @@ -3,7 +3,7 @@ 'use strict'; -import { inject, injectable, named } from 'inversify'; +import { inject, named } from 'inversify'; import * as os from 'os'; import * as path from 'path'; import { Uri } from 'vscode'; @@ -27,8 +27,7 @@ export class GlobalVirtualEnvService extends BaseVirtualEnvService { } } -@injectable() -export class GlobalVirtualEnvironmentsSearchPathProvider implements IVirtualEnvironmentsSearchPathProvider { +export class GlobalVirtualEnvironmentsSearchPathProvider { private readonly config: IConfigurationService; private readonly currentProcess: ICurrentProcess; private readonly virtualEnvMgr: IVirtualEnvironmentManager; diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index e8a9a431e4be..2ccb1e2d54f6 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -137,7 +137,7 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton( IVirtualEnvironmentsSearchPathProvider, - GlobalVirtualEnvironmentsSearchPathProvider, + GlobalVirtualEnvironmentsSearchPathProviderProxy, 'global' ); serviceManager.addSingleton( @@ -273,6 +273,17 @@ class WorkspaceVirtualEnvironmentsSearchPathProviderProxy implements IVirtualEnv } } +@injectable() +class GlobalVirtualEnvironmentsSearchPathProviderProxy implements IVirtualEnvironmentsSearchPathProvider { + private readonly impl: IVirtualEnvironmentsSearchPathProvider; + constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { + this.impl = new GlobalVirtualEnvironmentsSearchPathProvider(serviceContainer); + } + public async getSearchPaths(resource?: Uri): Promise { + return this.impl.getSearchPaths(resource); + } +} + @injectable() class PipEnvServiceHelperProxy implements IPipEnvServiceHelper { private readonly impl: IPipEnvServiceHelper; @@ -290,6 +301,9 @@ class PipEnvServiceHelperProxy implements IPipEnvServiceHelper { } } +//=========================== +// locators + @injectable() class BaseLocatorServiceProxy implements IInterpreterLocatorService { constructor(protected readonly impl: IInterpreterLocatorService) {} From be8b4a25b294da282db0f84aec98060f04048c3a Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 15:02:33 -0600 Subject: [PATCH 24/31] Add an IOC proxy for CondaService. --- .../locators/services/condaService.ts | 7 +- src/client/pythonEnvironments/legacyIOC.ts | 66 ++++++++++++++++++- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/condaService.ts b/src/client/pythonEnvironments/discovery/locators/services/condaService.ts index 7f9a7e57233a..05a4fac6f1a0 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/condaService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/condaService.ts @@ -1,4 +1,4 @@ -import { inject, injectable, named, optional } from 'inversify'; +import { inject, named, optional } from 'inversify'; import * as path from 'path'; import { compare, parse, SemVer } from 'semver'; import { ConfigurationChangeEvent, Uri } from 'vscode'; @@ -9,7 +9,7 @@ import { IFileSystem, IPlatformService } from '../../../../common/platform/types import { IProcessServiceFactory } from '../../../../common/process/types'; import { IConfigurationService, IDisposableRegistry, IPersistentStateFactory } from '../../../../common/types'; import { cache } from '../../../../common/utils/decorators'; -import { ICondaService, IInterpreterLocatorService, WINDOWS_REGISTRY_SERVICE } from '../../../../interpreter/contracts'; +import { IInterpreterLocatorService, WINDOWS_REGISTRY_SERVICE } from '../../../../interpreter/contracts'; import { InterpreterType, PythonInterpreter } from '../../../info'; import { CondaEnvironmentInfo, CondaInfo } from './conda'; import { parseCondaEnvFileContents } from './condaHelper'; @@ -48,8 +48,7 @@ export const CondaGetEnvironmentPrefix = 'Outputting Environment Now...'; /** * A wrapper around a conda installation. */ -@injectable() -export class CondaService implements ICondaService { +export class CondaService { private condaFile?: Promise; private isAvailable: boolean | undefined; diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 2ccb1e2d54f6..bd4bb5c18608 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -3,8 +3,10 @@ // tslint:disable:no-use-before-declare max-classes-per-file -import { inject, injectable, named } from 'inversify'; +import { inject, injectable, named, optional } from 'inversify'; +import { SemVer } from 'semver'; import { Disposable, Event, Uri } from 'vscode'; +import { IWorkspaceService } from '../common/application/types'; import { IFileSystem, IPlatformService, IRegistry } from '../common/platform/types'; import { IProcessServiceFactory } from '../common/process/types'; import { IConfigurationService, IDisposableRegistry, IPersistentStateFactory } from '../common/types'; @@ -40,6 +42,7 @@ import { IServiceContainer, IServiceManager } from '../ioc/types'; import { PythonInterpreterLocatorService } from './discovery/locators'; import { InterpreterLocatorHelper } from './discovery/locators/helpers'; import { InterpreterLocatorProgressService } from './discovery/locators/progressService'; +import { CondaEnvironmentInfo, CondaInfo } from './discovery/locators/services/conda'; import { CondaEnvFileService } from './discovery/locators/services/condaEnvFileService'; import { CondaEnvService } from './discovery/locators/services/condaEnvService'; import { CondaService } from './discovery/locators/services/condaService'; @@ -116,7 +119,7 @@ export function registerForIOC(serviceManager: IServiceManager) { KnownPathsServiceProxy, KNOWN_PATH_SERVICE ); - serviceManager.addSingleton(ICondaService, CondaService); + serviceManager.addSingleton(ICondaService, CondaServiceProxy); serviceManager.addSingleton(IPipEnvServiceHelper, PipEnvServiceHelperProxy); serviceManager.addSingleton( IPythonInPathCommandProvider, @@ -301,6 +304,65 @@ class PipEnvServiceHelperProxy implements IPipEnvServiceHelper { } } +@injectable() +class CondaServiceProxy implements ICondaService { + private readonly impl: ICondaService; + constructor( + @inject(IProcessServiceFactory) processServiceFactory: IProcessServiceFactory, + @inject(IPlatformService) platform: IPlatformService, + @inject(IFileSystem) fileSystem: IFileSystem, + @inject(IPersistentStateFactory) persistentStateFactory: IPersistentStateFactory, + @inject(IConfigurationService) configService: IConfigurationService, + @inject(IDisposableRegistry) disposableRegistry: IDisposableRegistry, + @inject(IWorkspaceService) workspaceService: IWorkspaceService, + @inject(IInterpreterLocatorService) + @named(WINDOWS_REGISTRY_SERVICE) + @optional() + registryLookupForConda?: IInterpreterLocatorService + ) { + this.impl = new CondaService( + processServiceFactory, + platform, + fileSystem, + persistentStateFactory, + configService, + disposableRegistry, + workspaceService, + registryLookupForConda + ); + } + public get condaEnvironmentsFile(): string | undefined { + return this.impl.condaEnvironmentsFile; + } + public async getCondaFile(): Promise { + return this.impl.getCondaFile(); + } + public async isCondaAvailable(): Promise { + return this.impl.isCondaAvailable(); + } + public async getCondaVersion(): Promise { + return this.impl.getCondaVersion(); + } + public async getCondaInfo(): Promise { + return this.impl.getCondaInfo(); + } + public async getCondaEnvironments(ignoreCache: boolean): Promise { + return this.impl.getCondaEnvironments(ignoreCache); + } + public getInterpreterPath(condaEnvironmentPath: string): string { + return this.impl.getInterpreterPath(condaEnvironmentPath); + } + public async getCondaFileFromInterpreter(interpreterPath?: string, envName?: string): Promise { + return this.impl.getCondaFileFromInterpreter(interpreterPath, envName); + } + public async isCondaEnvironment(interpreterPath: string): Promise { + return this.impl.isCondaEnvironment(interpreterPath); + } + public async getCondaEnvironment(interpreterPath: string): Promise<{ name: string; path: string } | undefined> { + return this.impl.getCondaEnvironment(interpreterPath); + } +} + //=========================== // locators From 0e964e731dd18f430286a9c49048f0ac41682db0 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 15:11:50 -0600 Subject: [PATCH 25/31] Add an IOC proxy for InterpreterWatcherBuilder. --- .../services/interpreterWatcherBuilder.ts | 11 +++-------- src/client/pythonEnvironments/legacyIOC.ts | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts b/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts index 86362011c7fb..b44eb3632641 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts @@ -3,21 +3,16 @@ 'use strict'; -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import { Uri } from 'vscode'; import { IWorkspaceService } from '../../../../common/application/types'; import { traceDecorators } from '../../../../common/logger'; import { createDeferred } from '../../../../common/utils/async'; -import { - IInterpreterWatcher, - IInterpreterWatcherBuilder, - WORKSPACE_VIRTUAL_ENV_SERVICE -} from '../../../../interpreter/contracts'; +import { IInterpreterWatcher, WORKSPACE_VIRTUAL_ENV_SERVICE } from '../../../../interpreter/contracts'; import { IServiceContainer } from '../../../../ioc/types'; import { WorkspaceVirtualEnvWatcherService } from './workspaceVirtualEnvWatcherService'; -@injectable() -export class InterpreterWatcherBuilder implements IInterpreterWatcherBuilder { +export class InterpreterWatcherBuilder { private readonly watchersByResource = new Map>(); /** * Creates an instance of InterpreterWatcherBuilder. diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index bd4bb5c18608..4d470134ac36 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -152,7 +152,7 @@ export function registerForIOC(serviceManager: IServiceManager) { IKnownSearchPathsForInterpreters, KnownSearchPathsForInterpretersProxy ); - serviceManager.addSingleton(IInterpreterWatcherBuilder, InterpreterWatcherBuilder); + serviceManager.addSingleton(IInterpreterWatcherBuilder, InterpreterWatcherBuilderProxy); } @injectable() @@ -363,6 +363,20 @@ class CondaServiceProxy implements ICondaService { } } +@injectable() +class InterpreterWatcherBuilderProxy implements IInterpreterWatcherBuilder { + private readonly impl: IInterpreterWatcherBuilder; + constructor( + @inject(IWorkspaceService) workspaceService: IWorkspaceService, + @inject(IServiceContainer) serviceContainer: IServiceContainer + ) { + this.impl = new InterpreterWatcherBuilder(workspaceService, serviceContainer); + } + public async getWorkspaceVirtualEnvInterpreterWatcher(resource: Uri | undefined): Promise { + return this.impl.getWorkspaceVirtualEnvInterpreterWatcher(resource); + } +} + //=========================== // locators From d1e900d964071dada4a8c7916e97acb254c0c123 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 15:17:14 -0600 Subject: [PATCH 26/31] Add an IOC proxy for WorkspaceVirtualEnvWatcherService. --- .../workspaceVirtualEnvWatcherService.ts | 6 ++-- src/client/pythonEnvironments/legacyIOC.ts | 30 +++++++++++++++++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvWatcherService.ts b/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvWatcherService.ts index 85eea917e9fa..844d3fde4c70 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvWatcherService.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvWatcherService.ts @@ -3,7 +3,7 @@ 'use strict'; -import { inject, injectable } from 'inversify'; +import { inject } from 'inversify'; import * as path from 'path'; import { Disposable, Event, EventEmitter, FileSystemWatcher, RelativePattern, Uri } from 'vscode'; import { IWorkspaceService } from '../../../../common/application/types'; @@ -12,13 +12,11 @@ import { traceDecorators, traceVerbose } from '../../../../common/logger'; import { IPlatformService } from '../../../../common/platform/types'; import { IPythonExecutionFactory } from '../../../../common/process/types'; import { IDisposableRegistry, Resource } from '../../../../common/types'; -import { IInterpreterWatcher } from '../../../../interpreter/contracts'; const maxTimeToWaitForEnvCreation = 60_000; const timeToPollForEnvCreation = 2_000; -@injectable() -export class WorkspaceVirtualEnvWatcherService implements IInterpreterWatcher, Disposable { +export class WorkspaceVirtualEnvWatcherService { private readonly didCreate: EventEmitter; private timers = new Map(); private fsWatchers: FileSystemWatcher[] = []; diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 4d470134ac36..254408be4472 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -8,8 +8,8 @@ import { SemVer } from 'semver'; import { Disposable, Event, Uri } from 'vscode'; import { IWorkspaceService } from '../common/application/types'; import { IFileSystem, IPlatformService, IRegistry } from '../common/platform/types'; -import { IProcessServiceFactory } from '../common/process/types'; -import { IConfigurationService, IDisposableRegistry, IPersistentStateFactory } from '../common/types'; +import { IProcessServiceFactory, IPythonExecutionFactory } from '../common/process/types'; +import { IConfigurationService, IDisposableRegistry, IPersistentStateFactory, Resource } from '../common/types'; import { CONDA_ENV_FILE_SERVICE, CONDA_ENV_SERVICE, @@ -128,7 +128,7 @@ export function registerForIOC(serviceManager: IServiceManager) { serviceManager.add( IInterpreterWatcher, - WorkspaceVirtualEnvWatcherService, + WorkspaceVirtualEnvWatcherServiceProxy, WORKSPACE_VIRTUAL_ENV_SERVICE ); serviceManager.addSingleton(IWindowsStoreInterpreter, WindowsStoreInterpreterProxy); @@ -377,6 +377,30 @@ class InterpreterWatcherBuilderProxy implements IInterpreterWatcherBuilder { } } +@injectable() +class WorkspaceVirtualEnvWatcherServiceProxy implements IInterpreterWatcher, Disposable { + private readonly impl: IInterpreterWatcher & Disposable; + constructor( + @inject(IDisposableRegistry) disposableRegistry: Disposable[], + @inject(IWorkspaceService) workspaceService: IWorkspaceService, + @inject(IPlatformService) platformService: IPlatformService, + @inject(IPythonExecutionFactory) pythonExecFactory: IPythonExecutionFactory + ) { + this.impl = new WorkspaceVirtualEnvWatcherService( + disposableRegistry, + workspaceService, + platformService, + pythonExecFactory + ); + } + public get onDidCreate(): Event { + return this.onDidCreate; + } + public dispose() { + return this.impl.dispose(); + } +} + //=========================== // locators From 78fc597eae6e309b5aed2a958ccce9666c20d254 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Tue, 7 Jul 2020 16:05:39 -0600 Subject: [PATCH 27/31] Drop the legacy DI registration test. --- .../pythonEnvironments/legacyIOC.unit.test.ts | 110 ------------------ 1 file changed, 110 deletions(-) delete mode 100644 src/test/pythonEnvironments/legacyIOC.unit.test.ts diff --git a/src/test/pythonEnvironments/legacyIOC.unit.test.ts b/src/test/pythonEnvironments/legacyIOC.unit.test.ts deleted file mode 100644 index 90910a730d8f..000000000000 --- a/src/test/pythonEnvironments/legacyIOC.unit.test.ts +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -'use strict'; - -// tslint:disable: no-any - -import { instance, mock, verify } from 'ts-mockito'; -import { - CONDA_ENV_FILE_SERVICE, - CONDA_ENV_SERVICE, - CURRENT_PATH_SERVICE, - GLOBAL_VIRTUAL_ENV_SERVICE, - ICondaService, - IInterpreterLocatorHelper, - IInterpreterLocatorProgressService, - IInterpreterLocatorService, - IInterpreterWatcher, - IInterpreterWatcherBuilder, - IKnownSearchPathsForInterpreters, - INTERPRETER_LOCATOR_SERVICE, - IVirtualEnvironmentsSearchPathProvider, - KNOWN_PATH_SERVICE, - PIPENV_SERVICE, - WINDOWS_REGISTRY_SERVICE, - WORKSPACE_VIRTUAL_ENV_SERVICE -} from '../../client/interpreter/contracts'; -import { - IInterpreterHashProviderFactory, - IPipEnvServiceHelper, - IPythonInPathCommandProvider -} from '../../client/interpreter/locators/types'; -import { ServiceManager } from '../../client/ioc/serviceManager'; -import { PythonInterpreterLocatorService } from '../../client/pythonEnvironments/discovery/locators'; -import { InterpreterLocatorHelper } from '../../client/pythonEnvironments/discovery/locators/helpers'; -import { InterpreterLocatorProgressService } from '../../client/pythonEnvironments/discovery/locators/progressService'; -import { CondaEnvFileService } from '../../client/pythonEnvironments/discovery/locators/services/condaEnvFileService'; -import { CondaEnvService } from '../../client/pythonEnvironments/discovery/locators/services/condaEnvService'; -import { CondaService } from '../../client/pythonEnvironments/discovery/locators/services/condaService'; -import { - CurrentPathService, - PythonInPathCommandProvider -} from '../../client/pythonEnvironments/discovery/locators/services/currentPathService'; -import { - GlobalVirtualEnvironmentsSearchPathProvider, - GlobalVirtualEnvService -} from '../../client/pythonEnvironments/discovery/locators/services/globalVirtualEnvService'; -import { InterpreterHashProvider } from '../../client/pythonEnvironments/discovery/locators/services/hashProvider'; -import { InterpreterHashProviderFactory } from '../../client/pythonEnvironments/discovery/locators/services/hashProviderFactory'; -import { InterpreterWatcherBuilder } from '../../client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder'; -import { - KnownPathsService, - KnownSearchPathsForInterpreters -} from '../../client/pythonEnvironments/discovery/locators/services/KnownPathsService'; -import { PipEnvService } from '../../client/pythonEnvironments/discovery/locators/services/pipEnvService'; -import { PipEnvServiceHelper } from '../../client/pythonEnvironments/discovery/locators/services/pipEnvServiceHelper'; -import { WindowsRegistryService } from '../../client/pythonEnvironments/discovery/locators/services/windowsRegistryService'; -import { WindowsStoreInterpreter } from '../../client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter'; -import { - WorkspaceVirtualEnvironmentsSearchPathProvider, - WorkspaceVirtualEnvService -} from '../../client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvService'; -import { WorkspaceVirtualEnvWatcherService } from '../../client/pythonEnvironments/discovery/locators/services/workspaceVirtualEnvWatcherService'; -import { registerForIOC } from '../../client/pythonEnvironments/legacyIOC'; - -suite('Interpreters - Service Registry', () => { - test('Registrations', () => { - const serviceManager = mock(ServiceManager); - registerForIOC(instance(serviceManager)); - - [ - [IKnownSearchPathsForInterpreters, KnownSearchPathsForInterpreters], - [IVirtualEnvironmentsSearchPathProvider, GlobalVirtualEnvironmentsSearchPathProvider, 'global'], - [IVirtualEnvironmentsSearchPathProvider, WorkspaceVirtualEnvironmentsSearchPathProvider, 'workspace'], - - [ICondaService, CondaService], - [IPipEnvServiceHelper, PipEnvServiceHelper], - [IPythonInPathCommandProvider, PythonInPathCommandProvider], - - [IInterpreterWatcherBuilder, InterpreterWatcherBuilder], - - [IInterpreterLocatorService, PythonInterpreterLocatorService, INTERPRETER_LOCATOR_SERVICE], - [IInterpreterLocatorService, CondaEnvFileService, CONDA_ENV_FILE_SERVICE], - [IInterpreterLocatorService, CondaEnvService, CONDA_ENV_SERVICE], - [IInterpreterLocatorService, CurrentPathService, CURRENT_PATH_SERVICE], - [IInterpreterLocatorService, GlobalVirtualEnvService, GLOBAL_VIRTUAL_ENV_SERVICE], - [IInterpreterLocatorService, WorkspaceVirtualEnvService, WORKSPACE_VIRTUAL_ENV_SERVICE], - [IInterpreterLocatorService, PipEnvService, PIPENV_SERVICE], - - [IInterpreterLocatorService, WindowsRegistryService, WINDOWS_REGISTRY_SERVICE], - [IInterpreterLocatorService, KnownPathsService, KNOWN_PATH_SERVICE], - - [IInterpreterLocatorHelper, InterpreterLocatorHelper], - [IInterpreterLocatorProgressService, InterpreterLocatorProgressService], - - [WindowsStoreInterpreter, WindowsStoreInterpreter], - [InterpreterHashProvider, InterpreterHashProvider], - [IInterpreterHashProviderFactory, InterpreterHashProviderFactory] - ].forEach((mapping) => { - verify(serviceManager.addSingleton.apply(serviceManager, mapping as any)).once(); - }); - verify( - serviceManager.add( - IInterpreterWatcher, - WorkspaceVirtualEnvWatcherService, - WORKSPACE_VIRTUAL_ENV_SERVICE - ) - ).once(); - }); -}); From 45a2d5350650095a041b797850afae0f1010cc5e Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 8 Jul 2020 11:10:03 -0600 Subject: [PATCH 28/31] Fix sneaky usage of IPipEnvService. --- .../pipEnvActivationProvider.ts | 13 +++------- src/client/interpreter/contracts.ts | 2 +- src/client/interpreter/virtualEnvs/index.ts | 7 ++---- src/client/pythonEnvironments/legacyIOC.ts | 25 +++++++++++++++++-- .../virtualEnvManager.unit.test.ts | 10 +++----- .../virtualEnvs/index.unit.test.ts | 6 ++--- 6 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts b/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts index be1f2bf9bd75..f6ecf8c1b24a 100644 --- a/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts +++ b/src/client/common/terminal/environmentActivationProviders/pipEnvActivationProvider.ts @@ -3,15 +3,10 @@ 'use strict'; -import { inject, injectable, named } from 'inversify'; +import { inject, injectable } from 'inversify'; import { Uri } from 'vscode'; import '../../../common/extensions'; -import { - IInterpreterLocatorService, - IInterpreterService, - IPipEnvService, - PIPENV_SERVICE -} from '../../../interpreter/contracts'; +import { IInterpreterService, IPipEnvService } from '../../../interpreter/contracts'; import { InterpreterType } from '../../../pythonEnvironments/info'; import { IWorkspaceService } from '../../application/types'; import { IFileSystem } from '../../platform/types'; @@ -21,9 +16,7 @@ import { ITerminalActivationCommandProvider, TerminalShellType } from '../types' export class PipEnvActivationCommandProvider implements ITerminalActivationCommandProvider { constructor( @inject(IInterpreterService) private readonly interpreterService: IInterpreterService, - @inject(IInterpreterLocatorService) - @named(PIPENV_SERVICE) - private readonly pipenvService: IPipEnvService, + @inject(IPipEnvService) private readonly pipenvService: IPipEnvService, @inject(IWorkspaceService) private readonly workspaceService: IWorkspaceService, @inject(IFileSystem) private readonly fs: IFileSystem ) {} diff --git a/src/client/interpreter/contracts.ts b/src/client/interpreter/contracts.ts index 3065d75cbef1..f504e0b3374c 100644 --- a/src/client/interpreter/contracts.ts +++ b/src/client/interpreter/contracts.ts @@ -89,7 +89,7 @@ export interface IInterpreterHelper { } export const IPipEnvService = Symbol('IPipEnvService'); -export interface IPipEnvService extends IInterpreterLocatorService { +export interface IPipEnvService { executable: string; isRelatedPipEnvironment(dir: string, pythonPath: string): Promise; } diff --git a/src/client/interpreter/virtualEnvs/index.ts b/src/client/interpreter/virtualEnvs/index.ts index 04368633d1f5..a88fdd9e2324 100644 --- a/src/client/interpreter/virtualEnvs/index.ts +++ b/src/client/interpreter/virtualEnvs/index.ts @@ -14,7 +14,7 @@ import { IServiceContainer } from '../../ioc/types'; import * as globalenvs from '../../pythonEnvironments/discovery/globalenv'; import * as subenvs from '../../pythonEnvironments/discovery/subenv'; import { InterpreterType } from '../../pythonEnvironments/info'; -import { IInterpreterLocatorService, IPipEnvService, PIPENV_SERVICE } from '../contracts'; +import { IPipEnvService } from '../contracts'; import { IVirtualEnvironmentManager } from './types'; @injectable() @@ -26,10 +26,7 @@ export class VirtualEnvironmentManager implements IVirtualEnvironmentManager { constructor(@inject(IServiceContainer) private readonly serviceContainer: IServiceContainer) { this.processServiceFactory = serviceContainer.get(IProcessServiceFactory); this.fs = serviceContainer.get(IFileSystem); - this.pipEnvService = serviceContainer.get( - IInterpreterLocatorService, - PIPENV_SERVICE - ) as IPipEnvService; + this.pipEnvService = serviceContainer.get(IPipEnvService); this.workspaceService = serviceContainer.get(IWorkspaceService); } diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 254408be4472..90e61aa0a80a 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -24,6 +24,7 @@ import { IInterpreterWatcherBuilder, IKnownSearchPathsForInterpreters, INTERPRETER_LOCATOR_SERVICE, + IPipEnvService, IVirtualEnvironmentsSearchPathProvider, KNOWN_PATH_SERVICE, PIPENV_SERVICE, @@ -105,7 +106,7 @@ export function registerForIOC(serviceManager: IServiceManager) { ); serviceManager.addSingleton( IInterpreterLocatorService, - PipEnvServiceProxy, + PipEnvLocatorServiceProxy, PIPENV_SERVICE ); @@ -120,6 +121,7 @@ export function registerForIOC(serviceManager: IServiceManager) { KNOWN_PATH_SERVICE ); serviceManager.addSingleton(ICondaService, CondaServiceProxy); + serviceManager.addSingleton(IPipEnvService, PipEnvServiceProxy); serviceManager.addSingleton(IPipEnvServiceHelper, PipEnvServiceHelperProxy); serviceManager.addSingleton( IPythonInPathCommandProvider, @@ -287,6 +289,22 @@ class GlobalVirtualEnvironmentsSearchPathProviderProxy implements IVirtualEnviro } } +@injectable() +class PipEnvServiceProxy { + private readonly impl: IPipEnvService; + constructor(@inject(IInterpreterLocatorService) @named(PIPENV_SERVICE) proxy: IPipEnvService) { + // tslint:disable-next-line:no-any + const locator = (proxy as unknown) as any; + this.impl = locator.pipEnvService; + } + public async isRelatedPipEnvironment(dir: string, pythonPath: string): Promise { + return this.impl.isRelatedPipEnvironment(dir, pythonPath); + } + public get executable(): string { + return this.impl.executable; + } +} + @injectable() class PipEnvServiceHelperProxy implements IPipEnvServiceHelper { private readonly impl: IPipEnvServiceHelper; @@ -505,9 +523,12 @@ class KnownPathsServiceProxy extends BaseLocatorServiceProxy { } @injectable() -class PipEnvServiceProxy extends BaseLocatorServiceProxy { +class PipEnvLocatorServiceProxy extends BaseLocatorServiceProxy { + // This is only meant for consumption by PipEnvServiceProxy. + public readonly pipEnvService: IPipEnvService; constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { super(new PipEnvService(serviceContainer)); + this.pipEnvService = (this.impl as unknown) as IPipEnvService; } } diff --git a/src/test/interpreters/virtualEnvManager.unit.test.ts b/src/test/interpreters/virtualEnvManager.unit.test.ts index d4c3de8c7851..64d672d349a5 100644 --- a/src/test/interpreters/virtualEnvManager.unit.test.ts +++ b/src/test/interpreters/virtualEnvManager.unit.test.ts @@ -10,7 +10,7 @@ import { Uri, WorkspaceFolder } from 'vscode'; import { IWorkspaceService } from '../../client/common/application/types'; import { IFileSystem } from '../../client/common/platform/types'; import { IProcessServiceFactory } from '../../client/common/process/types'; -import { IInterpreterLocatorService, IPipEnvService, PIPENV_SERVICE } from '../../client/interpreter/contracts'; +import { IPipEnvService } from '../../client/interpreter/contracts'; import { VirtualEnvironmentManager } from '../../client/interpreter/virtualEnvs'; import { IServiceContainer } from '../../client/ioc/types'; @@ -51,9 +51,7 @@ suite('Virtual environment manager', () => { serviceContainer .setup((s) => s.get(TypeMoq.It.isValue(IProcessServiceFactory))) .returns(() => TypeMoq.Mock.ofType().object); - serviceContainer - .setup((s) => s.get(TypeMoq.It.isValue(IInterpreterLocatorService), TypeMoq.It.isValue(PIPENV_SERVICE))) - .returns(() => pipEnvService.object); + serviceContainer.setup((s) => s.get(TypeMoq.It.isValue(IPipEnvService))).returns(() => pipEnvService.object); serviceContainer .setup((s) => s.get(TypeMoq.It.isValue(IFileSystem))) .returns(() => TypeMoq.Mock.ofType().object); @@ -85,9 +83,7 @@ suite('Virtual environment manager', () => { pipEnvService .setup((w) => w.isRelatedPipEnvironment(TypeMoq.It.isAny(), TypeMoq.It.isAny())) .returns(() => Promise.resolve(isPipEnvironment)); - serviceContainer - .setup((s) => s.get(TypeMoq.It.isValue(IInterpreterLocatorService), TypeMoq.It.isValue(PIPENV_SERVICE))) - .returns(() => pipEnvService.object); + serviceContainer.setup((s) => s.get(TypeMoq.It.isValue(IPipEnvService))).returns(() => pipEnvService.object); const workspaceService = TypeMoq.Mock.ofType(); workspaceService.setup((w) => w.hasWorkspaceFolders).returns(() => false); if (resource) { diff --git a/src/test/interpreters/virtualEnvs/index.unit.test.ts b/src/test/interpreters/virtualEnvs/index.unit.test.ts index 3e8fefcffc1b..62d16eec7cca 100644 --- a/src/test/interpreters/virtualEnvs/index.unit.test.ts +++ b/src/test/interpreters/virtualEnvs/index.unit.test.ts @@ -14,7 +14,7 @@ import { IFileSystem, IPlatformService } from '../../../client/common/platform/t import { IProcessService, IProcessServiceFactory } from '../../../client/common/process/types'; import { ITerminalActivationCommandProvider } from '../../../client/common/terminal/types'; import { ICurrentProcess, IPathUtils } from '../../../client/common/types'; -import { IInterpreterLocatorService, IPipEnvService, PIPENV_SERVICE } from '../../../client/interpreter/contracts'; +import { IPipEnvService } from '../../../client/interpreter/contracts'; import { VirtualEnvironmentManager } from '../../../client/interpreter/virtualEnvs'; import { IServiceContainer } from '../../../client/ioc/types'; @@ -51,9 +51,7 @@ suite('Virtual Environment Manager', () => { serviceContainer.setup((c) => c.get(TypeMoq.It.isValue(IPathUtils))).returns(() => pathUtils.object); serviceContainer.setup((c) => c.get(TypeMoq.It.isValue(IFileSystem))).returns(() => fs.object); serviceContainer.setup((c) => c.get(TypeMoq.It.isValue(IWorkspaceService))).returns(() => workspace.object); - serviceContainer - .setup((c) => c.get(TypeMoq.It.isValue(IInterpreterLocatorService), TypeMoq.It.isValue(PIPENV_SERVICE))) - .returns(() => pipEnvService.object); + serviceContainer.setup((c) => c.get(TypeMoq.It.isValue(IPipEnvService))).returns(() => pipEnvService.object); serviceContainer .setup((c) => c.get(TypeMoq.It.isValue(ITerminalActivationCommandProvider), TypeMoq.It.isAny())) .returns(() => terminalActivation.object); From fa2ec88a392ae0bb31a2f86170b5c72891f643e2 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 8 Jul 2020 12:34:20 -0600 Subject: [PATCH 29/31] Fix sneaky usage of WorkspaceVirtualEnvWatcherService. --- src/client/interpreter/contracts.ts | 6 +++++- .../services/interpreterWatcherBuilder.ts | 11 ++++++---- src/client/pythonEnvironments/legacyIOC.ts | 14 ++++++++----- .../interpreterWatcherBuilder.unit.test.ts | 20 ++++++++++++------- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/client/interpreter/contracts.ts b/src/client/interpreter/contracts.ts index f504e0b3374c..b221264b3914 100644 --- a/src/client/interpreter/contracts.ts +++ b/src/client/interpreter/contracts.ts @@ -99,11 +99,15 @@ export interface IInterpreterLocatorHelper { mergeInterpreters(interpreters: PythonInterpreter[]): Promise; } -export const IInterpreterWatcher = Symbol('IInterpreterWatcher'); export interface IInterpreterWatcher { onDidCreate: Event; } +export const IInterpreterWatcherRegistry = Symbol('IInterpreterWatcherRegistry'); +export interface IInterpreterWatcherRegistry extends IInterpreterWatcher { + register(resource: Resource): Promise; +} + export const IInterpreterWatcherBuilder = Symbol('IInterpreterWatcherBuilder'); export interface IInterpreterWatcherBuilder { getWorkspaceVirtualEnvInterpreterWatcher(resource: Resource): Promise; diff --git a/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts b/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts index b44eb3632641..acfeed9b624d 100644 --- a/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts +++ b/src/client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder.ts @@ -8,9 +8,12 @@ import { Uri } from 'vscode'; import { IWorkspaceService } from '../../../../common/application/types'; import { traceDecorators } from '../../../../common/logger'; import { createDeferred } from '../../../../common/utils/async'; -import { IInterpreterWatcher, WORKSPACE_VIRTUAL_ENV_SERVICE } from '../../../../interpreter/contracts'; +import { + IInterpreterWatcher, + IInterpreterWatcherRegistry, + WORKSPACE_VIRTUAL_ENV_SERVICE +} from '../../../../interpreter/contracts'; import { IServiceContainer } from '../../../../ioc/types'; -import { WorkspaceVirtualEnvWatcherService } from './workspaceVirtualEnvWatcherService'; export class InterpreterWatcherBuilder { private readonly watchersByResource = new Map>(); @@ -32,8 +35,8 @@ export class InterpreterWatcherBuilder { if (!this.watchersByResource.has(key)) { const deferred = createDeferred(); this.watchersByResource.set(key, deferred.promise); - const watcher = this.serviceContainer.get( - IInterpreterWatcher, + const watcher = this.serviceContainer.get( + IInterpreterWatcherRegistry, WORKSPACE_VIRTUAL_ENV_SERVICE ); await watcher.register(resource); diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 90e61aa0a80a..737ca7d3973a 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -22,6 +22,7 @@ import { IInterpreterLocatorService, IInterpreterWatcher, IInterpreterWatcherBuilder, + IInterpreterWatcherRegistry, IKnownSearchPathsForInterpreters, INTERPRETER_LOCATOR_SERVICE, IPipEnvService, @@ -128,8 +129,8 @@ export function registerForIOC(serviceManager: IServiceManager) { PythonInPathCommandProviderProxy ); - serviceManager.add( - IInterpreterWatcher, + serviceManager.add( + IInterpreterWatcherRegistry, WorkspaceVirtualEnvWatcherServiceProxy, WORKSPACE_VIRTUAL_ENV_SERVICE ); @@ -396,8 +397,8 @@ class InterpreterWatcherBuilderProxy implements IInterpreterWatcherBuilder { } @injectable() -class WorkspaceVirtualEnvWatcherServiceProxy implements IInterpreterWatcher, Disposable { - private readonly impl: IInterpreterWatcher & Disposable; +class WorkspaceVirtualEnvWatcherServiceProxy implements IInterpreterWatcherRegistry, Disposable { + private readonly impl: IInterpreterWatcherRegistry & Disposable; constructor( @inject(IDisposableRegistry) disposableRegistry: Disposable[], @inject(IWorkspaceService) workspaceService: IWorkspaceService, @@ -412,7 +413,10 @@ class WorkspaceVirtualEnvWatcherServiceProxy implements IInterpreterWatcher, Dis ); } public get onDidCreate(): Event { - return this.onDidCreate; + return this.impl.onDidCreate; + } + public async register(resource: Resource): Promise { + return this.impl.register(resource); } public dispose() { return this.impl.dispose(); diff --git a/src/test/pythonEnvironments/discovery/locators/interpreterWatcherBuilder.unit.test.ts b/src/test/pythonEnvironments/discovery/locators/interpreterWatcherBuilder.unit.test.ts index 07e31dd236c6..729b90f8a201 100644 --- a/src/test/pythonEnvironments/discovery/locators/interpreterWatcherBuilder.unit.test.ts +++ b/src/test/pythonEnvironments/discovery/locators/interpreterWatcherBuilder.unit.test.ts @@ -8,7 +8,7 @@ import { expect } from 'chai'; import { anything, instance, mock, when } from 'ts-mockito'; import { WorkspaceService } from '../../../../client/common/application/workspace'; -import { IInterpreterWatcher, WORKSPACE_VIRTUAL_ENV_SERVICE } from '../../../../client/interpreter/contracts'; +import { IInterpreterWatcherRegistry, WORKSPACE_VIRTUAL_ENV_SERVICE } from '../../../../client/interpreter/contracts'; import { ServiceContainer } from '../../../../client/ioc/container'; import { InterpreterWatcherBuilder } from '../../../../client/pythonEnvironments/discovery/locators/services/interpreterWatcherBuilder'; @@ -20,9 +20,12 @@ suite('Interpreters - Watcher Builder', () => { const watcher = { register: () => Promise.resolve() }; when(workspaceService.getWorkspaceFolder(anything())).thenReturn(); - when(serviceContainer.get(IInterpreterWatcher, WORKSPACE_VIRTUAL_ENV_SERVICE)).thenReturn( - (watcher as any) as IInterpreterWatcher - ); + when( + serviceContainer.get( + IInterpreterWatcherRegistry, + WORKSPACE_VIRTUAL_ENV_SERVICE + ) + ).thenReturn((watcher as any) as IInterpreterWatcherRegistry); const item = await builder.getWorkspaceVirtualEnvInterpreterWatcher(undefined); @@ -35,9 +38,12 @@ suite('Interpreters - Watcher Builder', () => { const watcher = { register: () => Promise.resolve() }; when(workspaceService.getWorkspaceFolder(anything())).thenReturn(); - when(serviceContainer.get(IInterpreterWatcher, WORKSPACE_VIRTUAL_ENV_SERVICE)).thenReturn( - (watcher as any) as IInterpreterWatcher - ); + when( + serviceContainer.get( + IInterpreterWatcherRegistry, + WORKSPACE_VIRTUAL_ENV_SERVICE + ) + ).thenReturn((watcher as any) as IInterpreterWatcherRegistry); const [item1, item2, item3] = await Promise.all([ builder.getWorkspaceVirtualEnvInterpreterWatcher(undefined), From 5bc2bdd240a609e3c051d9afe9af04aa0a67494b Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 8 Jul 2020 12:59:25 -0600 Subject: [PATCH 30/31] Add a setter for BaseLocatorServiceProxy.didTriggerInterpreterSuggestions. --- src/client/pythonEnvironments/legacyIOC.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/client/pythonEnvironments/legacyIOC.ts b/src/client/pythonEnvironments/legacyIOC.ts index 737ca7d3973a..6d39f540171f 100644 --- a/src/client/pythonEnvironments/legacyIOC.ts +++ b/src/client/pythonEnvironments/legacyIOC.ts @@ -438,8 +438,11 @@ class BaseLocatorServiceProxy implements IInterpreterLocatorService { public get hasInterpreters(): Promise { return this.impl.hasInterpreters; } - public get didTriggerInterpreterSuggestions(): boolean | undefined { - return this.impl.didTriggerInterpreterSuggestions; + public get didTriggerInterpreterSuggestions(): boolean { + return this.impl.didTriggerInterpreterSuggestions as boolean; + } + public set didTriggerInterpreterSuggestions(value: boolean) { + this.impl.didTriggerInterpreterSuggestions = value; } public async getInterpreters(resource?: Uri, options?: GetInterpreterLocatorOptions): Promise { return this.impl.getInterpreters(resource, options); From 7215db02115de525c80ade72a9d2c122c18e25df Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Wed, 8 Jul 2020 13:07:51 -0600 Subject: [PATCH 31/31] Fix some "standard" tests. --- src/test/testing/pytest/pytest.discovery.test.ts | 4 ++-- src/test/testing/pytest/pytest.run.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/testing/pytest/pytest.discovery.test.ts b/src/test/testing/pytest/pytest.discovery.test.ts index c1351e13ab33..3ee16265b429 100644 --- a/src/test/testing/pytest/pytest.discovery.test.ts +++ b/src/test/testing/pytest/pytest.discovery.test.ts @@ -22,9 +22,9 @@ import { IConfigurationService } from '../../../client/common/types'; import { IEnvironmentActivationService } from '../../../client/interpreter/activation/types'; import { ICondaService, IInterpreterService } from '../../../client/interpreter/contracts'; import { InterpreterService } from '../../../client/interpreter/interpreterService'; +import { IWindowsStoreInterpreter } from '../../../client/interpreter/locators/types'; import { IServiceContainer } from '../../../client/ioc/types'; import { CondaService } from '../../../client/pythonEnvironments/discovery/locators/services/condaService'; -import { WindowsStoreInterpreter } from '../../../client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter'; import { registerForIOC } from '../../../client/pythonEnvironments/legacyIOC'; import { CommandSource } from '../../../client/testing/common/constants'; import { ITestManagerFactory } from '../../../client/testing/common/types'; @@ -71,7 +71,7 @@ suite('Unit Tests - pytest - discovery with mocked process output', () => { @inject(IProcessServiceFactory) processServiceFactory: IProcessServiceFactory, @inject(IConfigurationService) private readonly _configService: IConfigurationService, @inject(ICondaService) condaService: ICondaService, - @inject(WindowsStoreInterpreter) windowsStoreInterpreter: WindowsStoreInterpreter, + @inject(IWindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter, @inject(IBufferDecoder) decoder: IBufferDecoder, @inject(IPlatformService) platformService: IPlatformService ) { diff --git a/src/test/testing/pytest/pytest.run.test.ts b/src/test/testing/pytest/pytest.run.test.ts index d75a73869a8a..d4eca020f59c 100644 --- a/src/test/testing/pytest/pytest.run.test.ts +++ b/src/test/testing/pytest/pytest.run.test.ts @@ -23,9 +23,9 @@ import { IConfigurationService } from '../../../client/common/types'; import { IEnvironmentActivationService } from '../../../client/interpreter/activation/types'; import { ICondaService, IInterpreterService } from '../../../client/interpreter/contracts'; import { InterpreterService } from '../../../client/interpreter/interpreterService'; +import { IWindowsStoreInterpreter } from '../../../client/interpreter/locators/types'; import { IServiceContainer } from '../../../client/ioc/types'; import { CondaService } from '../../../client/pythonEnvironments/discovery/locators/services/condaService'; -import { WindowsStoreInterpreter } from '../../../client/pythonEnvironments/discovery/locators/services/windowsStoreInterpreter'; import { registerForIOC } from '../../../client/pythonEnvironments/legacyIOC'; import { CommandSource } from '../../../client/testing/common/constants'; import { UnitTestDiagnosticService } from '../../../client/testing/common/services/unitTestDiagnosticService'; @@ -394,7 +394,7 @@ suite('Unit Tests - pytest - run with mocked process output', () => { @inject(IProcessServiceFactory) processServiceFactory: IProcessServiceFactory, @inject(IConfigurationService) private readonly _configService: IConfigurationService, @inject(ICondaService) condaService: ICondaService, - @inject(WindowsStoreInterpreter) windowsStoreInterpreter: WindowsStoreInterpreter, + @inject(IWindowsStoreInterpreter) windowsStoreInterpreter: IWindowsStoreInterpreter, @inject(IBufferDecoder) decoder: IBufferDecoder, @inject(IPlatformService) platformService: IPlatformService ) {