debug.ts 12.5 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import uri from 'vs/base/common/uri';
I
isidor 已提交
7
import {TPromise} from 'vs/base/common/winjs.base';
8
import Event from 'vs/base/common/event';
E
Erich Gamma 已提交
9
import severity from 'vs/base/common/severity';
I
isidor 已提交
10
import {createDecorator} from 'vs/platform/instantiation/common/instantiation';
E
Erich Gamma 已提交
11
import editor = require('vs/editor/common/editorCommon');
I
isidor 已提交
12 13
import {Position} from 'vs/editor/common/core/position';
import {ISuggestion} from 'vs/editor/common/modes';
I
isidor 已提交
14 15
import {Source} from 'vs/workbench/parts/debug/common/debugSource';
import {Range} from 'vs/editor/common/core/range';
A
Alex Dima 已提交
16
import {RawContextKey, ContextKeyExpr} from 'vs/platform/contextkey/common/contextkey';
E
Erich Gamma 已提交
17

I
isidor 已提交
18 19 20
export const VIEWLET_ID = 'workbench.view.debug';
export const REPL_ID = 'workbench.panel.repl';
export const DEBUG_SERVICE_ID = 'debugService';
A
Alex Dima 已提交
21
export const CONTEXT_IN_DEBUG_MODE = new RawContextKey<boolean>('inDebugMode', false);
22 23 24
export const CONTEXT_NOT_IN_DEBUG_MODE: ContextKeyExpr = CONTEXT_IN_DEBUG_MODE.toNegated();
export const CONTEXT_IN_DEBUG_REPL = new RawContextKey<boolean>('inDebugRepl', false);
export const CONTEXT_NOT_IN_DEBUG_REPL: ContextKeyExpr = CONTEXT_IN_DEBUG_REPL.toNegated();
25 26
export const CONTEXT_ON_FIRST_DEBUG_REPL_LINE = new RawContextKey<boolean>('onFirsteDebugReplLine', false);
export const CONTEXT_ON_LAST_DEBUG_REPL_LINE = new RawContextKey<boolean>('onLastDebugReplLine', false);
I
isidor 已提交
27
export const EDITOR_CONTRIBUTION_ID = 'editor.contrib.debug';
I
isidor 已提交
28
export const DEBUG_SCHEME = 'debug';
E
Erich Gamma 已提交
29

I
isidor 已提交
30
// raw
E
Erich Gamma 已提交
31 32 33 34 35

export interface IRawModelUpdate {
	threadId: number;
	thread?: DebugProtocol.Thread;
	callStack?: DebugProtocol.StackFrame[];
I
isidor 已提交
36
	stoppedDetails?: IRawStoppedDetails;
37
	allThreadsStopped?: boolean;
I
isidor 已提交
38 39 40 41 42 43
}

export interface IRawStoppedDetails {
	reason: string;
	threadId?: number;
	text?: string;
I
isidor 已提交
44
	totalFrames?: number;
45
	framesErrorMessage?: string;
E
Erich Gamma 已提交
46 47
}

I
isidor 已提交
48
// model
E
Erich Gamma 已提交
49 50 51 52 53 54 55 56 57 58 59 60 61

export interface ITreeElement {
	getId(): string;
}

export interface IExpressionContainer extends ITreeElement {
	reference: number;
	getChildren(debugService: IDebugService): TPromise<IExpression[]>;
}

export interface IExpression extends ITreeElement, IExpressionContainer {
	name: string;
	value: string;
62
	valueChanged: boolean;
63
	type?: string;
E
Erich Gamma 已提交
64 65 66
}

export interface IThread extends ITreeElement {
I
isidor 已提交
67 68 69
	/**
	 * Id of the thread generated by the debug adapter backend.
	 */
E
Erich Gamma 已提交
70
	threadId: number;
I
isidor 已提交
71 72 73 74

	/**
	 * Name of the thread.
	 */
E
Erich Gamma 已提交
75
	name: string;
I
isidor 已提交
76 77 78 79

