diff --git a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts index f971f5722be..aed656accd0 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadDebugService.ts @@ -8,7 +8,6 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import uri from 'vs/base/common/uri'; import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData } from 'vs/workbench/parts/debug/common/debug'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { ExtHostContext, ExtHostDebugServiceShape, MainThreadDebugServiceShape, DebugSessionUUID, MainContext, IExtHostContext, IBreakpointsDeltaDto, ISourceMultiBreakpointDto, ISourceBreakpointDto, IFunctionBreakpointDto @@ -25,8 +24,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape { constructor( extHostContext: IExtHostContext, - @IDebugService private debugService: IDebugService, - @IWorkspaceContextService private contextService: IWorkspaceContextService, + @IDebugService private debugService: IDebugService ) { this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDebugService); this._toDispose = []; @@ -180,8 +178,8 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape { public $startDebugging(_folderUri: uri | undefined, nameOrConfiguration: string | IConfig): TPromise { const folderUriString = _folderUri ? uri.revive(_folderUri).toString() : undefined; - const folder = folderUriString ? this.contextService.getWorkspace().folders.filter(wf => wf.uri.toString() === folderUriString).pop() : undefined; - return this.debugService.startDebugging(folder, nameOrConfiguration).then(x => { + const launch = folderUriString ? this.debugService.getConfigurationManager().getLaunches().filter(l => l.workspace && l.workspace.uri.toString() === folderUriString).pop() : undefined; + return this.debugService.startDebugging(launch, nameOrConfiguration).then(x => { return true; }, err => { return TPromise.wrapError(err && err.message ? err.message : 'cannot start debugging'); diff --git a/src/vs/workbench/parts/debug/browser/debugActions.ts b/src/vs/workbench/parts/debug/browser/debugActions.ts index 8cbe0a6d287..fb303070b97 100644 --- a/src/vs/workbench/parts/debug/browser/debugActions.ts +++ b/src/vs/workbench/parts/debug/browser/debugActions.ts @@ -126,7 +126,7 @@ export class StartAction extends AbstractDebugAction { public run(): TPromise { const launch = this.debugService.getConfigurationManager().selectedConfiguration.launch; - return this.debugService.startDebugging(launch ? launch.workspace : undefined, undefined, this.isNoDebug()); + return this.debugService.startDebugging(launch, undefined, this.isNoDebug()); } protected isNoDebug(): boolean { diff --git a/src/vs/workbench/parts/debug/browser/debugQuickOpen.ts b/src/vs/workbench/parts/debug/browser/debugQuickOpen.ts index c75ddf12c13..16f3a4b8de8 100644 --- a/src/vs/workbench/parts/debug/browser/debugQuickOpen.ts +++ b/src/vs/workbench/parts/debug/browser/debugQuickOpen.ts @@ -70,7 +70,7 @@ class StartDebugEntry extends Model.QuickOpenEntry { } // Run selected debug configuration this.debugService.getConfigurationManager().selectConfiguration(this.launch, this.configurationName); - this.debugService.startDebugging(this.launch.workspace).done(undefined, e => this.messageService.show(Severity.Error, e)); + this.debugService.startDebugging(this.launch).done(undefined, e => this.messageService.show(Severity.Error, e)); return true; } diff --git a/src/vs/workbench/parts/debug/common/debug.ts b/src/vs/workbench/parts/debug/common/debug.ts index 69096337e0d..164cad54b53 100644 --- a/src/vs/workbench/parts/debug/common/debug.ts +++ b/src/vs/workbench/parts/debug/common/debug.ts @@ -624,7 +624,7 @@ export interface IDebugService { * Also saves all files, manages if compounds are present in the configuration * and resolveds configurations via DebugConfigurationProviders. */ - startDebugging(root: IWorkspaceFolder, configOrName?: IConfig | string, noDebug?: boolean): TPromise; + startDebugging(launch: ILaunch, configOrName?: IConfig | string, noDebug?: boolean): TPromise; /** * Restarts a process or creates a new one if there is no active session. diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index f2400633557..8aee38d766b 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -658,10 +658,10 @@ export class DebugService implements debug.IDebugService { this.model.removeWatchExpressions(id); } - public startDebugging(root: IWorkspaceFolder, configOrName?: debug.IConfig | string, noDebug = false): TPromise { + public startDebugging(launch: debug.ILaunch, configOrName?: debug.IConfig | string, noDebug = false): TPromise { // make sure to save all files and that the configuration is up to date - return this.extensionService.activateByEvent('onDebug').then(() => this.textFileService.saveAll().then(() => this.configurationService.reloadConfiguration(root).then(() => + return this.extensionService.activateByEvent('onDebug').then(() => this.textFileService.saveAll().then(() => this.configurationService.reloadConfiguration(launch.workspace).then(() => this.extensionService.whenInstalledExtensionsRegistered().then(() => { if (this.model.getProcesses().length === 0) { this.removeReplExpressions(); @@ -669,8 +669,9 @@ export class DebugService implements debug.IDebugService { this.model.getBreakpoints().forEach(bp => bp.verified = false); } this.launchJsonChanged = false; - const launch = root ? this.configurationManager.getLaunches().filter(l => l.workspace && l.workspace.uri.toString() === root.uri.toString()).pop() - : this.configurationManager.getWorkspaceLaunch(); + if (!launch) { + launch = this.configurationManager.selectedConfiguration.launch; + } let config: debug.IConfig, compound: debug.ICompound; if (!configOrName) { @@ -695,28 +696,28 @@ export class DebugService implements debug.IDebugService { return TPromise.as(null); } - let rootForName: IWorkspaceFolder; + let launchForName: debug.ILaunch; if (typeof configData === 'string') { const launchesContainingName = this.configurationManager.getLaunches().filter(l => !!l.getConfiguration(name)); if (launchesContainingName.length === 1) { - rootForName = launchesContainingName[0].workspace; + launchForName = launchesContainingName[0]; } else if (launchesContainingName.length > 1 && launchesContainingName.indexOf(launch) >= 0) { // If there are multiple launches containing the configuration give priority to the configuration in the current launch - rootForName = launch.workspace; + launchForName = launch; } else { return TPromise.wrapError(new Error(launchesContainingName.length === 0 ? nls.localize('noConfigurationNameInWorkspace', "Could not find launch configuration '{0}' in the workspace.", name) : nls.localize('multipleConfigurationNamesInWorkspace', "There are multiple launch configurations `{0}` in the workspace. Use folder name to qualify the configuration.", name))); } } else if (configData.folder) { - const root = this.contextService.getWorkspace().folders.filter(f => f.name === configData.folder).pop(); - if (root) { - rootForName = root; + const launchesMatchingConfigData = this.configurationManager.getLaunches().filter(l => l.workspace && l.workspace.name === configData.folder && !!l.getConfiguration(configData.name)); + if (launchesMatchingConfigData.length === 1) { + launchForName = launchesMatchingConfigData[0]; } else { return TPromise.wrapError(new Error(nls.localize('noFolderWithName', "Can not find folder with name '{0}' for configuration '{1}' in compound '{2}'.", configData.folder, configData.name, compound.name))); } } - return this.startDebugging(rootForName, name, noDebug); + return this.startDebugging(launchForName, name, noDebug); })); } if (configOrName && !config) { @@ -751,7 +752,7 @@ export class DebugService implements debug.IDebugService { this.configurationManager.resolveConfigurationByProviders(launch && launch.workspace ? launch.workspace.uri : undefined, type, config).then(config => { // a falsy config indicates an aborted launch if (config && config.type) { - return this.createProcess(root, config, sessionId); + return this.createProcess(launch, config, sessionId); } if (launch) { @@ -766,8 +767,7 @@ export class DebugService implements debug.IDebugService { ))); } - private createProcess(root: IWorkspaceFolder, config: debug.IConfig, sessionId: string): TPromise { - const launch = root ? this.configurationManager.getLaunches().filter(l => l.workspace && l.workspace.uri.toString() === root.uri.toString()).pop() : undefined; + private createProcess(launch: debug.ILaunch, config: debug.IConfig, sessionId: string): TPromise { return this.textFileService.saveAll().then(() => (launch ? launch.resolveConfiguration(config) : TPromise.as(config)).then(resolvedConfig => { if (!resolvedConfig) { @@ -791,12 +791,13 @@ export class DebugService implements debug.IDebugService { this.toDisposeOnSessionEnd.set(sessionId, []); - return this.runPreLaunchTask(sessionId, root, resolvedConfig.preLaunchTask).then((taskSummary: ITaskSummary) => { + const workspace = launch ? launch.workspace : undefined; + return this.runPreLaunchTask(sessionId, workspace, resolvedConfig.preLaunchTask).then((taskSummary: ITaskSummary) => { const errorCount = resolvedConfig.preLaunchTask ? this.markerService.getStatistics().errors : 0; const successExitCode = taskSummary && taskSummary.exitCode === 0; const failureExitCode = taskSummary && taskSummary.exitCode !== undefined && taskSummary.exitCode !== 0; if (successExitCode || (errorCount === 0 && !failureExitCode)) { - return this.doCreateProcess(root, resolvedConfig, sessionId); + return this.doCreateProcess(workspace, resolvedConfig, sessionId); } const message = errorCount > 1 ? nls.localize('preLaunchTaskErrors', "Build errors have been detected during preLaunchTask '{0}'.", resolvedConfig.preLaunchTask) : @@ -806,7 +807,7 @@ export class DebugService implements debug.IDebugService { return this.choiceService.choose(severity.Error, message, [nls.localize('debugAnyway', "Debug Anyway"), nls.localize('showErrors', "Show Errors"), nls.localize('cancel', "Cancel")], 2, true).then(choice => { switch (choice) { case 0: - return this.doCreateProcess(root, resolvedConfig, sessionId); + return this.doCreateProcess(workspace, resolvedConfig, sessionId); case 1: return this.panelService.openPanel(Constants.MARKERS_PANEL_ID).then(() => undefined); default: @@ -817,7 +818,7 @@ export class DebugService implements debug.IDebugService { return this.choiceService.choose(severity.Error, err.message, [nls.localize('debugAnyway', "Debug Anyway"), debugactions.ConfigureAction.LABEL, this.taskService.configureAction().label, nls.localize('cancel', "Cancel")], 3, true).then(choice => { switch (choice) { case 0: - return this.doCreateProcess(root, resolvedConfig, sessionId); + return this.doCreateProcess(workspace, resolvedConfig, sessionId); case 1: return launch && launch.openConfigFile(false); case 2: @@ -1072,7 +1073,7 @@ export class DebugService implements debug.IDebugService { config.noDebug = process.configuration.noDebug; } config.__restart = restartData; - this.startDebugging(process.session.root, config).then(() => c(null), err => e(err)); + this.startDebugging(launch, config).then(() => c(null), err => e(err)); }, 300); }); }).then(() => { diff --git a/src/vs/workbench/parts/debug/test/common/mockDebug.ts b/src/vs/workbench/parts/debug/test/common/mockDebug.ts index 81acf9c471d..f1484bdf3e0 100644 --- a/src/vs/workbench/parts/debug/test/common/mockDebug.ts +++ b/src/vs/workbench/parts/debug/test/common/mockDebug.ts @@ -6,44 +6,44 @@ import uri from 'vs/base/common/uri'; import Event, { Emitter } from 'vs/base/common/event'; import { TPromise } from 'vs/base/common/winjs.base'; -import * as debug from 'vs/workbench/parts/debug/common/debug'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; +import { ILaunch, IDebugService, State, DebugEvent, IProcess, IConfigurationManager, IStackFrame, IBreakpointData, IBreakpointUpdateData, IConfig, IModel, IViewModel, ISession } from 'vs/workbench/parts/debug/common/debug'; -export class MockDebugService implements debug.IDebugService { +export class MockDebugService implements IDebugService { public _serviceBrand: any; - public get state(): debug.State { + public get state(): State { return null; } - public get onDidCustomEvent(): Event { + public get onDidCustomEvent(): Event { return null; } - public get onDidNewProcess(): Event { + public get onDidNewProcess(): Event { return null; } - public get onDidEndProcess(): Event { + public get onDidEndProcess(): Event { return null; } - public get onDidChangeState(): Event { + public get onDidChangeState(): Event { return null; } - public getConfigurationManager(): debug.IConfigurationManager { + public getConfigurationManager(): IConfigurationManager { return null; } - public focusStackFrame(focusedStackFrame: debug.IStackFrame): void { + public focusStackFrame(focusedStackFrame: IStackFrame): void { } - public addBreakpoints(uri: uri, rawBreakpoints: debug.IBreakpointData[]): TPromise { + public addBreakpoints(uri: uri, rawBreakpoints: IBreakpointData[]): TPromise { return TPromise.as(null); } - public updateBreakpoints(uri: uri, data: { [id: string]: debug.IBreakpointUpdateData }): void { } + public updateBreakpoints(uri: uri, data: { [id: string]: IBreakpointUpdateData }): void { } public enableOrDisableBreakpoints(enabled: boolean): TPromise { return TPromise.as(null); @@ -85,7 +85,7 @@ export class MockDebugService implements debug.IDebugService { public removeWatchExpressions(id?: string): void { } - public startDebugging(root: IWorkspaceFolder, configOrName?: debug.IConfig | string, noDebug?: boolean): TPromise { + public startDebugging(launch: ILaunch, configOrName?: IConfig | string, noDebug?: boolean): TPromise { return TPromise.as(null); } @@ -97,11 +97,11 @@ export class MockDebugService implements debug.IDebugService { return TPromise.as(null); } - public getModel(): debug.IModel { + public getModel(): IModel { return null; } - public getViewModel(): debug.IViewModel { + public getViewModel(): IViewModel { return null; } @@ -110,7 +110,7 @@ export class MockDebugService implements debug.IDebugService { public sourceIsNotAvailable(uri: uri): void { } } -export class MockSession implements debug.ISession { +export class MockSession implements ISession { public readyForBreakpoints = true; public emittedStopped = true; @@ -166,7 +166,7 @@ export class MockSession implements debug.ISession { return {}; } - public get onDidEvent(): Event { + public get onDidEvent(): Event { return null; } @@ -175,8 +175,8 @@ export class MockSession implements debug.ISession { return emitter.event; } - public get onDidExitAdapter(): Event { - const emitter = new Emitter(); + public get onDidExitAdapter(): Event { + const emitter = new Emitter(); return emitter.event; }