From 460ef3a4a68785198d8efaa77c369e2b4c8db789 Mon Sep 17 00:00:00 2001 From: isidor Date: Mon, 14 Oct 2019 16:43:07 +0200 Subject: [PATCH] debug session: more async await --- .../contrib/debug/browser/debugSession.ts | 592 +++++++++--------- 1 file changed, 303 insertions(+), 289 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/debugSession.ts b/src/vs/workbench/contrib/debug/browser/debugSession.ts index b54b3043509..783900187ab 100644 --- a/src/vs/workbench/contrib/debug/browser/debugSession.ts +++ b/src/vs/workbench/contrib/debug/browser/debugSession.ts @@ -30,7 +30,6 @@ import { Range } from 'vs/editor/common/core/range'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { ReplModel } from 'vs/workbench/contrib/debug/common/replModel'; -import { onUnexpectedError } from 'vs/base/common/errors'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { variableSetEmitter } from 'vs/workbench/contrib/debug/browser/variablesView'; import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation'; @@ -181,110 +180,100 @@ export class DebugSession implements IDebugSession { /** * create and initialize a new debug adapter for this session */ - initialize(dbgr: IDebugger): Promise { + async initialize(dbgr: IDebugger): Promise { if (this.raw) { // if there was already a connection make sure to remove old listeners this.shutdown(); } - return dbgr.getCustomTelemetryService().then(customTelemetryService => { - - return dbgr.createDebugAdapter(this).then(debugAdapter => { - - this.raw = new RawDebugSession(debugAdapter, dbgr, this.telemetryService, customTelemetryService, this.extensionHostDebugService, this.openerService); - - return this.raw.start().then(() => { - - this.registerListeners(); - - return this.raw!.initialize({ - clientID: 'vscode', - clientName: this.productService.nameLong, - adapterID: this.configuration.type, - pathFormat: 'path', - linesStartAt1: true, - columnsStartAt1: true, - supportsVariableType: true, // #8858 - supportsVariablePaging: true, // #9537 - supportsRunInTerminalRequest: true, // #10574 - locale: platform.locale - }).then(() => { - this.initialized = true; - this._onDidChangeState.fire(); - this.model.setExceptionBreakpoints(this.raw!.capabilities.exceptionBreakpointFilters || []); - }); - }); + try { + const customTelemetryService = await dbgr.getCustomTelemetryService(); + const debugAdapter = await dbgr.createDebugAdapter(this); + this.raw = new RawDebugSession(debugAdapter, dbgr, this.telemetryService, customTelemetryService, this.extensionHostDebugService, this.openerService); + + await this.raw.start(); + this.registerListeners(); + await this.raw!.initialize({ + clientID: 'vscode', + clientName: this.productService.nameLong, + adapterID: this.configuration.type, + pathFormat: 'path', + linesStartAt1: true, + columnsStartAt1: true, + supportsVariableType: true, // #8858 + supportsVariablePaging: true, // #9537 + supportsRunInTerminalRequest: true, // #10574 + locale: platform.locale }); - }).then(undefined, err => { + this.initialized = true; this._onDidChangeState.fire(); - return Promise.reject(err); - }); + this.model.setExceptionBreakpoints(this.raw!.capabilities.exceptionBreakpointFilters || []); + } catch (err) { + this.initialized = true; + this._onDidChangeState.fire(); + throw err; + } } /** * launch or attach to the debuggee */ - launchOrAttach(config: IConfig): Promise { - if (this.raw) { + async launchOrAttach(config: IConfig): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); + } - // __sessionID only used for EH debugging (but we add it always for now...) - config.__sessionId = this.getId(); + // __sessionID only used for EH debugging (but we add it always for now...) + config.__sessionId = this.getId(); + await this.raw.launchOrAttach(config); - return this.raw.launchOrAttach(config).then(result => { - return undefined; - }); - } - return Promise.reject(new Error('no debug adapter')); } /** * end the current debug adapter session */ - terminate(restart = false): Promise { - if (this.raw) { - this.cancelAllRequests(); - if (this.raw.capabilities.supportsTerminateRequest && this._configuration.resolved.request === 'launch') { - return this.raw.terminate(restart).then(response => { - return undefined; - }); - } - return this.raw.disconnect(restart).then(response => { - return undefined; - }); + async terminate(restart = false): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); + } + + this.cancelAllRequests(); + if (this.raw.capabilities.supportsTerminateRequest && this._configuration.resolved.request === 'launch') { + await this.raw.terminate(restart); + } else { + await this.raw.disconnect(restart); } - return Promise.reject(new Error('no debug adapter')); } /** * end the current debug adapter session */ - disconnect(restart = false): Promise { - if (this.raw) { - this.cancelAllRequests(); - return this.raw.disconnect(restart).then(response => { - return undefined; - }); + async disconnect(restart = false): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + this.cancelAllRequests(); + await this.raw.disconnect(restart); } /** * restart debug adapter session */ - restart(): Promise { - if (this.raw) { - this.cancelAllRequests(); - return this.raw.restart().then(() => undefined); + async restart(): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); - } - sendBreakpoints(modelUri: URI, breakpointsToSend: IBreakpoint[], sourceModified: boolean): Promise { + this.cancelAllRequests(); + await this.raw.restart(); + } + async sendBreakpoints(modelUri: URI, breakpointsToSend: IBreakpoint[], sourceModified: boolean): Promise { if (!this.raw) { - return Promise.reject(new Error('no debug adapter')); + throw new Error('no debug adapter'); } if (!this.raw.readyForBreakpoints) { @@ -300,237 +289,252 @@ export class DebugSession implements IDebugSession { rawSource.path = normalizeDriveLetter(rawSource.path); } - return this.raw.setBreakpoints({ + const response = await this.raw.setBreakpoints({ source: rawSource, lines: breakpointsToSend.map(bp => bp.sessionAgnosticData.lineNumber), breakpoints: breakpointsToSend.map(bp => ({ line: bp.sessionAgnosticData.lineNumber, column: bp.sessionAgnosticData.column, condition: bp.condition, hitCondition: bp.hitCondition, logMessage: bp.logMessage })), sourceModified - }).then(response => { + }); + if (response && response.body) { + const data = new Map(); + for (let i = 0; i < breakpointsToSend.length; i++) { + data.set(breakpointsToSend[i].getId(), response.body.breakpoints[i]); + } + + this.model.setBreakpointSessionData(this.getId(), this.capabilities, data); + } + } + + async sendFunctionBreakpoints(fbpts: IFunctionBreakpoint[]): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); + } + + if (this.raw.readyForBreakpoints) { + const response = await this.raw.setFunctionBreakpoints({ breakpoints: fbpts }); if (response && response.body) { const data = new Map(); - for (let i = 0; i < breakpointsToSend.length; i++) { - data.set(breakpointsToSend[i].getId(), response.body.breakpoints[i]); + for (let i = 0; i < fbpts.length; i++) { + data.set(fbpts[i].getId(), response.body.breakpoints[i]); } - this.model.setBreakpointSessionData(this.getId(), this.capabilities, data); } - }); + } } - sendFunctionBreakpoints(fbpts: IFunctionBreakpoint[]): Promise { - if (this.raw) { - if (this.raw.readyForBreakpoints) { - return this.raw.setFunctionBreakpoints({ breakpoints: fbpts }).then(response => { - if (response && response.body) { - const data = new Map(); - for (let i = 0; i < fbpts.length; i++) { - data.set(fbpts[i].getId(), response.body.breakpoints[i]); - } - this.model.setBreakpointSessionData(this.getId(), this.capabilities, data); - } - }); - } - - return Promise.resolve(undefined); + async sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + if (this.raw.readyForBreakpoints) { + await this.raw.setExceptionBreakpoints({ filters: exbpts.map(exb => exb.filter) }); + } } - sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): Promise { - if (this.raw) { - if (this.raw.readyForBreakpoints) { - return this.raw.setExceptionBreakpoints({ filters: exbpts.map(exb => exb.filter) }).then(() => undefined); - } - return Promise.resolve(undefined); + async dataBreakpointInfo(name: string, variablesReference?: number): Promise<{ dataId: string | null, description: string, canPersist?: boolean }> { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + if (!this.raw.readyForBreakpoints) { + throw new Error(nls.localize('sessionNotReadyForBreakpoints', "Session is not ready for breakpoints")); + } + + const response = await this.raw.dataBreakpointInfo({ name, variablesReference }); + return response.body; } - dataBreakpointInfo(name: string, variablesReference?: number): Promise<{ dataId: string | null, description: string, canPersist?: boolean }> { - if (this.raw) { - if (this.raw.readyForBreakpoints) { - return this.raw.dataBreakpointInfo({ name, variablesReference }).then(response => response.body); - } - return Promise.reject(new Error(nls.localize('sessionNotReadyForBreakpoints', "Session is not ready for breakpoints"))); + async sendDataBreakpoints(dataBreakpoints: IDataBreakpoint[]): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); - } - sendDataBreakpoints(dataBreakpoints: IDataBreakpoint[]): Promise { - if (this.raw) { - if (this.raw.readyForBreakpoints) { - return this.raw.setDataBreakpoints({ breakpoints: dataBreakpoints }).then(response => { - if (response && response.body) { - const data = new Map(); - for (let i = 0; i < dataBreakpoints.length; i++) { - data.set(dataBreakpoints[i].getId(), response.body.breakpoints[i]); - } - this.model.setBreakpointSessionData(this.getId(), this.capabilities, data); - } - }); + if (this.raw.readyForBreakpoints) { + const response = await this.raw.setDataBreakpoints({ breakpoints: dataBreakpoints }); + if (response && response.body) { + const data = new Map(); + for (let i = 0; i < dataBreakpoints.length; i++) { + data.set(dataBreakpoints[i].getId(), response.body.breakpoints[i]); + } + this.model.setBreakpointSessionData(this.getId(), this.capabilities, data); } - return Promise.resolve(undefined); } - return Promise.reject(new Error('no debug adapter')); } async breakpointsLocations(uri: URI, lineNumber: number): Promise { - if (this.raw) { - const source = this.getRawSource(uri); - const response = await this.raw.breakpointLocations({ source, line: lineNumber }); - if (!response.body || !response.body.breakpoints) { - return []; - } - - const positions = response.body.breakpoints.map(bp => ({ lineNumber: bp.line, column: bp.column || 1 })); + if (!this.raw) { + throw new Error('no debug adapter'); + } - return distinct(positions, p => `${p.lineNumber}:${p.column}`); + const source = this.getRawSource(uri); + const response = await this.raw.breakpointLocations({ source, line: lineNumber }); + if (!response.body || !response.body.breakpoints) { + return []; } - return Promise.reject(new Error('no debug adapter')); + + const positions = response.body.breakpoints.map(bp => ({ lineNumber: bp.line, column: bp.column || 1 })); + + return distinct(positions, p => `${p.lineNumber}:${p.column}`); } customRequest(request: string, args: any): Promise { - if (this.raw) { - return this.raw.custom(request, args); + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + return this.raw.custom(request, args); } stackTrace(threadId: number, startFrame: number, levels: number): Promise { - if (this.raw) { - const token = this.getNewCancellationToken(threadId); - return this.raw.stackTrace({ threadId, startFrame, levels }, token); + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + const token = this.getNewCancellationToken(threadId); + return this.raw.stackTrace({ threadId, startFrame, levels }, token); } - exceptionInfo(threadId: number): Promise { - if (this.raw) { - return this.raw.exceptionInfo({ threadId }).then(response => { - if (response) { - return { - id: response.body.exceptionId, - description: response.body.description, - breakMode: response.body.breakMode, - details: response.body.details - }; - } - return undefined; - }); + async exceptionInfo(threadId: number): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); + } + + const response = await this.raw.exceptionInfo({ threadId }); + if (response) { + return { + id: response.body.exceptionId, + description: response.body.description, + breakMode: response.body.breakMode, + details: response.body.details + }; } - return Promise.reject(new Error('no debug adapter')); + + return undefined; } scopes(frameId: number, threadId: number): Promise { - if (this.raw) { - const token = this.getNewCancellationToken(threadId); - return this.raw.scopes({ frameId }, token); + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + const token = this.getNewCancellationToken(threadId); + return this.raw.scopes({ frameId }, token); } variables(variablesReference: number, threadId: number | undefined, filter: 'indexed' | 'named' | undefined, start: number | undefined, count: number | undefined): Promise { - if (this.raw) { - const token = threadId ? this.getNewCancellationToken(threadId) : undefined; - return this.raw.variables({ variablesReference, filter, start, count }, token); + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + const token = threadId ? this.getNewCancellationToken(threadId) : undefined; + return this.raw.variables({ variablesReference, filter, start, count }, token); } evaluate(expression: string, frameId: number, context?: string): Promise { - if (this.raw) { - return this.raw.evaluate({ expression, frameId, context }); + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + return this.raw.evaluate({ expression, frameId, context }); } - restartFrame(frameId: number, threadId: number): Promise { - if (this.raw) { - return this.raw.restartFrame({ frameId }, threadId).then(() => undefined); + async restartFrame(frameId: number, threadId: number): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + await this.raw.restartFrame({ frameId }, threadId); } - next(threadId: number): Promise { - if (this.raw) { - return this.raw.next({ threadId }).then(() => undefined); + async next(threadId: number): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + await this.raw.next({ threadId }); } - stepIn(threadId: number): Promise { - if (this.raw) { - return this.raw.stepIn({ threadId }).then(() => undefined); + async stepIn(threadId: number): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + await this.raw.stepIn({ threadId }); } - stepOut(threadId: number): Promise { - if (this.raw) { - return this.raw.stepOut({ threadId }).then(() => undefined); + async stepOut(threadId: number): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + await this.raw.stepOut({ threadId }); } - stepBack(threadId: number): Promise { - if (this.raw) { - return this.raw.stepBack({ threadId }).then(() => undefined); + async stepBack(threadId: number): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + await this.raw.stepBack({ threadId }); } - continue(threadId: number): Promise { - if (this.raw) { - return this.raw.continue({ threadId }).then(() => undefined); + async continue(threadId: number): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + await this.raw.continue({ threadId }); } - reverseContinue(threadId: number): Promise { - if (this.raw) { - return this.raw.reverseContinue({ threadId }).then(() => undefined); + async reverseContinue(threadId: number): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + await this.raw.reverseContinue({ threadId }); } - pause(threadId: number): Promise { - if (this.raw) { - return this.raw.pause({ threadId }).then(() => undefined); + async pause(threadId: number): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + await this.raw.pause({ threadId }); } - terminateThreads(threadIds?: number[]): Promise { - if (this.raw) { - return this.raw.terminateThreads({ threadIds }).then(() => undefined); + async terminateThreads(threadIds?: number[]): Promise { + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + await this.raw.terminateThreads({ threadIds }); } setVariable(variablesReference: number, name: string, value: string): Promise { - if (this.raw) { - return this.raw.setVariable({ variablesReference, name, value }); + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + return this.raw.setVariable({ variablesReference, name, value }); } gotoTargets(source: DebugProtocol.Source, line: number, column?: number): Promise { - if (this.raw) { - return this.raw.gotoTargets({ source, line, column }); + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + return this.raw.gotoTargets({ source, line, column }); } goto(threadId: number, targetId: number): Promise { - if (this.raw) { - return this.raw.goto({ threadId, targetId }); + if (!this.raw) { + throw new Error('no debug adapter'); } - return Promise.reject(new Error('no debug adapter')); + + return this.raw.goto({ threadId, targetId }); } loadSource(resource: URI): Promise { - if (!this.raw) { return Promise.reject(new Error('no debug adapter')); } @@ -548,50 +552,48 @@ export class DebugSession implements IDebugSession { return this.raw.source({ sourceReference: rawSource.sourceReference || 0, source: rawSource }); } - getLoadedSources(): Promise { - if (this.raw) { - return this.raw.loadedSources({}).then(response => { - if (response.body && response.body.sources) { - return response.body.sources.map(src => this.getSource(src)); - } else { - return []; - } - }, () => { - return []; - }); + async getLoadedSources(): Promise { + if (!this.raw) { + return Promise.reject(new Error('no debug adapter')); + } + + const response = await this.raw.loadedSources({}); + if (response.body && response.body.sources) { + return response.body.sources.map(src => this.getSource(src)); + } else { + return []; } - return Promise.reject(new Error('no debug adapter')); } - completions(frameId: number | undefined, text: string, position: Position, overwriteBefore: number, token: CancellationToken): Promise { - if (this.raw) { - return this.raw.completions({ - frameId, - text, - column: position.column, - line: position.lineNumber, - }, token).then(response => { - - const result: CompletionItem[] = []; - if (response && response.body && response.body.targets) { - response.body.targets.forEach(item => { - if (item && item.label) { - result.push({ - label: item.label, - insertText: item.text || item.label, - kind: completionKindFromString(item.type || 'property'), - filterText: (item.start && item.length) ? text.substr(item.start, item.length).concat(item.label) : undefined, - range: Range.fromPositions(position.delta(0, -(item.length || overwriteBefore)), position), - sortText: item.sortText - }); - } + async completions(frameId: number | undefined, text: string, position: Position, overwriteBefore: number, token: CancellationToken): Promise { + if (!this.raw) { + return Promise.reject(new Error('no debug adapter')); + } + + const response = await this.raw.completions({ + frameId, + text, + column: position.column, + line: position.lineNumber, + }, token); + + const result: CompletionItem[] = []; + if (response && response.body && response.body.targets) { + response.body.targets.forEach(item => { + if (item && item.label) { + result.push({ + label: item.label, + insertText: item.text || item.label, + kind: completionKindFromString(item.type || 'property'), + filterText: (item.start && item.length) ? text.substr(item.start, item.length).concat(item.label) : undefined, + range: Range.fromPositions(position.delta(0, -(item.length || overwriteBefore)), position), + sortText: item.sortText }); } - - return result; }); } - return Promise.reject(new Error('no debug adapter')); + + return result; } //---- threads @@ -676,8 +678,9 @@ export class DebugSession implements IDebugSession { } } - private fetchThreads(stoppedDetails?: IRawStoppedDetails): Promise { - return this.raw ? this.raw.threads().then(response => { + private async fetchThreads(stoppedDetails?: IRawStoppedDetails): Promise { + if (this.raw) { + const response = await this.raw.threads(); if (response && response.body && response.body.threads) { this.model.rawUpdate({ sessionId: this.getId(), @@ -685,7 +688,7 @@ export class DebugSession implements IDebugSession { stoppedDetails }); } - }) : Promise.resolve(undefined); + } } //---- private @@ -695,57 +698,64 @@ export class DebugSession implements IDebugSession { return; } - this.rawListeners.push(this.raw.onDidInitialize(() => { + this.rawListeners.push(this.raw.onDidInitialize(async () => { aria.status(nls.localize('debuggingStarted', "Debugging started.")); - const sendConfigurationDone = () => { + const sendConfigurationDone = async () => { if (this.raw && this.raw.capabilities.supportsConfigurationDoneRequest) { - return this.raw.configurationDone().then(undefined, () => { + try { + await this.raw.configurationDone(); + } catch (e) { // Disconnect the debug session on configuration done error #10596 if (this.raw) { this.raw.disconnect(); } - }); + } } return undefined; }; // Send all breakpoints - this.debugService.sendAllBreakpoints(this).then(sendConfigurationDone, sendConfigurationDone) - .then(() => this.fetchThreads()); + try { + await this.debugService.sendAllBreakpoints(this); + await sendConfigurationDone(); + } catch { + await sendConfigurationDone(); + } + await this.fetchThreads(); })); - this.rawListeners.push(this.raw.onDidStop(event => { - this.fetchThreads(event.body).then(() => { - const thread = typeof event.body.threadId === 'number' ? this.getThread(event.body.threadId) : undefined; - if (thread) { - // Call fetch call stack twice, the first only return the top stack frame. - // Second retrieves the rest of the call stack. For performance reasons #25605 - const promises = this.model.fetchCallStack(thread); - const focus = async () => { - if (!event.body.preserveFocusHint && thread.getCallStack().length) { - await this.debugService.focusStackFrame(undefined, thread); - if (thread.stoppedDetails) { - if (this.configurationService.getValue('debug').openDebug === 'openOnDebugBreak') { - this.viewletService.openViewlet(VIEWLET_ID); - } - - if (this.configurationService.getValue('debug').focusWindowOnBreak) { - this.hostService.focus(); - } + this.rawListeners.push(this.raw.onDidStop(async event => { + await this.fetchThreads(event.body); + const thread = typeof event.body.threadId === 'number' ? this.getThread(event.body.threadId) : undefined; + if (thread) { + // Call fetch call stack twice, the first only return the top stack frame. + // Second retrieves the rest of the call stack. For performance reasons #25605 + const promises = this.model.fetchCallStack(thread); + const focus = async () => { + if (!event.body.preserveFocusHint && thread.getCallStack().length) { + await this.debugService.focusStackFrame(undefined, thread); + if (thread.stoppedDetails) { + if (this.configurationService.getValue('debug').openDebug === 'openOnDebugBreak') { + this.viewletService.openViewlet(VIEWLET_ID); } - } - }; - promises.topCallStack.then(focus); - promises.wholeCallStack.then(() => { - if (!this.debugService.getViewModel().focusedStackFrame) { - // The top stack frame can be deemphesized so try to focus again #68616 - focus(); + if (this.configurationService.getValue('debug').focusWindowOnBreak) { + this.hostService.focus(); + } } - }); + } + }; + + await promises.topCallStack; + focus(); + await promises.wholeCallStack; + if (!this.debugService.getViewModel().focusedStackFrame) { + // The top stack frame can be deemphesized so try to focus again #68616 + focus(); } - }).then(() => this._onDidChangeState.fire()); + } + this._onDidChangeState.fire(); })); this.rawListeners.push(this.raw.onDidThread(event => { @@ -765,12 +775,12 @@ export class DebugSession implements IDebugSession { } })); - this.rawListeners.push(this.raw.onDidTerminateDebugee(event => { + this.rawListeners.push(this.raw.onDidTerminateDebugee(async event => { aria.status(nls.localize('debuggingStopped', "Debugging stopped.")); if (event.body && event.body.restart) { - this.debugService.restartSession(this, event.body.restart).then(undefined, onUnexpectedError); + await this.debugService.restartSession(this, event.body.restart); } else if (this.raw) { - this.raw.disconnect(); + await this.raw.disconnect(); } })); @@ -791,7 +801,7 @@ export class DebugSession implements IDebugSession { })); let outpuPromises: Promise[] = []; - this.rawListeners.push(this.raw.onDidOutput(event => { + this.rawListeners.push(this.raw.onDidOutput(async event => { if (!event.body || !this.raw) { return; } @@ -817,17 +827,21 @@ export class DebugSession implements IDebugSession { } : undefined; if (event.body.variablesReference) { const container = new ExpressionContainer(this, undefined, event.body.variablesReference, generateUuid()); - outpuPromises.push(container.getChildren().then(children => { - return Promise.all(waitFor).then(() => children.forEach(child => { + outpuPromises.push(container.getChildren().then(async children => { + await Promise.all(waitFor); + children.forEach(child => { // Since we can not display multiple trees in a row, we are displaying these variables one after the other (ignoring their names) (child).name = null; this.appendToRepl(child, outputSeverity, source); - })); + }); })); } else if (typeof event.body.output === 'string') { - Promise.all(waitFor).then(() => this.appendToRepl(event.body.output, outputSeverity, source)); + await Promise.all(waitFor); + this.appendToRepl(event.body.output, outputSeverity, source); } - Promise.all(outpuPromises).then(() => outpuPromises = []); + + await Promise.all(outpuPromises); + outpuPromises = []; })); this.rawListeners.push(this.raw.onDidBreakpoint(event => { -- GitLab