	/**
	 * Information about the current thread stop event. Null if thread is not stopped.
	 */
I
isidor 已提交
80
	stoppedDetails: IRawStoppedDetails;
81 82 83 84 85

	/**
	 * Queries the debug adapter for the callstack and returns a promise with
	 * the stack frames of the callstack.
	 * If the thread is not stopped, it returns a promise to an empty array.
I
isidor 已提交
86 87
	 * Only gets the first 20 stack frames. Calling this method consecutive times
	 * with getAdditionalStackFrames = true gets the remainder of the call stack.
88
	 */
I
isidor 已提交
89
	getCallStack(debugService: IDebugService, getAdditionalStackFrames?: boolean): TPromise<IStackFrame[]>;
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106

	/**
	 * Gets the callstack if it has already been received from the debug
	 * adapter, otherwise it returns undefined.
	 */
	getCachedCallStack(): IStackFrame[];

	/**
	 * Invalidates the callstack cache
	 */
	clearCallStack(): void;

	/**
	 * Indicates whether this thread is stopped. The callstack for stopped
	 * threads can be retrieved from the debug adapter.
	 */
	stopped: boolean;
E
Erich Gamma 已提交
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
}

export interface IScope extends IExpressionContainer {
	name: string;
	expensive: boolean;
}

export interface IStackFrame extends ITreeElement {
	threadId: number;
	name: string;
	lineNumber: number;
	column: number;
	frameId: number;
	source: Source;
	getScopes(debugService: IDebugService): TPromise<IScope[]>;
}

export interface IEnablement extends ITreeElement {
	enabled: boolean;
}

128 129 130
export interface IRawBreakpoint {
	uri: uri;
	lineNumber: number;
131
	enabled?: boolean;
132
	condition?: string;
133
	hitCondition?: string;
134 135
}

E
Erich Gamma 已提交
136 137 138 139
export interface IBreakpoint extends IEnablement {
	source: Source;
	lineNumber: number;
	desiredLineNumber: number;
I
isidor 已提交
140
	condition: string;
141
	hitCondition: string;
142
	verified: boolean;
143
	idFromAdapter: number;
I
isidor 已提交
144
	message: string;
E
Erich Gamma 已提交
145 146
}

I
isidor 已提交
147
export interface IFunctionBreakpoint extends IEnablement {
148
	name: string;
I
isidor 已提交
149
	verified: boolean;
150
	idFromAdapter: number;
151
	hitCondition: string;
I
isidor 已提交
152 153
}

E
Erich Gamma 已提交
154
export interface IExceptionBreakpoint extends IEnablement {
155 156
	filter: string;
	label: string;
E
Erich Gamma 已提交
157 158
}

I
isidor 已提交
159
// model interfaces
E
Erich Gamma 已提交
160

161
export interface IViewModel extends ITreeElement {
E
Erich Gamma 已提交
162 163 164 165
	getFocusedStackFrame(): IStackFrame;
	getSelectedExpression(): IExpression;
	getFocusedThreadId(): number;
	setSelectedExpression(expression: IExpression);
I
isidor 已提交
166 167
	getSelectedFunctionBreakpoint(): IFunctionBreakpoint;
	setSelectedFunctionBreakpoint(functionBreakpoint: IFunctionBreakpoint): void;
168 169 170 171

	onDidFocusStackFrame: Event<IStackFrame>;
	onDidSelectExpression: Event<IExpression>;
	onDidSelectFunctionBreakpoint: Event<IFunctionBreakpoint>;
E
Erich Gamma 已提交
172 173
}

174
export interface IModel extends ITreeElement {
175
	getThreads(): { [threadId: number]: IThread; };
E
Erich Gamma 已提交
176 177
	getBreakpoints(): IBreakpoint[];
	areBreakpointsActivated(): boolean;
I
isidor 已提交
178
	getFunctionBreakpoints(): IFunctionBreakpoint[];
E
Erich Gamma 已提交
179 180 181
	getExceptionBreakpoints(): IExceptionBreakpoint[];
	getWatchExpressions(): IExpression[];
	getReplElements(): ITreeElement[];
182 183 184 185

