diff --git a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts index 3ba19b01323..0cc8ef90f2c 100644 --- a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts @@ -18,7 +18,7 @@ import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configur import { IFileService } from 'vs/platform/files/common/files'; import { IWorkspaceContextService, IWorkspaceFolder, WorkbenchState, IWorkspaceFoldersChangeEvent } from 'vs/platform/workspace/common/workspace'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { IDebugConfigurationProvider, ICompound, IConfig, IGlobalConfig, IConfigurationManager, ILaunch, CONTEXT_DEBUG_CONFIGURATION_TYPE, IConfigPresentation, DebugConfigurationProviderTriggerKind } from 'vs/workbench/contrib/debug/common/debug'; +import { IDebugConfigurationProvider, ICompound, IConfig, IGlobalConfig, IConfigurationManager, ILaunch, CONTEXT_DEBUG_CONFIGURATION_TYPE, IConfigPresentation, DebugConfigurationProviderTriggerKind, IAdapterManager } from 'vs/workbench/contrib/debug/common/debug'; import { IEditorService, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { launchSchemaId } from 'vs/workbench/services/configuration/common/configuration'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; @@ -35,7 +35,6 @@ import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { flatten, distinct } from 'vs/base/common/arrays'; import { getVisibleAndSorted } from 'vs/workbench/contrib/debug/common/debugUtils'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; -import { AdapterManager } from 'vs/workbench/contrib/debug/browser/debugAdapterManager'; import { debugConfigure } from 'vs/workbench/contrib/debug/browser/debugIcons'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; @@ -62,7 +61,7 @@ export class ConfigurationManager implements IConfigurationManager { private debugConfigurationTypeContext: IContextKey; constructor( - private readonly adapterManager: AdapterManager, + private readonly adapterManager: IAdapterManager, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService, @IConfigurationService private readonly configurationService: IConfigurationService, @IQuickInputService private readonly quickInputService: IQuickInputService, @@ -481,7 +480,7 @@ abstract class AbstractLaunch { constructor( protected configurationManager: ConfigurationManager, - private readonly adapterManager: AdapterManager + private readonly adapterManager: IAdapterManager ) { } getCompound(name: string): ICompound | undefined { @@ -554,7 +553,7 @@ class Launch extends AbstractLaunch implements ILaunch { constructor( configurationManager: ConfigurationManager, - adapterManager: AdapterManager, + adapterManager: IAdapterManager, public workspace: IWorkspaceFolder, @IFileService private readonly fileService: IFileService, @ITextFileService private readonly textFileService: ITextFileService, @@ -637,7 +636,7 @@ class Launch extends AbstractLaunch implements ILaunch { class WorkspaceLaunch extends AbstractLaunch implements ILaunch { constructor( configurationManager: ConfigurationManager, - adapterManager: AdapterManager, + adapterManager: IAdapterManager, @IEditorService private readonly editorService: IEditorService, @IConfigurationService private readonly configurationService: IConfigurationService, @IWorkspaceContextService private readonly contextService: IWorkspaceContextService @@ -689,7 +688,7 @@ class UserLaunch extends AbstractLaunch implements ILaunch { constructor( configurationManager: ConfigurationManager, - adapterManager: AdapterManager, + adapterManager: IAdapterManager, @IConfigurationService private readonly configurationService: IConfigurationService, @IPreferencesService private readonly preferencesService: IPreferencesService ) { diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index ca1c5e318d2..31a9c6f6de3 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -157,6 +157,7 @@ export interface IDebugger { createDebugAdapter(session: IDebugSession): Promise; runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments, sessionId: string): Promise; getCustomTelemetryEndpoint(): ITelemetryEndpoint | undefined; + getInitialConfigurationContent(initialConfigs?: IConfig[]): Promise; } export interface IDebuggerMetadata { @@ -882,6 +883,10 @@ export interface IAdapterManager { substituteVariables(debugType: string, folder: IWorkspaceFolder | undefined, config: IConfig): Promise; runInTerminal(debugType: string, args: DebugProtocol.RunInTerminalRequestArguments, sessionId: string): Promise; + getEnabledDebugger(type: string): (IDebugger & IDebuggerMetadata) | undefined; + guessDebugger(gettingConfigurations: boolean): Promise<(IDebugger & IDebuggerMetadata) | undefined>; + + get onDidDebuggersExtPointRead(): Event; } export interface ILaunch { diff --git a/src/vs/workbench/contrib/debug/test/browser/debugConfigurationManager.test.ts b/src/vs/workbench/contrib/debug/test/browser/debugConfigurationManager.test.ts new file mode 100644 index 00000000000..950b044b58b --- /dev/null +++ b/src/vs/workbench/contrib/debug/test/browser/debugConfigurationManager.test.ts @@ -0,0 +1,107 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { CancellationToken } from 'vs/base/common/cancellation'; +import { DisposableStore } from 'vs/base/common/lifecycle'; +import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService'; +import { FileService } from 'vs/platform/files/common/fileService'; +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; +import { NullLogService } from 'vs/platform/log/common/log'; +import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService'; +import { ConfigurationManager } from 'vs/workbench/contrib/debug/browser/debugConfigurationManager'; +import { DebugConfigurationProviderTriggerKind, IAdapterManager, IConfig, IDebugAdapterExecutable, IDebugSession } from 'vs/workbench/contrib/debug/common/debug'; +import { TestHistoryService, TestQuickInputService } from 'vs/workbench/test/browser/workbenchTestServices'; +import { TestContextService, TestExtensionService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices'; + +suite('debugConfigurationManager', () => { + const configurationProviderType = 'custom-type'; + let _debugConfigurationManager: ConfigurationManager; + const disposables = new DisposableStore(); + + const adapterManager = { + getDebugAdapterDescriptor(session: IDebugSession, config: IConfig): Promise { + return Promise.resolve(undefined); + } + }; + + const configurationService = new TestConfigurationService(); + setup(() => { + const fileService = disposables.add(new FileService(new NullLogService())); + _debugConfigurationManager = new ConfigurationManager( + adapterManager, + new TestContextService(), + configurationService, + new TestQuickInputService(), + new TestInstantiationService(), + new TestStorageService(), + new TestExtensionService(), + new TestHistoryService(), + new UriIdentityService(fileService), + new ContextKeyService(configurationService)); + }); + + test('resolves configuration based on type', async () => { + disposables.add(_debugConfigurationManager.registerDebugConfigurationProvider({ + type: configurationProviderType, + resolveDebugConfiguration: (folderUri, config, token) => { + assert.strictEqual(config.type, configurationProviderType); + return Promise.resolve({ + ...config, + configurationResolved: true + }); + }, + triggerKind: DebugConfigurationProviderTriggerKind.Initial + })); + + const initialConfig: IConfig = { + type: configurationProviderType, + request: 'launch', + name: 'configName', + }; + + const resultConfig = await _debugConfigurationManager.resolveConfigurationByProviders(undefined, configurationProviderType, initialConfig, CancellationToken.None); + assert.strictEqual((resultConfig as any).configurationResolved, true, 'Configuration should be updated by test provider'); + }); + + test('resolves configuration from second provider if type changes', async () => { + const secondProviderType = 'second-provider'; + disposables.add(_debugConfigurationManager.registerDebugConfigurationProvider({ + type: configurationProviderType, + resolveDebugConfiguration: (folderUri, config, token) => { + assert.strictEqual(config.type, configurationProviderType); + return Promise.resolve({ + ...config, + type: secondProviderType + }); + }, + triggerKind: DebugConfigurationProviderTriggerKind.Initial + })); + disposables.add(_debugConfigurationManager.registerDebugConfigurationProvider({ + type: secondProviderType, + resolveDebugConfiguration: (folderUri, config, token) => { + assert.strictEqual(config.type, secondProviderType); + return Promise.resolve({ + ...config, + configurationResolved: true + }); + }, + triggerKind: DebugConfigurationProviderTriggerKind.Initial + })); + + const initialConfig: IConfig = { + type: configurationProviderType, + request: 'launch', + name: 'configName', + }; + + const resultConfig = await _debugConfigurationManager.resolveConfigurationByProviders(undefined, configurationProviderType, initialConfig, CancellationToken.None); + assert.strictEqual(resultConfig!.type, secondProviderType); + assert.strictEqual((resultConfig as any).configurationResolved, true, 'Configuration should be updated by test provider'); + }); + + teardown(() => disposables.clear()); +});