提交 b5ff5a17 编写于 作者: M Matt Bierner

Strict null work in debug

上级 947238c9
......@@ -517,11 +517,20 @@
"./vs/workbench/contrib/comments/electron-browser/commentService.ts",
"./vs/workbench/contrib/comments/electron-browser/simpleCommentEditor.ts",
"./vs/workbench/contrib/debug/browser/debugANSIHandling.ts",
"./vs/workbench/contrib/debug/browser/debugActionItems.ts",
"./vs/workbench/contrib/debug/browser/debugContentProvider.ts",
"./vs/workbench/contrib/debug/browser/debugStatus.ts",
"./vs/workbench/contrib/debug/browser/exceptionWidget.ts",
"./vs/workbench/contrib/debug/browser/linkDetector.ts",
"./vs/workbench/contrib/debug/browser/statusbarColorProvider.ts",
"./vs/workbench/contrib/debug/common/debug.ts",
"./vs/workbench/contrib/debug/common/debugProtocol.d.ts",
"./vs/workbench/contrib/debug/common/debugSchemas.ts",
"./vs/workbench/contrib/debug/common/debugSource.ts",
"./vs/workbench/contrib/debug/common/debugUtils.ts",
"./vs/workbench/contrib/debug/common/debugViewModel.ts",
"./vs/workbench/contrib/debug/electron-browser/rawDebugSession.ts",
"./vs/workbench/contrib/debug/node/debugAdapter.ts",
"./vs/workbench/contrib/debug/node/telemetryApp.ts",
"./vs/workbench/contrib/debug/test/common/debugSource.test.ts",
"./vs/workbench/contrib/debug/test/common/debugUtils.test.ts",
......
......@@ -31,7 +31,7 @@ export class StartDebugActionItem implements IActionItem {
private container: HTMLElement;
private start: HTMLElement;
private selectBox: SelectBox;
private options: { label: string, handler: (() => boolean) }[];
private options: { label: string, handler?: (() => boolean) }[];
private toDispose: IDisposable[];
private selected: number;
......@@ -46,7 +46,7 @@ export class StartDebugActionItem implements IActionItem {
@IContextViewService contextViewService: IContextViewService,
) {
this.toDispose = [];
this.selectBox = new SelectBox([], -1, contextViewService, null, { ariaLabel: nls.localize('debugLaunchConfigurations', 'Debug Launch Configurations') });
this.selectBox = new SelectBox([], -1, contextViewService, undefined, { ariaLabel: nls.localize('debugLaunchConfigurations', 'Debug Launch Configurations') });
this.toDispose.push(this.selectBox);
this.toDispose.push(attachSelectBoxStyler(this.selectBox, themeService, {
selectBackground: SIDE_BAR_BACKGROUND
......@@ -102,7 +102,8 @@ export class StartDebugActionItem implements IActionItem {
}
}));
this.toDispose.push(this.selectBox.onDidSelect(e => {
const shouldBeSelected = this.options[e.index].handler();
const target = this.options[e.index];
const shouldBeSelected = target.handler ? target.handler() : false;
if (shouldBeSelected) {
this.selected = e.index;
} else {
......
......@@ -52,7 +52,7 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC
this.pendingUpdates.forEach(cancellationSource => cancellationSource.dispose());
}
provideTextContent(resource: uri): Promise<ITextModel> {
provideTextContent(resource: uri): Promise<ITextModel> | null {
return this.createOrUpdateContentModel(resource, true);
}
......@@ -69,15 +69,15 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC
/**
* Create or reload the model content of the given resource.
*/
private createOrUpdateContentModel(resource: uri, createIfNotExists: boolean): Promise<ITextModel> {
private createOrUpdateContentModel(resource: uri, createIfNotExists: boolean): Promise<ITextModel> | null {
const model = this.modelService.getModel(resource);
if (!model && !createIfNotExists) {
// nothing to do
return undefined;
return null;
}
let session: IDebugSession;
let session: IDebugSession | undefined;
if (resource.query) {
const data = Source.getEncodedDebugData(resource);
......@@ -125,7 +125,7 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC
// remove token
this.pendingUpdates.delete(model.id);
if (!myToken.token.isCancellationRequested && edits.length > 0) {
if (!myToken.token.isCancellationRequested && edits && edits.length > 0) {
// use the evil-edit as these models show in readonly-editor only
model.applyEdits(edits.map(edit => EditOperation.replace(Range.lift(edit.range), edit.text)));
}
......
......@@ -24,7 +24,7 @@ export const debugExceptionWidgetBackground = registerColor('debugExceptionWidge
export class ExceptionWidget extends ZoneWidget {
private _backgroundColor: Color;
private _backgroundColor?: Color;
constructor(editor: ICodeEditor, private exceptionInfo: IExceptionInfo,
@IThemeService themeService: IThemeService,
......@@ -55,7 +55,7 @@ export class ExceptionWidget extends ZoneWidget {
protected _applyStyles(): void {
if (this.container) {
this.container.style.backgroundColor = this._backgroundColor.toString();
this.container.style.backgroundColor = this._backgroundColor ? this._backgroundColor.toString() : '';
}
super._applyStyles();
}
......@@ -86,7 +86,7 @@ export class ExceptionWidget extends ZoneWidget {
}
}
protected _doLayout(heightInPixel: number, widthInPixel: number): void {
protected _doLayout(_heightInPixel: number | undefined, _widthInPixel: number | undefined): void {
// Reload the height with respect to the exception text content and relayout it to match the line count.
this.container.style.height = 'initial';
......
......@@ -57,6 +57,9 @@ export class StatusBarColorProvider extends Themable implements IWorkbenchContri
super.updateStyles();
const container = this.partService.getContainer(Parts.STATUSBAR_PART);
if (!container) {
return;
}
if (isStatusbarInDebugMode(this.debugService)) {
addClass(container, 'debugging');
} else {
......
......@@ -461,7 +461,7 @@ export interface ICompound {
export interface IDebugAdapter extends IDisposable {
readonly onError: Event<Error>;
readonly onExit: Event<number>;
readonly onExit: Event<number | null>;
onRequest(callback: (request: DebugProtocol.Request) => void);
onEvent(callback: (event: DebugProtocol.Event) => void);
startSession(): Promise<void>;
......
......@@ -195,6 +195,6 @@ export const launchSchema: IJSONSchema = {
defaultCompound
]
},
inputs: inputsSchema.definitions.inputs
inputs: inputsSchema.definitions!.inputs
}
};
......@@ -73,10 +73,10 @@ export function getExactExpressionStartAndEnd(lineContent: string, looseStart: n
// RFC 2396, Appendix A: https://www.ietf.org/rfc/rfc2396.txt
const _schemePattern = /^[a-zA-Z][a-zA-Z0-9\+\-\.]+:/;
export function isUri(s: string) {
export function isUri(s: string | undefined): boolean {
// heuristics: a valid uri starts with a scheme and
// the scheme has at least 2 characters so that it doesn't look like a drive letter.
return s && s.match(_schemePattern);
return !!(s && s.match(_schemePattern));
}
function stringToUri(path: string): string {
......
......@@ -58,7 +58,7 @@ export class ViewModel implements IViewModel {
this._focusedThread = thread;
this._focusedSession = session;
this.loadedScriptsSupportedContextKey.set(session && session.capabilities.supportsLoadedSourcesRequest);
this.loadedScriptsSupportedContextKey.set(session ? !!session.capabilities.supportsLoadedSourcesRequest : false);
if (shouldEmitForSession) {
this._onDidFocusSession.fire(session);
......@@ -68,7 +68,7 @@ export class ViewModel implements IViewModel {
}
}
get onDidFocusSession(): Event<IDebugSession> {
get onDidFocusSession(): Event<IDebugSession | undefined> {
return this._onDidFocusSession.event;
}
......
......@@ -53,7 +53,7 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi
private conditionInput = '';
private hitCountInput = '';
private logMessageInput = '';
private breakpoint: IBreakpoint;
private breakpoint?: IBreakpoint;
constructor(editor: ICodeEditor, private lineNumber: number, private context: Context,
@IContextViewService private readonly contextViewService: IContextViewService,
......@@ -102,7 +102,7 @@ export class BreakpointWidget extends ZoneWidget implements IPrivateBreakpointWi
}
}
private getInputValue(breakpoint: IBreakpoint): string {
private getInputValue(breakpoint: IBreakpoint | undefined): string {
switch (this.context) {
case Context.LOG_MESSAGE:
return breakpoint && breakpoint.logMessage ? breakpoint.logMessage : this.logMessageInput;
......
......@@ -64,14 +64,16 @@ export class RawDebugSession {
// DA events
private readonly _onDidExitAdapter: Emitter<AdapterEndEvent>;
private debugAdapter: IDebugAdapter | null;
constructor(
private debugAdapter: IDebugAdapter,
debugAdapter: IDebugAdapter,
dbgr: IDebugger,
private telemetryService: ITelemetryService,
public customTelemetryService: ITelemetryService,
private environmentService: IEnvironmentService
) {
this.debugAdapter = debugAdapter;
this._capabilities = Object.create(null);
this._readyForBreakpoints = false;
this.inShutdown = false;
......@@ -224,6 +226,9 @@ export class RawDebugSession {
* Starts the underlying debug adapter and tracks the session time for telemetry.
*/
public start(): Promise<void> {
if (!this.debugAdapter) {
return Promise.reject(new Error('no debug adapter'));
}
return this.debugAdapter.startSession().then(() => {
this.startTime = new Date().getTime();
}, err => {
......@@ -560,7 +565,7 @@ export class RawDebugSession {
let spawnArgs = vscodeArgs.args.map(a => {
if ((a.prefix === '--file-uri=' || a.prefix === '--folder-uri=') && !isUri(a.path)) {
return a.path;
return (a.path || '');
}
return (a.prefix || '') + (a.path || '');
});
......@@ -622,6 +627,10 @@ export class RawDebugSession {
private send<R extends DebugProtocol.Response>(command: string, args: any, 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) => {
if (response.success) {
completeDispatch(response);
......@@ -639,7 +648,7 @@ export class RawDebugSession {
}
const error = errorResponse && errorResponse.body ? errorResponse.body.error : null;
const errorMessage = errorResponse ? errorResponse.message : '';
const errorMessage = errorResponse ? errorResponse.message || '' : '';
if (error && error.sendTelemetry) {
const telemetryMessage = error ? formatPII(error.format, true, error.variables) : errorMessage;
......@@ -650,7 +659,7 @@ export class RawDebugSession {
if (error && error.url) {
const label = error.urlLabel ? error.urlLabel : nls.localize('moreInfo', "More Info");
return createErrorWithActions(userMessage, {
actions: [new Action('debug.moreInfo', label, null, true, () => {
actions: [new Action('debug.moreInfo', label, undefined, true, () => {
window.open(error.url);
return Promise.resolve(null);
})]
......@@ -660,7 +669,7 @@ export class RawDebugSession {
return new Error(userMessage);
}
private mergeCapabilities(capabilities: DebugProtocol.Capabilities): void {
private mergeCapabilities(capabilities: DebugProtocol.Capabilities | undefined): void {
if (capabilities) {
this._capabilities = objects.mixin(this._capabilities, capabilities);
}
......@@ -674,11 +683,11 @@ export class RawDebugSession {
threadId,
allThreadsContinued
},
seq: undefined
seq: undefined!
});
}
private telemetryDebugProtocolErrorResponse(telemetryMessage: string) {
private telemetryDebugProtocolErrorResponse(telemetryMessage: string | undefined) {
/* __GDPR__
"debugProtocolErrorResponse" : {
"error" : { "classification": "CallstackOrException", "purpose": "FeatureInsight" }
......
......@@ -31,7 +31,7 @@ export abstract class AbstractDebugAdapter implements IDebugAdapter {
private messageCallback: (message: DebugProtocol.ProtocolMessage) => void;
protected readonly _onError: Emitter<Error>;
protected readonly _onExit: Emitter<number>;
protected readonly _onExit: Emitter<number | null>;
constructor() {
this.sequence = 1;
......@@ -50,7 +50,7 @@ export abstract class AbstractDebugAdapter implements IDebugAdapter {
return this._onError.event;
}
get onExit(): Event<number> {
get onExit(): Event<number | null> {
return this._onExit.event;
}
......@@ -255,7 +255,7 @@ export abstract class StreamDebugAdapter extends AbstractDebugAdapter {
*/
export class SocketDebugAdapter extends StreamDebugAdapter {
private socket: net.Socket;
private socket?: net.Socket;
constructor(private adapterServer: IDebugAdapterServer) {
super();
......@@ -265,8 +265,8 @@ export class SocketDebugAdapter extends StreamDebugAdapter {
return new Promise<void>((resolve, reject) => {
let connected = false;
this.socket = net.createConnection(this.adapterServer.port, this.adapterServer.host || '127.0.0.1', () => {
this.connect(this.socket, this.socket);
resolve(null);
this.connect(this.socket!, this.socket!);
resolve();
connected = true;
});
this.socket.on('close', () => {
......@@ -306,7 +306,7 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter {
private serverProcess: cp.ChildProcess;
constructor(private adapterExecutable: IDebugAdapterExecutable, private debugType: string, private outputService?: IOutputService) {
constructor(private adapterExecutable: IDebugAdapterExecutable, private debugType: string, private readonly outputService?: IOutputService) {
super();
}
......@@ -354,7 +354,7 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter {
reject(new Error(nls.localize('unableToLaunchDebugAdapter', "Unable to launch debug adapter from '{0}'.", this.adapterExecutable.args[0])));
}
this.serverProcess = child;
resolve(null);
resolve();
} else {
reject(new Error(nls.localize('unableToLaunchDebugAdapterNoArgs', "Unable to launch debug adapter.")));
}
......@@ -366,7 +366,7 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter {
options.cwd = this.adapterExecutable.options.cwd;
}
this.serverProcess = cp.spawn(this.adapterExecutable.command, this.adapterExecutable.args, options);
resolve(null);
resolve();
}
}).then(_ => {
this.serverProcess.on('error', err => {
......@@ -387,13 +387,14 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter {
this._onError.fire(error);
});
if (this.outputService) {
const outputService = this.outputService;
if (outputService) {
const sanitize = (s: string) => s.toString().replace(/\r?\n$/mg, '');
// this.serverProcess.stdout.on('data', (data: string) => {
// console.log('%c' + sanitize(data), 'background: #ddd; font-style: italic;');
// });
this.serverProcess.stderr.on('data', (data: string) => {
this.outputService.getChannel(ExtensionsChannelId).append(sanitize(data));
outputService.getChannel(ExtensionsChannelId).append(sanitize(data));
});
}
......@@ -431,7 +432,7 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter {
}
}
private static extract(contribution: IDebuggerContribution, extensionFolderPath: string): IDebuggerContribution {
private static extract(contribution: IDebuggerContribution, extensionFolderPath: string): IDebuggerContribution | undefined {
if (!contribution) {
return undefined;
}
......@@ -485,7 +486,7 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter {
if (ed.contributes) {
const debuggers = <IDebuggerContribution[]>ed.contributes['debuggers'];
if (debuggers && debuggers.length > 0) {
debuggers.filter(dbg => strings.equalsIgnoreCase(dbg.type, debugType)).forEach(dbg => {
debuggers.filter(dbg => typeof dbg.type === 'string' && strings.equalsIgnoreCase(dbg.type, debugType)).forEach(dbg => {
// extract relevant attributes and make then absolute where needed
const extractedDbg = ExecutableDebugAdapter.extract(dbg, ed.extensionLocation.fsPath);
......@@ -497,7 +498,7 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter {
}
// select the right platform
let platformInfo: IPlatformSpecificAdapterContribution;
let platformInfo: IPlatformSpecificAdapterContribution | undefined;
if (platform.isWindows && !process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432')) {
platformInfo = result.winx86 || result.win || result.windows;
} else if (platform.isWindows) {
......@@ -519,7 +520,7 @@ export class ExecutableDebugAdapter extends StreamDebugAdapter {
return {
type: 'executable',
command: runtime,
args: (runtimeArgs || []).concat([program]).concat(args || [])
args: (runtimeArgs || []).concat(typeof program === 'string' ? [program] : []).concat(args || [])
};
} else if (program) {
return {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册