	onDidChangeBreakpoints: Event<void>;
	onDidChangeCallStack: Event<void>;
	onDidChangeWatchExpressions: Event<IExpression>;
186
	onDidChangeReplElements: Event<void>;
187
};
E
Erich Gamma 已提交
188

I
isidor 已提交
189
// service enums
E
Erich Gamma 已提交
190 191 192 193 194 195

export enum State {
	Disabled,
	Inactive,
	Initializing,
	Stopped,
I
isidor 已提交
196 197
	Running,
	RunningNoDebug
E
Erich Gamma 已提交
198 199
}

I
isidor 已提交
200
// service interfaces
E
Erich Gamma 已提交
201 202 203

export interface IGlobalConfig {
	version: string;
204
	debugServer?: number;
E
Erich Gamma 已提交
205 206 207
	configurations: IConfig[];
}

208
export interface IEnvConfig {
209
	name?: string;
E
Erich Gamma 已提交
210 211
	type: string;
	request: string;
212
	internalConsoleOptions?: string;
213 214
	preLaunchTask?: string;
	debugServer?: number;
I
isidor 已提交
215
	noDebug?: boolean;
216
	silentlyAbort?: boolean;
E
Erich Gamma 已提交
217 218
}

I
isidor 已提交
219 220 221 222 223 224
export interface IExtHostConfig extends IEnvConfig {
	port?: number;
	sourceMaps?: boolean;
	outDir?: string;
}

225 226 227 228 229 230
export interface IConfig extends IEnvConfig {
	windows?: IEnvConfig;
	osx?: IEnvConfig;
	linux?: IEnvConfig;
}

E
Erich Gamma 已提交
231
export interface IRawEnvAdapter {
I
isidor 已提交
232 233 234 235 236 237
	type?: string;
	label?: string;
	program?: string;
	args?: string[];
	runtime?: string;
	runtimeArgs?: string[];
E
Erich Gamma 已提交
238 239 240
}

export interface IRawAdapter extends IRawEnvAdapter {
I
isidor 已提交
241 242
	enableBreakpointsFor?: { languageIds: string[] };
	configurationAttributes?: any;
243
	initialConfigurations?: any[] | string;
244
	variables: { [key: string]: string };
I
isidor 已提交
245
	aiKey?: string;
I
isidor 已提交
246
	win?: IRawEnvAdapter;
I
isidor 已提交
247
	winx86?: IRawEnvAdapter;
248
	windows?: IRawEnvAdapter;
I
isidor 已提交
249 250
	osx?: IRawEnvAdapter;
	linux?: IRawEnvAdapter;
E
Erich Gamma 已提交
251 252
}

253 254 255 256
export interface IRawBreakpointContribution {
	language: string;
}

257
export interface IRawDebugSession {
A
Andre Weinand 已提交
258
	configuration: { type: string, capabilities: DebugProtocol.Capabilities };
I
isidor 已提交
259

260
	disconnect(restart?: boolean, force?: boolean): TPromise<DebugProtocol.DisconnectResponse>;
E
Erich Gamma 已提交
261

262
	stackTrace(args: DebugProtocol.StackTraceArguments): TPromise<DebugProtocol.StackTraceResponse>;
E
Erich Gamma 已提交
263
	scopes(args: DebugProtocol.ScopesArguments): TPromise<DebugProtocol.ScopesResponse>;
264
	variables(args: DebugProtocol.VariablesArguments): TPromise<DebugProtocol.VariablesResponse>;
E
Erich Gamma 已提交
265
	evaluate(args: DebugProtocol.EvaluateArguments): TPromise<DebugProtocol.EvaluateResponse>;
266

267 268 269
	custom(request: string, args: any): TPromise<DebugProtocol.Response>;

