Skip to content

Commit 630eb0e

Browse files
committed
strict null checks: debugSession
1 parent 7ac3bf1 commit 630eb0e

5 files changed

Lines changed: 54 additions & 43 deletions

File tree

src/tsconfig.strictNullChecks.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@
175175
"./vs/workbench/contrib/debug/electron-browser/breakpointWidget.ts",
176176
"./vs/workbench/contrib/debug/electron-browser/debugEditorContribution.ts",
177177
"./vs/workbench/contrib/debug/electron-browser/debugHover.ts",
178+
"./vs/workbench/contrib/debug/electron-browser/debugSession.ts",
178179
"./vs/workbench/contrib/debug/electron-browser/electronDebugActions.ts",
179180
"./vs/workbench/contrib/debug/electron-browser/rawDebugSession.ts",
180181
"./vs/workbench/contrib/debug/electron-browser/repl.ts",

src/vs/workbench/contrib/debug/common/debug.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export interface IRawModelUpdate {
7171
}
7272

7373
export interface IRawStoppedDetails {
74-
reason: string;
74+
reason?: string;
7575
description?: string;
7676
threadId?: number;
7777
text?: string;
@@ -151,13 +151,13 @@ export interface IDebugSession extends ITreeElement {
151151

152152
getLabel(): string;
153153

154-
getSourceForUri(modelUri: uri): Source;
154+
getSourceForUri(modelUri: uri): Source | undefined;
155155
getSource(raw?: DebugProtocol.Source): Source;
156156

157157
setConfiguration(configuration: { resolved: IConfig, unresolved: IConfig }): void;
158158
rawUpdate(data: IRawModelUpdate): void;
159159

160-
getThread(threadId: number): IThread;
160+
getThread(threadId: number): IThread | undefined;
161161
getAllThreads(): IThread[];
162162
clearThreads(removeThreads: boolean, reference?: number): void;
163163

@@ -197,9 +197,9 @@ export interface IDebugSession extends ITreeElement {
197197
sendExceptionBreakpoints(exbpts: IExceptionBreakpoint[]): Promise<void>;
198198

199199
stackTrace(threadId: number, startFrame: number, levels: number): Promise<DebugProtocol.StackTraceResponse>;
200-
exceptionInfo(threadId: number): Promise<IExceptionInfo>;
200+
exceptionInfo(threadId: number): Promise<IExceptionInfo | undefined>;
201201
scopes(frameId: number): Promise<DebugProtocol.ScopesResponse>;
202-
variables(variablesReference: number | undefined, filter: 'indexed' | 'named' | undefined, start: number | undefined, count: number | undefined): Promise<DebugProtocol.VariablesResponse>;
202+
variables(variablesReference: number, filter: 'indexed' | 'named' | undefined, start: number | undefined, count: number | undefined): Promise<DebugProtocol.VariablesResponse>;
203203
evaluate(expression: string, frameId?: number, context?: string): Promise<DebugProtocol.EvaluateResponse>;
204204
customRequest(request: string, args: any): Promise<DebugProtocol.Response>;
205205

@@ -237,14 +237,14 @@ export interface IThread extends ITreeElement {
237237
readonly name: string;
238238

239239
/**
240-
* Information about the current thread stop event. Null if thread is not stopped.
240+
* Information about the current thread stop event. Undefined if thread is not stopped.
241241
*/
242-
readonly stoppedDetails: IRawStoppedDetails;
242+
readonly stoppedDetails: IRawStoppedDetails | undefined;
243243

244244
/**
245-
* Information about the exception if an 'exception' stopped event raised and DA supports the 'exceptionInfo' request, otherwise null.
245+
* Information about the exception if an 'exception' stopped event raised and DA supports the 'exceptionInfo' request, otherwise undefined.
246246
*/
247-
readonly exceptionInfo: Promise<IExceptionInfo | null>;
247+
readonly exceptionInfo: Promise<IExceptionInfo | undefined>;
248248

249249
readonly stateLabel: string;
250250

src/vs/workbench/contrib/debug/common/debugModel.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ export class ExpressionContainer implements IExpressionContainer {
172172
}
173173

174174
private fetchVariables(start: number | undefined, count: number | undefined, filter: 'indexed' | 'named' | undefined): Promise<Variable[]> {
175-
return this.session!.variables(this.reference, filter, start, count).then(response => {
175+
return this.session!.variables(this.reference || 0, filter, start, count).then(response => {
176176
return response && response.body && response.body.variables
177177
? distinct(response.body.variables.filter(v => !!v && isString(v.name)), (v: DebugProtocol.Variable) => v.name).map((v: DebugProtocol.Variable) =>
178178
new Variable(this.session, this, v.variablesReference, v.name, v.evaluateName, v.value, v.namedVariables, v.indexedVariables, v.presentationHint, v.type))
@@ -393,7 +393,7 @@ export class StackFrame implements IStackFrame {
393393
export class Thread implements IThread {
394394
private callStack: IStackFrame[];
395395
private staleCallStack: IStackFrame[];
396-
public stoppedDetails: IRawStoppedDetails;
396+
public stoppedDetails: IRawStoppedDetails | undefined;
397397
public stopped: boolean;
398398

399399
constructor(public session: IDebugSession, public name: string, public threadId: number) {
@@ -422,7 +422,7 @@ export class Thread implements IThread {
422422
}
423423

424424
get stateLabel(): string {
425-
if (this.stopped) {
425+
if (this.stoppedDetails) {
426426
return this.stoppedDetails.description ||
427427
this.stoppedDetails.reason ? nls.localize({ key: 'pausedOn', comment: ['indicates reason for program being paused'] }, "Paused on {0}", this.stoppedDetails.reason) : nls.localize('paused', "Paused");
428428
}
@@ -482,9 +482,9 @@ export class Thread implements IThread {
482482
}
483483

484484
/**
485-
* Returns exception info promise if the exception was thrown, otherwise null
485+
* Returns exception info promise if the exception was thrown, otherwise undefined
486486
*/
487-
get exceptionInfo(): Promise<IExceptionInfo | null> {
487+
get exceptionInfo(): Promise<IExceptionInfo | undefined> {
488488
if (this.stoppedDetails && this.stoppedDetails.reason === 'exception') {
489489
if (this.session.capabilities.supportsExceptionInfoRequest) {
490490
return this.session.exceptionInfo(this.threadId);
@@ -494,7 +494,7 @@ export class Thread implements IThread {
494494
breakMode: null
495495
});
496496
}
497-
return Promise.resolve(null);
497+
return Promise.resolve(undefined);
498498
}
499499

500500
next(): Promise<any> {

src/vs/workbench/contrib/debug/electron-browser/debugSession.ts

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
3636

3737
export class DebugSession implements IDebugSession {
3838
private id: string;
39-
private raw: RawDebugSession;
39+
private raw: RawDebugSession | undefined;
4040
private initialized = false;
4141

4242
private sources = new Map<string, Source>();
@@ -156,11 +156,11 @@ export class DebugSession implements IDebugSession {
156156

157157
this.raw = new RawDebugSession(debugAdapter, dbgr, this.telemetryService, customTelemetryService, this.environmentService);
158158

159-
return this.raw.start().then(() => {
159+
return this.raw!.start().then(() => {
160160

161161
this.registerListeners();
162162

163-
return this.raw.initialize({
163+
return this.raw!.initialize({
164164
clientID: 'vscode',
165165
clientName: product.nameLong,
166166
adapterID: this.configuration.type,
@@ -174,7 +174,7 @@ export class DebugSession implements IDebugSession {
174174
}).then(() => {
175175
this.initialized = true;
176176
this._onDidChangeState.fire();
177-
this.model.setExceptionBreakpoints(this.raw.capabilities.exceptionBreakpointFilters);
177+
this.model.setExceptionBreakpoints(this.raw!.capabilities.exceptionBreakpointFilters || []);
178178
});
179179
});
180180
});
@@ -259,7 +259,9 @@ export class DebugSession implements IDebugSession {
259259
rawSource.adapterData = breakpointsToSend[0].adapterData;
260260
}
261261
// Normalize all drive letters going out from vscode to debug adapters so we are consistent with our resolving #43959
262-
rawSource.path = normalizeDriveLetter(rawSource.path);
262+
if (rawSource.path) {
263+
rawSource.path = normalizeDriveLetter(rawSource.path);
264+
}
263265

264266
return this.raw.setBreakpoints({
265267
source: rawSource,
@@ -322,7 +324,7 @@ export class DebugSession implements IDebugSession {
322324
return Promise.reject(new Error('no debug adapter'));
323325
}
324326

325-
exceptionInfo(threadId: number): Promise<IExceptionInfo> {
327+
exceptionInfo(threadId: number): Promise<IExceptionInfo | undefined> {
326328
if (this.raw) {
327329
return this.raw.exceptionInfo({ threadId }).then(response => {
328330
if (response) {
@@ -333,7 +335,7 @@ export class DebugSession implements IDebugSession {
333335
details: response.body.details
334336
};
335337
}
336-
return null;
338+
return undefined;
337339
});
338340
}
339341
return Promise.reject(new Error('no debug adapter'));
@@ -346,11 +348,11 @@ export class DebugSession implements IDebugSession {
346348
return Promise.reject(new Error('no debug adapter'));
347349
}
348350

349-
variables(variablesReference: number, filter: 'indexed' | 'named', start: number, count: number): Promise<DebugProtocol.VariablesResponse | undefined> {
351+
variables(variablesReference: number, filter: 'indexed' | 'named' | undefined, start: number | undefined, count: number | undefined): Promise<DebugProtocol.VariablesResponse> {
350352
if (this.raw) {
351353
return this.raw.variables({ variablesReference, filter, start, count });
352354
}
353-
return Promise.resolve(undefined);
355+
return Promise.reject(new Error('no debug adapter'));
354356
}
355357

356358
evaluate(expression: string, frameId: number, context?: string): Promise<DebugProtocol.EvaluateResponse> {
@@ -455,7 +457,7 @@ export class DebugSession implements IDebugSession {
455457
};
456458
}
457459

458-
return this.raw.source({ sourceReference: rawSource.sourceReference, source: rawSource });
460+
return this.raw.source({ sourceReference: rawSource.sourceReference || 0, source: rawSource });
459461
}
460462

461463
getLoadedSources(): Promise<Source[]> {
@@ -489,8 +491,8 @@ export class DebugSession implements IDebugSession {
489491
result.push({
490492
label: item.label,
491493
insertText: item.text || item.label,
492-
kind: completionKindFromString(item.type),
493-
filterText: item.start && item.length && text.substr(item.start, item.length).concat(item.label),
494+
kind: completionKindFromString(item.type || 'property'),
495+
filterText: (item.start && item.length) ? text.substr(item.start, item.length).concat(item.label) : undefined,
494496
range: Range.fromPositions(position.delta(0, -(item.length || overwriteBefore)), position)
495497
});
496498
}
@@ -505,7 +507,7 @@ export class DebugSession implements IDebugSession {
505507

506508
//---- threads
507509

508-
getThread(threadId: number): Thread {
510+
getThread(threadId: number): Thread | undefined {
509511
return this.threads.get(threadId);
510512
}
511513

@@ -548,7 +550,10 @@ export class DebugSession implements IDebugSession {
548550
this.threads.set(data.threadId, new Thread(this, data.thread.name, data.thread.id));
549551
} else if (data.thread && data.thread.name) {
550552
// Just the thread name got updated #18244
551-
this.threads.get(data.threadId).name = data.thread.name;
553+
const thread = this.threads.get(data.threadId);
554+
if (thread) {
555+
thread.name = data.thread.name;
556+
}
552557
}
553558

554559
if (data.stoppedDetails) {
@@ -560,12 +565,14 @@ export class DebugSession implements IDebugSession {
560565
thread.stopped = true;
561566
thread.clearCallStack();
562567
});
563-
} else if (this.threads.has(data.threadId)) {
564-
// One thread is stopped, only update that thread.
568+
} else {
565569
const thread = this.threads.get(data.threadId);
566-
thread.stoppedDetails = data.stoppedDetails;
567-
thread.clearCallStack();
568-
thread.stopped = true;
570+
if (thread) {
571+
// One thread is stopped, only update that thread.
572+
thread.stoppedDetails = data.stoppedDetails;
573+
thread.clearCallStack();
574+
thread.stopped = true;
575+
}
569576
}
570577
}
571578
}
@@ -588,6 +595,10 @@ export class DebugSession implements IDebugSession {
588595
//---- private
589596

590597
private registerListeners(): void {
598+
if (!this.raw) {
599+
return;
600+
}
601+
591602
this.rawListeners.push(this.raw.onDidInitialize(() => {
592603
aria.status(nls.localize('debuggingStarted', "Debugging started."));
593604
const sendConfigurationDone = () => {
@@ -613,7 +624,7 @@ export class DebugSession implements IDebugSession {
613624

614625
this.rawListeners.push(this.raw.onDidStop(event => {
615626
this.fetchThreads(event.body).then(() => {
616-
const thread = this.getThread(event.body.threadId);
627+
const thread = typeof event.body.threadId === 'number' ? this.getThread(event.body.threadId) : undefined;
617628
if (thread) {
618629
// Call fetch call stack twice, the first only return the top stack frame.
619630
// Second retrieves the rest of the call stack. For performance reasons #25605
@@ -662,7 +673,7 @@ export class DebugSession implements IDebugSession {
662673
aria.status(nls.localize('debuggingStopped', "Debugging stopped."));
663674
if (event.body && event.body.restart) {
664675
this.debugService.restartSession(this, event.body.restart).then(undefined, onUnexpectedError);
665-
} else {
676+
} else if (this.raw) {
666677
this.raw.disconnect();
667678
}
668679
}));
@@ -675,7 +686,7 @@ export class DebugSession implements IDebugSession {
675686

676687
let outpuPromises: Promise<void>[] = [];
677688
this.rawListeners.push(this.raw.onDidOutput(event => {
678-
if (!event.body) {
689+
if (!event.body || !this.raw) {
679690
return;
680691
}
681692

@@ -693,7 +704,7 @@ export class DebugSession implements IDebugSession {
693704

694705
// Make sure to append output in the correct order by properly waiting on preivous promises #33822
695706
const waitFor = outpuPromises.slice();
696-
const source = event.body.source ? {
707+
const source = event.body.source && event.body.line ? {
697708
lineNumber: event.body.line,
698709
column: event.body.column ? event.body.column : 1,
699710
source: this.getSource(event.body.source)
@@ -703,7 +714,7 @@ export class DebugSession implements IDebugSession {
703714
outpuPromises.push(container.getChildren().then(children => {
704715
return Promise.all(waitFor).then(() => children.forEach(child => {
705716
// Since we can not display multiple trees in a row, we are displaying these variables one after the other (ignoring their names)
706-
child.name = null;
717+
(<any>child).name = null;
707718
this.appendToRepl(child, outputSeverity, source);
708719
}));
709720
}));
@@ -718,7 +729,7 @@ export class DebugSession implements IDebugSession {
718729
const breakpoint = this.model.getBreakpoints().filter(bp => bp.idFromAdapter === id).pop();
719730
const functionBreakpoint = this.model.getFunctionBreakpoints().filter(bp => bp.idFromAdapter === id).pop();
720731

721-
if (event.body.reason === 'new' && event.body.breakpoint.source) {
732+
if (event.body.reason === 'new' && event.body.breakpoint.source && event.body.breakpoint.line) {
722733
const source = this.getSource(event.body.breakpoint.source);
723734
const bps = this.model.addBreakpoints(source.uri, [{
724735
column: event.body.breakpoint.column,
@@ -770,7 +781,6 @@ export class DebugSession implements IDebugSession {
770781

771782
shutdown(): void {
772783
dispose(this.rawListeners);
773-
this.fetchThreadsScheduler = undefined;
774784
if (this.raw) {
775785
this.raw.disconnect();
776786
}
@@ -781,7 +791,7 @@ export class DebugSession implements IDebugSession {
781791

782792
//---- sources
783793

784-
getSourceForUri(uri: URI): Source {
794+
getSourceForUri(uri: URI): Source | undefined {
785795
return this.sources.get(this.getUriKey(uri));
786796
}
787797

src/vs/workbench/contrib/debug/electron-browser/rawDebugSession.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export class RawDebugSession {
7070
debugAdapter: IDebugAdapter,
7171
dbgr: IDebugger,
7272
private telemetryService: ITelemetryService,
73-
public customTelemetryService: ITelemetryService,
73+
public customTelemetryService: ITelemetryService | undefined,
7474
private environmentService: IEnvironmentService
7575
) {
7676
this.debugAdapter = debugAdapter;

0 commit comments

Comments
 (0)