diff --git a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts index f50028823b85b8e9c0e8c5bd82811551dbef6058..16a6f3be5029da5062437bd05bcb26bcc793b475 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts @@ -25,6 +25,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb private _breakpointEventsActive: boolean; private _debugAdapters: Map; private _debugAdaptersHandleCounter = 1; + private _debugConfigurationProviders: Map; constructor( extHostContext: IExtHostContext, @@ -46,7 +47,8 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb this._proxy.$acceptDebugSessionActiveChanged(this.getSessionDto(session)); })); - this._debugAdapters = new Map(); + this._debugAdapters = new Map(); + this._debugConfigurationProviders = new Map(); } public dispose(): void { @@ -166,13 +168,18 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb return Promise.resolve(this._proxy.$provideDebugAdapter(handle, this.getSessionDto(session), folder, config)); }; } - this.debugService.getConfigurationManager().registerDebugConfigurationProvider(handle, provider); + this._debugConfigurationProviders.set(handle, provider); + this._toDispose.push(this.debugService.getConfigurationManager().registerDebugConfigurationProvider(provider)); return Promise.resolve(undefined); } public $unregisterDebugConfigurationProvider(handle: number): Thenable { - this.debugService.getConfigurationManager().unregisterDebugConfigurationProvider(handle); + const provider = this._debugConfigurationProviders.get(handle); + if (provider) { + this._debugConfigurationProviders.delete(handle); + this.debugService.getConfigurationManager().unregisterDebugConfigurationProvider(provider); + } return TPromise.wrap(undefined); } diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 19a9c212ba16c75e8cf1961ba4620c7a6c417ce5..dff4da426ff6d6602842ef263bf8122ce32fc3f6 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -518,7 +518,6 @@ export interface IDebuggerContribution extends IPlatformSpecificAdapterContribut export interface IDebugConfigurationProvider { readonly type: string; - handle: number; resolveDebugConfiguration?(folderUri: uri | undefined, debugConfiguration: IConfig): Promise; provideDebugConfigurations?(folderUri: uri | undefined): Promise; provideDebugAdapter?(session: IDebugSession, folderUri: uri | undefined, config: IConfig): Promise; @@ -570,9 +569,10 @@ export interface IConfigurationManager { onDidSelectConfiguration: Event; needsToRunInExtHost(debugType: string): boolean; + hasDebugConfigurationProvider(debugType: string): boolean; - registerDebugConfigurationProvider(handle: number, debugConfigurationProvider: IDebugConfigurationProvider): void; - unregisterDebugConfigurationProvider(handle: number): void; + registerDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): IDisposable; + unregisterDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): void; resolveConfigurationByProviders(folderUri: uri | undefined, type: string | undefined, debugConfiguration: any): Thenable; provideDebugAdapter(session: IDebugSession, folderUri: uri | undefined, config: IConfig): Promise; diff --git a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts index ff6e340dff922ef0f83dff8da116cd6f30e90aab..248226309fc1cd5b51cb9e30b4252fdee2ecbf30 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugConfigurationManager.ts @@ -79,31 +79,36 @@ export class ConfigurationManager implements IConfigurationManager { } } - public registerDebugConfigurationProvider(handle: number, debugConfigurationProvider: IDebugConfigurationProvider): void { - if (!debugConfigurationProvider) { - return; - } + public registerDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): IDisposable { - debugConfigurationProvider.handle = handle; - this.providers = this.providers.filter(p => p.handle !== handle); this.providers.push(debugConfigurationProvider); - const dbg = this.getDebugger(debugConfigurationProvider.type); - // Check if the provider contributes provideDebugConfigurations method - if (dbg && debugConfigurationProvider.provideDebugConfigurations) { - dbg.hasConfigurationProvider = true; + + return { + dispose: () => { + this.unregisterDebugConfigurationProvider(debugConfigurationProvider); + } + }; + } + + public unregisterDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): void { + const ix = this.providers.indexOf(debugConfigurationProvider); + if (ix >= 0) { + this.providers.splice(ix, 1); } } + public hasDebugConfigurationProvider(debugType: string): boolean { + // check if there are providers for the given type that contribute a provideDebugConfigurations method + const providers = this.providers.filter(p => p.provideDebugConfigurations && (p.type === debugType)); + return providers.length > 0; + } + public needsToRunInExtHost(debugType: string): boolean { // if the given debugType matches any registered provider that has a provideTracker method, we need to run the DA in the EH const providers = this.providers.filter(p => p.hasTracker && (p.type === debugType || p.type === '*')); return providers.length > 0; } - public unregisterDebugConfigurationProvider(handle: number): void { - this.providers = this.providers.filter(p => p.handle !== handle); - } - public resolveConfigurationByProviders(folderUri: uri | undefined, type: string | undefined, debugConfiguration: IConfig): Thenable { return this.activateDebuggers(`onDebugResolve:${type}`).then(() => { // pipe the config through the promises sequentially. append at the end the '*' types @@ -358,7 +363,7 @@ export class ConfigurationManager implements IConfigurationManager { } if (!candidates) { - candidates = this.activateDebuggers('onDebugInitialConfigurations').then(() => this.debuggers.filter(a => a.hasInitialConfiguration() || a.hasConfigurationProvider)); + candidates = this.activateDebuggers('onDebugInitialConfigurations').then(() => this.debuggers.filter(dbg => dbg.hasInitialConfiguration() || dbg.hasConfigurationProvider())); } return candidates.then(debuggers => { diff --git a/src/vs/workbench/parts/debug/node/debugger.ts b/src/vs/workbench/parts/debug/node/debugger.ts index a45eabff95d62456f0ef84201f1391ec393fd315..53b50384cfc777e7b36ca2ba7c4df32765b24c5e 100644 --- a/src/vs/workbench/parts/debug/node/debugger.ts +++ b/src/vs/workbench/parts/debug/node/debugger.ts @@ -40,7 +40,6 @@ export class Debugger implements IDebugger { this.mergedExtensionDescriptions = [extensionDescription]; } - public hasConfigurationProvider = false; public createDebugAdapter(session: IDebugSession, root: IWorkspaceFolder, config: IConfig, outputService: IOutputService): Promise { if (this.inExtHost()) { @@ -149,6 +148,10 @@ export class Debugger implements IDebugger { return !!this.debuggerContribution.initialConfigurations; } + public hasConfigurationProvider() { + this.configurationManager.hasDebugConfigurationProvider(this.type); + } + public getInitialConfigurationContent(initialConfigs?: IConfig[]): Promise { // at this point we got some configs from the package.json and/or from registered DebugConfigurationProviders let initialConfigurations = this.debuggerContribution.initialConfigurations || [];