	onDidEvent: Event<DebugProtocol.Event>;
E
Erich Gamma 已提交
270 271
}

272
export interface IConfigurationManager {
273
	configuration: IConfig;
274 275 276 277 278 279 280 281
	setConfiguration(name: string): TPromise<void>;
	openConfigFile(sideBySide: boolean): TPromise<boolean>;
	loadLaunchConfig(): TPromise<IGlobalConfig>;
	canSetBreakpointsIn(model: editor.IModel): boolean;

	/**
	 * Allows to register on change of debug configuration.
	 */
282
	onDidConfigurationChange: Event<IConfig>;
283 284
}

B
Benjamin Pasero 已提交
285
export const IDebugService = createDecorator<IDebugService>(DEBUG_SERVICE_ID);
E
Erich Gamma 已提交
286

287
export interface IDebugService {
288
	_serviceBrand: any;
289 290 291 292

	/**
	 * Gets the current debug state.
	 */
I
isidor 已提交
293
	state: State;
E
Erich Gamma 已提交
294

295 296 297 298 299
	/**
	 * Allows to register on debug state changes.
	 */
	onDidChangeState: Event<State>;

300 301 302 303
	/**
	 * Gets the current configuration manager.
	 */
	getConfigurationManager(): IConfigurationManager;
E
Erich Gamma 已提交
304

I
isidor 已提交
305 306 307 308
	/**
	 * Sets the focused stack frame and evaluates all expresions against the newly focused stack frame,
	 */
	setFocusedStackFrameAndEvaluate(focusedStackFrame: IStackFrame): TPromise<void>;
E
Erich Gamma 已提交
309

310
	/**
311
	 * Adds new breakpoints to the model. Notifies debug adapter of breakpoint changes.
312
	 */
313
	addBreakpoints(rawBreakpoints: IRawBreakpoint[]): TPromise<void[]>;
314 315 316 317 318 319 320 321 322 323 324

	/**
	 * Enables or disables all breakpoints. If breakpoint is passed only enables or disables the passed breakpoint.
	 * Notifies debug adapter of breakpoint changes.
	 */
	enableOrDisableBreakpoints(enable: boolean, breakpoint?: IEnablement): TPromise<void>;

	/**
	 * Sets the global activated property for all breakpoints.
	 * Notifies debug adapter of breakpoint changes.
	 */
325
	setBreakpointsActivated(activated: boolean): TPromise<void>;
326 327 328 329 330

	/**
	 * Removes all breakpoints. If id is passed only removes the breakpoint associated with that id.
	 * Notifies debug adapter of breakpoint changes.
	 */
331
	removeBreakpoints(id?: string): TPromise<any>;
I
isidor 已提交
332

333
	/**
334
	 * Adds a new no name function breakpoint. The function breakpoint should be renamed once user enters the name.
335
	 */
I
isidor 已提交
336
	addFunctionBreakpoint(): void;
337 338 339 340 341

	/**
	 * Renames an already existing function breakpoint.
	 * Notifies debug adapter of breakpoint changes.
	 */
I
isidor 已提交
342
	renameFunctionBreakpoint(id: string, newFunctionName: string): TPromise<void>;
343 344 345 346 347

	/**
	 * Removes all function breakpoints. If id is passed only removes the function breakpoint with the passed id.
	 * Notifies debug adapter of breakpoint changes.
	 */
I
isidor 已提交
348
	removeFunctionBreakpoints(id?: string): TPromise<void>;
E
Erich Gamma 已提交
349

350
	/**
351
	 * Adds a new expression to the repl.
352
	 */
I
isidor 已提交
353
	addReplExpression(name: string): TPromise<void>;
354 355 356 357

	/**
	 * Removes all repl expressions.
	 */
358
	removeReplExpressions(): void;
359 360 361 362

	/**
	 * Adds a new log to the repl. Either a string value or a dictionary (used to inspect complex objects printed to the repl).
	 */
363
	logToRepl(value: string | { [key: string]: any }, severity?: severity): void;
364 365 366 367

