From 46f60b7b272df8c21c4c817e39fc911e5c9dee26 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 26 Oct 2020 15:10:22 +0100 Subject: [PATCH] debug: Do a late activation so extensions are not activated too early fixes #108578 --- .../debug/browser/debugActionViewItems.ts | 8 +++---- .../browser/debugConfigurationManager.ts | 22 ++++++++++++------- .../workbench/contrib/debug/common/debug.ts | 2 +- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts b/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts index 97d2519b297..f7fcea5002a 100644 --- a/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts +++ b/src/vs/workbench/contrib/debug/browser/debugActionViewItems.ts @@ -11,7 +11,7 @@ import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { SelectBox, ISelectOptionItem } from 'vs/base/browser/ui/selectBox/selectBox'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { ICommandService } from 'vs/platform/commands/common/commands'; -import { IDebugService, IDebugSession, IDebugConfiguration, IConfig, ILaunch, IDebugConfigurationProvider } from 'vs/workbench/contrib/debug/common/debug'; +import { IDebugService, IDebugSession, IDebugConfiguration, IConfig, ILaunch } from 'vs/workbench/contrib/debug/common/debug'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { attachSelectBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler'; import { selectBorder, selectBackground } from 'vs/platform/theme/common/colorRegistry'; @@ -34,7 +34,7 @@ export class StartDebugActionViewItem implements IActionViewItem { private options: { label: string, handler: (() => Promise) }[] = []; private toDispose: IDisposable[]; private selected = 0; - private providers: { label: string, provider: IDebugConfigurationProvider | undefined, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[] = []; + private providers: { label: string, type: string, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[] = []; constructor( private context: unknown, @@ -196,7 +196,7 @@ export class StartDebugActionViewItem implements IActionViewItem { } this.providers.forEach(p => { - if (p.provider && p.provider.type === manager.selectedConfiguration.type) { + if (p.type === manager.selectedConfiguration.type) { this.selected = this.options.length; } @@ -204,7 +204,7 @@ export class StartDebugActionViewItem implements IActionViewItem { label: `${p.label}...`, handler: async () => { const picked = await p.pick(); if (picked) { - await manager.selectConfiguration(picked.launch, picked.config.name, picked.config, p.provider?.type); + await manager.selectConfiguration(picked.launch, picked.config.name, picked.config, p.type); return true; } return false; diff --git a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts index 3a8524c0b81..041c97e217e 100644 --- a/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts @@ -266,7 +266,7 @@ export class ConfigurationManager implements IConfigurationManager { return results.reduce((first, second) => first.concat(second), []); } - async getDynamicProviders(): Promise<{ label: string, provider: IDebugConfigurationProvider | undefined, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[]> { + async getDynamicProviders(): Promise<{ label: string, type: string, getProvider: () => Promise, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[]> { const extensions = await this.extensionService.getExtensions(); const onDebugDynamicConfigurationsName = 'onDebugDynamicConfigurations'; const debugDynamicExtensionsTypes = extensions.reduce((acc, e) => { @@ -296,13 +296,17 @@ export class ConfigurationManager implements IConfigurationManager { return acc; }, [] as string[]); - await Promise.all(debugDynamicExtensionsTypes.map(type => this.activateDebuggers(onDebugDynamicConfigurationsName, type))); return debugDynamicExtensionsTypes.map(type => { - const provider = this.configProviders.find(p => p.type === type && p.triggerKind === DebugConfigurationProviderTriggerKind.Dynamic && p.provideDebugConfigurations); return { label: this.getDebuggerLabel(type)!, - provider, + getProvider: async () => { + await this.activateDebuggers(onDebugDynamicConfigurationsName, type); + return this.configProviders.find(p => p.type === type && p.triggerKind === DebugConfigurationProviderTriggerKind.Dynamic && p.provideDebugConfigurations); + }, + type, pick: async () => { + // Do a late 'onDebugDynamicConfigurationsName' activation so extensions are not activated too early #108578 + await this.activateDebuggers(onDebugDynamicConfigurationsName, type); const disposables = new DisposableStore(); const input = disposables.add(this.quickInputService.createQuickPick()); input.busy = true; @@ -325,6 +329,7 @@ export class ConfigurationManager implements IConfigurationManager { const token = new CancellationTokenSource(); const picks: Promise[] = []; + const provider = this.configProviders.find(p => p.type === type && p.triggerKind === DebugConfigurationProviderTriggerKind.Dynamic && p.provideDebugConfigurations); this.getLaunches().forEach(launch => { if (launch.workspace && provider) { picks.push(provider.provideDebugConfigurations!(launch.workspace.uri, token.token).then(configurations => configurations.map(config => ({ @@ -542,12 +547,13 @@ export class ConfigurationManager implements IConfigurationManager { } else if (!this.selectedName || names.indexOf(this.selectedName) === -1) { // We could not find the previously used name. We should get all dynamic configurations from providers // And potentially auto select the previously used dynamic configuration #96293 - const providers = await this.getDynamicProviders(); - const provider = providers.find(p => p.provider && p.provider.type === type); + const providers = (await this.getDynamicProviders()).filter(p => p.type === type); + const activatedProviders = await Promise.all(providers.map(p => p.getProvider())); + const provider = activatedProviders.find(p => p && p.type === type); let nameToSet = names.length ? names[0] : undefined; - if (provider && launch && launch.workspace && provider.provider) { + if (provider && launch && launch.workspace) { const token = new CancellationTokenSource(); - const dynamicConfigs = await provider.provider.provideDebugConfigurations!(launch.workspace.uri, token.token); + const dynamicConfigs = await provider.provideDebugConfigurations!(launch.workspace.uri, token.token); const dynamicConfig = dynamicConfigs.find(c => c.name === name); if (dynamicConfig) { config = dynamicConfig; diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index fd56628f5af..782bb5af4a1 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -697,7 +697,7 @@ export interface IConfigurationManager { isDebuggerInterestedInLanguage(language: string): boolean; hasDebugConfigurationProvider(debugType: string): boolean; - getDynamicProviders(): Promise<{ label: string, provider: IDebugConfigurationProvider | undefined, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[]>; + getDynamicProviders(): Promise<{ label: string, type: string, pick: () => Promise<{ launch: ILaunch, config: IConfig } | undefined> }[]>; registerDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): IDisposable; unregisterDebugConfigurationProvider(debugConfigurationProvider: IDebugConfigurationProvider): void; -- GitLab