parent
aa0231b08b
commit
64980ea1f3
|
@ -361,23 +361,24 @@ class ExtensionHostDebugAdapter extends AbstractDebugAdapter {
|
|||
super();
|
||||
}
|
||||
|
||||
public fireError(handle: number, err: Error) {
|
||||
fireError(handle: number, err: Error) {
|
||||
this._onError.fire(err);
|
||||
}
|
||||
|
||||
public fireExit(handle: number, code: number, signal: string) {
|
||||
fireExit(handle: number, code: number, signal: string) {
|
||||
this._onExit.fire(code);
|
||||
}
|
||||
|
||||
public startSession(): Promise<void> {
|
||||
startSession(): Promise<void> {
|
||||
return Promise.resolve(this._proxy.$startDASession(this._handle, this._ds.getSessionDto(this._session)));
|
||||
}
|
||||
|
||||
public sendMessage(message: DebugProtocol.ProtocolMessage): void {
|
||||
sendMessage(message: DebugProtocol.ProtocolMessage): void {
|
||||
this._proxy.$sendDAMessage(this._handle, convertToDAPaths(message, true));
|
||||
}
|
||||
|
||||
public stopSession(): Promise<void> {
|
||||
async stopSession(): Promise<void> {
|
||||
await this.cancelPendingRequests();
|
||||
return Promise.resolve(this._proxy.$stopDASession(this._handle));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import { onUnexpectedError } from 'vs/base/common/errors';
|
|||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
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';
|
||||
|
||||
export class DebugSession implements IDebugSession {
|
||||
|
||||
|
@ -43,6 +44,7 @@ export class DebugSession implements IDebugSession {
|
|||
|
||||
private sources = new Map<string, Source>();
|
||||
private threads = new Map<number, Thread>();
|
||||
private cancellationMap = new Map<number, CancellationTokenSource[]>();
|
||||
private rawListeners: IDisposable[] = [];
|
||||
private fetchThreadsScheduler: RunOnceScheduler | undefined;
|
||||
private repl: ReplModel;
|
||||
|
@ -235,6 +237,7 @@ export class DebugSession implements IDebugSession {
|
|||
*/
|
||||
terminate(restart = false): Promise<void> {
|
||||
if (this.raw) {
|
||||
this.cancelAllRequests();
|
||||
if (this.raw.capabilities.supportsTerminateRequest && this._configuration.resolved.request === 'launch') {
|
||||
return this.raw.terminate(restart).then(response => {
|
||||
return undefined;
|
||||
|
@ -252,6 +255,7 @@ export class DebugSession implements IDebugSession {
|
|||
*/
|
||||
disconnect(restart = false): Promise<void> {
|
||||
if (this.raw) {
|
||||
this.cancelAllRequests();
|
||||
return this.raw.disconnect(restart).then(response => {
|
||||
return undefined;
|
||||
});
|
||||
|
@ -264,6 +268,7 @@ export class DebugSession implements IDebugSession {
|
|||
*/
|
||||
restart(): Promise<void> {
|
||||
if (this.raw) {
|
||||
this.cancelAllRequests();
|
||||
return this.raw.restart().then(() => undefined);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
|
@ -380,7 +385,8 @@ export class DebugSession implements IDebugSession {
|
|||
|
||||
stackTrace(threadId: number, startFrame: number, levels: number): Promise<DebugProtocol.StackTraceResponse> {
|
||||
if (this.raw) {
|
||||
return this.raw.stackTrace({ threadId, startFrame, levels });
|
||||
const token = this.getNewCancellationToken(threadId);
|
||||
return this.raw.stackTrace({ threadId, startFrame, levels }, token);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
@ -402,16 +408,18 @@ export class DebugSession implements IDebugSession {
|
|||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
scopes(frameId: number): Promise<DebugProtocol.ScopesResponse> {
|
||||
scopes(frameId: number, threadId: number): Promise<DebugProtocol.ScopesResponse> {
|
||||
if (this.raw) {
|
||||
return this.raw.scopes({ frameId });
|
||||
const token = this.getNewCancellationToken(threadId);
|
||||
return this.raw.scopes({ frameId }, token);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
variables(variablesReference: number, filter: 'indexed' | 'named' | undefined, start: number | undefined, count: number | undefined): Promise<DebugProtocol.VariablesResponse> {
|
||||
variables(variablesReference: number, threadId: number | undefined, filter: 'indexed' | 'named' | undefined, start: number | undefined, count: number | undefined): Promise<DebugProtocol.VariablesResponse> {
|
||||
if (this.raw) {
|
||||
return this.raw.variables({ variablesReference, filter, start, count });
|
||||
const token = threadId ? this.getNewCancellationToken(threadId) : undefined;
|
||||
return this.raw.variables({ variablesReference, filter, start, count }, token);
|
||||
}
|
||||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
@ -541,14 +549,14 @@ export class DebugSession implements IDebugSession {
|
|||
return Promise.reject(new Error('no debug adapter'));
|
||||
}
|
||||
|
||||
completions(frameId: number | undefined, text: string, position: Position, overwriteBefore: number): Promise<CompletionItem[]> {
|
||||
completions(frameId: number | undefined, text: string, position: Position, overwriteBefore: number, token: CancellationToken): Promise<CompletionItem[]> {
|
||||
if (this.raw) {
|
||||
return this.raw.completions({
|
||||
frameId,
|
||||
text,
|
||||
column: position.column,
|
||||
line: position.lineNumber
|
||||
}).then(response => {
|
||||
line: position.lineNumber,
|
||||
}, token).then(response => {
|
||||
|
||||
const result: CompletionItem[] = [];
|
||||
if (response && response.body && response.body.targets) {
|
||||
|
@ -757,6 +765,16 @@ export class DebugSession implements IDebugSession {
|
|||
|
||||
this.rawListeners.push(this.raw.onDidContinued(event => {
|
||||
const threadId = event.body.allThreadsContinued !== false ? undefined : event.body.threadId;
|
||||
if (threadId) {
|
||||
const tokens = this.cancellationMap.get(threadId);
|
||||
this.cancellationMap.delete(threadId);
|
||||
if (tokens) {
|
||||
tokens.forEach(t => t.cancel());
|
||||
}
|
||||
} else {
|
||||
this.cancelAllRequests();
|
||||
}
|
||||
|
||||
this.model.clearThreads(this.getId(), false, threadId);
|
||||
this._onDidChangeState.fire();
|
||||
}));
|
||||
|
@ -787,7 +805,7 @@ export class DebugSession implements IDebugSession {
|
|||
source: this.getSource(event.body.source)
|
||||
} : undefined;
|
||||
if (event.body.variablesReference) {
|
||||
const container = new ExpressionContainer(this, event.body.variablesReference, generateUuid());
|
||||
const container = new ExpressionContainer(this, undefined, event.body.variablesReference, generateUuid());
|
||||
outpuPromises.push(container.getChildren().then(children => {
|
||||
return Promise.all(waitFor).then(() => 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)
|
||||
|
@ -896,6 +914,20 @@ export class DebugSession implements IDebugSession {
|
|||
return source;
|
||||
}
|
||||
|
||||
private getNewCancellationToken(threadId: number): CancellationToken {
|
||||
const tokenSource = new CancellationTokenSource();
|
||||
const tokens = this.cancellationMap.get(threadId) || [];
|
||||
tokens.push(tokenSource);
|
||||
this.cancellationMap.set(threadId, tokens);
|
||||
|
||||
return tokenSource.token;
|
||||
}
|
||||
|
||||
private cancelAllRequests(): void {
|
||||
this.cancellationMap.forEach(tokens => tokens.forEach(t => t.cancel()));
|
||||
this.cancellationMap.clear();
|
||||
}
|
||||
|
||||
private getUriKey(uri: URI): string {
|
||||
// TODO: the following code does not make sense if uri originates from a different platform
|
||||
return platform.isLinux ? uri.toString() : uri.toString().toLowerCase();
|
||||
|
|
|
@ -19,6 +19,7 @@ import { IProcessEnvironment } from 'vs/base/common/platform';
|
|||
import { env as processEnv } from 'vs/base/common/process';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
/**
|
||||
* This interface represents a single command line argument split into a "prefix" and a "path" half.
|
||||
|
@ -112,8 +113,6 @@ export class RawDebugSession implements IDisposable {
|
|||
}
|
||||
}));
|
||||
|
||||
this.toDispose.push(this.onDidContinued(() => this.cancelPendingRequests()));
|
||||
|
||||
this.debugAdapter.onEvent(event => {
|
||||
switch (event.event) {
|
||||
case 'initialized':
|
||||
|
@ -346,9 +345,9 @@ export class RawDebugSession implements IDisposable {
|
|||
return Promise.reject(new Error('restartFrame not supported'));
|
||||
}
|
||||
|
||||
completions(args: DebugProtocol.CompletionsArguments): Promise<DebugProtocol.CompletionsResponse> {
|
||||
completions(args: DebugProtocol.CompletionsArguments, token: CancellationToken): Promise<DebugProtocol.CompletionsResponse> {
|
||||
if (this.capabilities.supportsCompletionsRequest) {
|
||||
return this.send<DebugProtocol.CompletionsResponse>('completions', args);
|
||||
return this.send<DebugProtocol.CompletionsResponse>('completions', args, token);
|
||||
}
|
||||
return Promise.reject(new Error('completions not supported'));
|
||||
}
|
||||
|
@ -389,8 +388,8 @@ export class RawDebugSession implements IDisposable {
|
|||
return Promise.reject(new Error('configurationDone not supported'));
|
||||
}
|
||||
|
||||
stackTrace(args: DebugProtocol.StackTraceArguments): Promise<DebugProtocol.StackTraceResponse> {
|
||||
return this.send<DebugProtocol.StackTraceResponse>('stackTrace', args);
|
||||
stackTrace(args: DebugProtocol.StackTraceArguments, token: CancellationToken): Promise<DebugProtocol.StackTraceResponse> {
|
||||
return this.send<DebugProtocol.StackTraceResponse>('stackTrace', args, token);
|
||||
}
|
||||
|
||||
exceptionInfo(args: DebugProtocol.ExceptionInfoArguments): Promise<DebugProtocol.ExceptionInfoResponse> {
|
||||
|
@ -400,12 +399,12 @@ export class RawDebugSession implements IDisposable {
|
|||
return Promise.reject(new Error('exceptionInfo not supported'));
|
||||
}
|
||||
|
||||
scopes(args: DebugProtocol.ScopesArguments): Promise<DebugProtocol.ScopesResponse> {
|
||||
return this.send<DebugProtocol.ScopesResponse>('scopes', args);
|
||||
scopes(args: DebugProtocol.ScopesArguments, token: CancellationToken): Promise<DebugProtocol.ScopesResponse> {
|
||||
return this.send<DebugProtocol.ScopesResponse>('scopes', args, token);
|
||||
}
|
||||
|
||||
variables(args: DebugProtocol.VariablesArguments): Promise<DebugProtocol.VariablesResponse> {
|
||||
return this.send<DebugProtocol.VariablesResponse>('variables', args);
|
||||
variables(args: DebugProtocol.VariablesArguments, token?: CancellationToken): Promise<DebugProtocol.VariablesResponse> {
|
||||
return this.send<DebugProtocol.VariablesResponse>('variables', args, token);
|
||||
}
|
||||
|
||||
source(args: DebugProtocol.SourceArguments): Promise<DebugProtocol.SourceResponse> {
|
||||
|
@ -482,7 +481,7 @@ export class RawDebugSession implements IDisposable {
|
|||
if (!this.inShutdown) {
|
||||
this.inShutdown = true;
|
||||
if (this.debugAdapter) {
|
||||
return this.send('disconnect', { restart }, 500).then(() => {
|
||||
return this.send('disconnect', { restart }, undefined, 500).then(() => {
|
||||
this.stopAdapter(error);
|
||||
}, () => {
|
||||
// ignore error
|
||||
|
@ -494,23 +493,10 @@ export class RawDebugSession implements IDisposable {
|
|||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
private cancelPendingRequests(): void {
|
||||
if (this.debugAdapter) {
|
||||
if (this.capabilities.supportsCancelRequest) {
|
||||
this.debugAdapter.getPendingRequestIds().forEach(requestId => {
|
||||
this.cancel({ requestId });
|
||||
});
|
||||
} else {
|
||||
this.debugAdapter.cancelPendingRequests();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private stopAdapter(error?: Error): Promise<any> {
|
||||
if (this.debugAdapter) {
|
||||
const da = this.debugAdapter;
|
||||
this.debugAdapter = null;
|
||||
this.cancelPendingRequests();
|
||||
return da.stopSession().then(_ => {
|
||||
this.debugAdapterStopped = true;
|
||||
this.fireAdapterExitEvent(error);
|
||||
|
@ -642,20 +628,34 @@ export class RawDebugSession implements IDisposable {
|
|||
return this.windowsService.openExtensionDevelopmentHostWindow(args, env);
|
||||
}
|
||||
|
||||
private send<R extends DebugProtocol.Response>(command: string, args: any, timeout?: number): Promise<R> {
|
||||
private send<R extends DebugProtocol.Response>(command: string, args: any, token?: CancellationToken, timeout?: number): Promise<R> {
|
||||
return new Promise<R>((completeDispatch, errorDispatch) => {
|
||||
if (!this.debugAdapter) {
|
||||
errorDispatch(new Error('no debug adapter found'));
|
||||
return;
|
||||
}
|
||||
this.debugAdapter.sendRequest(command, args, (response: R) => {
|
||||
let cancelationListener: IDisposable;
|
||||
const requestId = this.debugAdapter.sendRequest(command, args, (response: R) => {
|
||||
if (cancelationListener) {
|
||||
cancelationListener.dispose();
|
||||
}
|
||||
|
||||
if (response.success) {
|
||||
completeDispatch(response);
|
||||
} else {
|
||||
errorDispatch(response);
|
||||
}
|
||||
}, timeout);
|
||||
}).then(response => response, err => Promise.reject(this.handleErrorResponse(err)));
|
||||
|
||||
if (token) {
|
||||
cancelationListener = token.onCancellationRequested(() => {
|
||||
cancelationListener.dispose();
|
||||
if (this.capabilities.supportsCancelRequest) {
|
||||
this.cancel({ requestId });
|
||||
}
|
||||
});
|
||||
}
|
||||
}).then(undefined, err => Promise.reject(this.handleErrorResponse(err)));
|
||||
}
|
||||
|
||||
private handleErrorResponse(errorResponse: DebugProtocol.Response): Error {
|
||||
|
|
|
@ -149,7 +149,7 @@ export class Repl extends Panel implements IPrivateReplService, IHistoryNavigati
|
|||
const text = model.getLineContent(position.lineNumber);
|
||||
const focusedStackFrame = this.debugService.getViewModel().focusedStackFrame;
|
||||
const frameId = focusedStackFrame ? focusedStackFrame.frameId : undefined;
|
||||
const suggestions = await session.completions(frameId, text, position, overwriteBefore);
|
||||
const suggestions = await session.completions(frameId, text, position, overwriteBefore, token);
|
||||
return { suggestions };
|
||||
}
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ export abstract class AbstractDebugAdapter implements IDebugAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
sendRequest(command: string, args: any, clb: (result: DebugProtocol.Response) => void, timeout?: number): void {
|
||||
sendRequest(command: string, args: any, clb: (result: DebugProtocol.Response) => void, timeout?: number): number {
|
||||
const request: any = {
|
||||
command: command
|
||||
};
|
||||
|
@ -101,6 +101,8 @@ export abstract class AbstractDebugAdapter implements IDebugAdapter {
|
|||
// store callback for this request
|
||||
this.pendingRequests.set(request.seq, clb);
|
||||
}
|
||||
|
||||
return request.seq;
|
||||
}
|
||||
|
||||
acceptMessage(message: DebugProtocol.ProtocolMessage): void {
|
||||
|
@ -137,7 +139,11 @@ export abstract class AbstractDebugAdapter implements IDebugAdapter {
|
|||
this.sendMessage(message);
|
||||
}
|
||||
|
||||
async cancelPendingRequests(): Promise<void> {
|
||||
protected async cancelPendingRequests(): Promise<void> {
|
||||
if (this.pendingRequests.size === 0) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const pending = new Map<number, (e: DebugProtocol.Response) => void>();
|
||||
this.pendingRequests.forEach((value, key) => pending.set(key, value));
|
||||
await timeout(500);
|
||||
|
|
|
@ -210,8 +210,8 @@ export interface IDebugSession extends ITreeElement {
|
|||
|
||||
stackTrace(threadId: number, startFrame: number, levels: number): Promise<DebugProtocol.StackTraceResponse>;
|
||||
exceptionInfo(threadId: number): Promise<IExceptionInfo | undefined>;
|
||||
scopes(frameId: number): Promise<DebugProtocol.ScopesResponse>;
|
||||
variables(variablesReference: number, filter: 'indexed' | 'named' | undefined, start: number | undefined, count: number | undefined): Promise<DebugProtocol.VariablesResponse>;
|
||||
scopes(frameId: number, threadId: number): Promise<DebugProtocol.ScopesResponse>;
|
||||
variables(variablesReference: number, threadId: number | undefined, filter: 'indexed' | 'named' | undefined, start: number | undefined, count: number | undefined): Promise<DebugProtocol.VariablesResponse>;
|
||||
evaluate(expression: string, frameId?: number, context?: string): Promise<DebugProtocol.EvaluateResponse>;
|
||||
customRequest(request: string, args: any): Promise<DebugProtocol.Response>;
|
||||
|
||||
|
@ -225,7 +225,7 @@ export interface IDebugSession extends ITreeElement {
|
|||
pause(threadId: number): Promise<void>;
|
||||
terminateThreads(threadIds: number[]): Promise<void>;
|
||||
|
||||
completions(frameId: number | undefined, text: string, position: Position, overwriteBefore: number): Promise<CompletionItem[]>;
|
||||
completions(frameId: number | undefined, text: string, position: Position, overwriteBefore: number, token: CancellationToken): Promise<CompletionItem[]>;
|
||||
setVariable(variablesReference: number | undefined, name: string, value: string): Promise<DebugProtocol.SetVariableResponse>;
|
||||
loadSource(resource: uri): Promise<DebugProtocol.SourceResponse>;
|
||||
getLoadedSources(): Promise<Source[]>;
|
||||
|
@ -504,10 +504,8 @@ export interface IDebugAdapter extends IDisposable {
|
|||
startSession(): Promise<void>;
|
||||
sendMessage(message: DebugProtocol.ProtocolMessage): void;
|
||||
sendResponse(response: DebugProtocol.Response): void;
|
||||
sendRequest(command: string, args: any, clb: (result: DebugProtocol.Response) => void, timeout?: number): void;
|
||||
sendRequest(command: string, args: any, clb: (result: DebugProtocol.Response) => void, timeout?: number): number;
|
||||
stopSession(): Promise<void>;
|
||||
cancelPendingRequests(): void;
|
||||
getPendingRequestIds(): number[];
|
||||
}
|
||||
|
||||
export interface IDebugAdapterFactory extends ITerminalLauncher {
|
||||
|
|
|
@ -37,6 +37,7 @@ export class ExpressionContainer implements IExpressionContainer {
|
|||
|
||||
constructor(
|
||||
protected session: IDebugSession | undefined,
|
||||
protected threadId: number | undefined,
|
||||
private _reference: number | undefined,
|
||||
private id: string,
|
||||
public namedVariables: number | undefined = 0,
|
||||
|
@ -85,7 +86,7 @@ export class ExpressionContainer implements IExpressionContainer {
|
|||
for (let i = 0; i < numberOfChunks; i++) {
|
||||
const start = (this.startOfVariables || 0) + i * chunkSize;
|
||||
const count = Math.min(chunkSize, this.indexedVariables - i * chunkSize);
|
||||
children.push(new Variable(this.session, this, this.reference, `[${start}..${start + count - 1}]`, '', '', undefined, count, { kind: 'virtual' }, undefined, true, start));
|
||||
children.push(new Variable(this.session, this.threadId, this, this.reference, `[${start}..${start + count - 1}]`, '', '', undefined, count, { kind: 'virtual' }, undefined, true, start));
|
||||
}
|
||||
|
||||
return children;
|
||||
|
@ -109,12 +110,12 @@ export class ExpressionContainer implements IExpressionContainer {
|
|||
}
|
||||
|
||||
private fetchVariables(start: number | undefined, count: number | undefined, filter: 'indexed' | 'named' | undefined): Promise<Variable[]> {
|
||||
return this.session!.variables(this.reference || 0, filter, start, count).then(response => {
|
||||
return this.session!.variables(this.reference || 0, this.threadId, filter, start, count).then(response => {
|
||||
return response && response.body && response.body.variables
|
||||
? distinct(response.body.variables.filter(v => !!v && isString(v.name)), (v: DebugProtocol.Variable) => v.name).map((v: DebugProtocol.Variable) =>
|
||||
new Variable(this.session, this, v.variablesReference, v.name, v.evaluateName, v.value, v.namedVariables, v.indexedVariables, v.presentationHint, v.type))
|
||||
new Variable(this.session, this.threadId, this, v.variablesReference, v.name, v.evaluateName, v.value, v.namedVariables, v.indexedVariables, v.presentationHint, v.type))
|
||||
: [];
|
||||
}, (e: Error) => [new Variable(this.session, this, 0, e.message, e.message, '', 0, 0, { kind: 'virtual' }, undefined, false)]);
|
||||
}, (e: Error) => [new Variable(this.session, this.threadId, this, 0, e.message, e.message, '', 0, 0, { kind: 'virtual' }, undefined, false)]);
|
||||
}
|
||||
|
||||
// The adapter explicitly sents the children count of an expression only if there are lots of children which should be chunked.
|
||||
|
@ -171,7 +172,7 @@ export class Expression extends ExpressionContainer implements IExpression {
|
|||
public available: boolean;
|
||||
|
||||
constructor(public name: string, id = generateUuid()) {
|
||||
super(undefined, 0, id);
|
||||
super(undefined, undefined, 0, id);
|
||||
this.available = false;
|
||||
// name is not set if the expression is just being added
|
||||
// in that case do not set default value to prevent flashing #14499
|
||||
|
@ -196,6 +197,7 @@ export class Variable extends ExpressionContainer implements IExpression {
|
|||
|
||||
constructor(
|
||||
session: IDebugSession | undefined,
|
||||
threadId: number | undefined,
|
||||
public parent: IExpressionContainer,
|
||||
reference: number | undefined,
|
||||
public name: string,
|
||||
|
@ -208,7 +210,7 @@ export class Variable extends ExpressionContainer implements IExpression {
|
|||
public available = true,
|
||||
startOfVariables = 0
|
||||
) {
|
||||
super(session, reference, `variable:${parent.getId()}:${name}`, namedVariables, indexedVariables, startOfVariables);
|
||||
super(session, threadId, reference, `variable:${parent.getId()}:${name}`, namedVariables, indexedVariables, startOfVariables);
|
||||
this.value = value || '';
|
||||
}
|
||||
|
||||
|
@ -248,7 +250,7 @@ export class Scope extends ExpressionContainer implements IScope {
|
|||
indexedVariables?: number,
|
||||
public range?: IRange
|
||||
) {
|
||||
super(stackFrame.thread.session, reference, `scope:${name}:${index}`, namedVariables, indexedVariables);
|
||||
super(stackFrame.thread.session, stackFrame.thread.threadId, reference, `scope:${name}:${index}`, namedVariables, indexedVariables);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
|
@ -276,7 +278,7 @@ export class StackFrame implements IStackFrame {
|
|||
|
||||
getScopes(): Promise<IScope[]> {
|
||||
if (!this.scopes) {
|
||||
this.scopes = this.thread.session.scopes(this.frameId).then(response => {
|
||||
this.scopes = this.thread.session.scopes(this.frameId, this.thread.threadId).then(response => {
|
||||
return response && response.body && response.body.scopes ?
|
||||
response.body.scopes.map((rs, index) => new Scope(this, index, rs.name, rs.variablesReference, rs.expensive, rs.namedVariables, rs.indexedVariables,
|
||||
rs.line && rs.column && rs.endLine && rs.endColumn ? new Range(rs.line, rs.column, rs.endLine, rs.endColumn) : undefined)) : [];
|
||||
|
|
|
@ -97,7 +97,7 @@ export class ReplEvaluationInput implements IReplElement {
|
|||
|
||||
export class ReplEvaluationResult extends ExpressionContainer implements IReplElement {
|
||||
constructor() {
|
||||
super(undefined, 0, generateUuid());
|
||||
super(undefined, undefined, 0, generateUuid());
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
|
|
|
@ -127,8 +127,8 @@ export class SocketDebugAdapter extends StreamDebugAdapter {
|
|||
});
|
||||
}
|
||||
|
||||
stopSession(): Promise<void> {
|
||||
|
||||
async stopSession(): Promise<void> {
|
||||
await this.cancelPendingRequests();
|
||||
if (this.socket) {
|
||||
this.socket.end();
|
||||
this.socket = undefined;
|
||||
|
@ -249,7 +249,7 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
stopSession(): Promise<void> {
|
||||
async stopSession(): Promise<void> {
|
||||
|
||||
if (!this.serverProcess) {
|
||||
return Promise.resolve(undefined);
|
||||
|
@ -258,6 +258,7 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter {
|
|||
// when killing a process in windows its child
|
||||
// processes are *not* killed but become root
|
||||
// processes. Therefore we use TASKKILL.EXE
|
||||
await this.cancelPendingRequests();
|
||||
if (platform.isWindows) {
|
||||
return new Promise<void>((c, e) => {
|
||||
const killer = cp.exec(`taskkill /F /T /PID ${this.serverProcess!.pid}`, function (err, stdout, stderr) {
|
||||
|
|
|
@ -76,7 +76,7 @@ suite('Debug - Base Debug View', () => {
|
|||
const stackFrame = new StackFrame(thread, 1, null!, 'app.js', 'normal', { startLineNumber: 1, startColumn: 1, endLineNumber: undefined!, endColumn: undefined! }, 0);
|
||||
const scope = new Scope(stackFrame, 1, 'local', 1, false, 10, 10);
|
||||
|
||||
let variable = new Variable(session, scope, 2, 'foo', 'bar.foo', undefined!, 0, 0, {}, 'string');
|
||||
let variable = new Variable(session, 1, scope, 2, 'foo', 'bar.foo', undefined!, 0, 0, {}, 'string');
|
||||
let expression = $('.');
|
||||
let name = $('.');
|
||||
let value = $('.');
|
||||
|
@ -104,7 +104,7 @@ suite('Debug - Base Debug View', () => {
|
|||
assert.ok(value.querySelector('a'));
|
||||
assert.equal(value.querySelector('a')!.textContent, variable.value);
|
||||
|
||||
variable = new Variable(session, scope, 2, 'console', 'console', '5', 0, 0, { kind: 'virtual' });
|
||||
variable = new Variable(session, 1, scope, 2, 'console', 'console', '5', 0, 0, { kind: 'virtual' });
|
||||
expression = $('.');
|
||||
name = $('.');
|
||||
value = $('.');
|
||||
|
|
|
@ -264,7 +264,7 @@ export class MockSession implements IDebugSession {
|
|||
scopes(frameId: number): Promise<DebugProtocol.ScopesResponse> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
variables(variablesReference: number, filter: 'indexed' | 'named', start: number, count: number): Promise<DebugProtocol.VariablesResponse> {
|
||||
variables(variablesReference: number, threadId: number | undefined, filter: 'indexed' | 'named', start: number, count: number): Promise<DebugProtocol.VariablesResponse> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
evaluate(expression: string, frameId: number, context?: string): Promise<DebugProtocol.EvaluateResponse> {
|
||||
|
|
Loading…
Reference in a new issue