	/**
	 * Appends new output to the repl.
	 */
E
Erich Gamma 已提交
368 369
	appendReplOutput(value: string, severity?: severity): void;

I
isidor 已提交
370 371 372 373 374
	/**
	 * Sets the value for the variable against the debug adapter.
	 */
	setVariable(variable: IExpression, value: string): TPromise<void>;

375
	/**
376
	 * Adds a new watch expression and evaluates it against the debug adapter.
377
	 */
I
isidor 已提交
378
	addWatchExpression(name?: string): TPromise<void>;
379 380 381 382

	/**
	 * Renames a watch expression and evaluates it against the debug adapter.
	 */
I
isidor 已提交
383
	renameWatchExpression(id: string, newName: string): TPromise<void>;
384 385 386 387

	/**
	 * Removes all watch expressions. If id is passed only removes the watch expression with the passed id.
	 */
388
	removeWatchExpressions(id?: string): void;
E
Erich Gamma 已提交
389

I
isidor 已提交
390 391 392
	/**
	 * Creates a new debug session. Depending on the configuration will either 'launch' or 'attach'.
	 */
393
	createSession(noDebug: boolean, configuration?: IConfig): TPromise<any>;
I
isidor 已提交
394 395 396 397

	/**
	 * Restarts an active debug session or creates a new one if there is no active session.
	 */
I
isidor 已提交
398
	restartSession(): TPromise<any>;
I
isidor 已提交
399 400 401 402

	/**
	 * Returns the active debug session or null if debug is inactive.
	 */
E
Erich Gamma 已提交
403 404
	getActiveSession(): IRawDebugSession;

I
isidor 已提交
405 406 407
	/**
	 * Gets the current debug model.
	 */
E
Erich Gamma 已提交
408
	getModel(): IModel;
I
isidor 已提交
409 410 411 412

	/**
	 * Gets the current view model.
	 */
E
Erich Gamma 已提交
413 414
	getViewModel(): IViewModel;

I
isidor 已提交
415 416 417
	/**
	 * Opens a new or reveals an already visible editor showing the source.
	 */
418
	openOrRevealSource(source: Source, lineNumber: number, preserveFocus: boolean, sideBySide: boolean): TPromise<any>;
419 420 421 422

	next(threadId: number): TPromise<void>;
	stepIn(threadId: number): TPromise<void>;
	stepOut(threadId: number): TPromise<void>;
423
	stepBack(threadId: number): TPromise<void>;
424 425
	continue(threadId: number): TPromise<void>;
	pause(threadId: number): TPromise<any>;
A
Andre Weinand 已提交
426
	restartFrame(frameId: number): TPromise<any>;
I
isidor 已提交
427
	completions(text: string, position: Position): TPromise<ISuggestion[]>;
E
Erich Gamma 已提交
428 429
}

I
isidor 已提交
430 431
// Editor interfaces
export interface IDebugEditorContribution extends editor.IEditorContribution {
432
	showHover(range: Range, hoveringOver: string, focus: boolean): TPromise<void>;
I
isidor 已提交
433 434
}

I
isidor 已提交
435
// utils
E
Erich Gamma 已提交
436

I
isidor 已提交
437
const _formatPIIRegexp = /{([^}]+)}/g;
E
Erich Gamma 已提交
438

I
isidor 已提交
439 440
export function formatPII(value: string, excludePII: boolean, args: { [key: string]: string }): string {
	return value.replace(_formatPIIRegexp, function (match, group) {
E
Erich Gamma 已提交
441 442 443 444
		if (excludePII && group.length > 0 && group[0] !== '_') {
			return match;
		}

I
isidor 已提交
445
		return args && args.hasOwnProperty(group) ?
E
Erich Gamma 已提交
446 447
			args[group] :
			match;
I
isidor 已提交
448
	});
E
Erich Gamma 已提交
449
}