Skip to content

set strictNullChecks to true in tsconfig.json and fix errors #422

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/backend/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface Breakpoint {
file?: string;
line?: number;
raw?: string;
condition: string;
condition?: string;
countCondition?: string;
}

Expand Down Expand Up @@ -54,6 +54,8 @@ export interface SSHArguments {
sourceFileMap: { [index: string]: string };
}

export type ResultBreakpoint = [true, Breakpoint] | [false, undefined];

export interface IBackend {
load(cwd: string, target: string, procArgs: string, separateConsole: string, autorun: string[]): Thenable<any>;
ssh(args: SSHArguments, cwd: string, target: string, procArgs: string, separateConsole: string, attach: boolean, autorun: string[]): Thenable<any>;
Expand All @@ -67,8 +69,8 @@ export interface IBackend {
next(): Thenable<boolean>;
step(): Thenable<boolean>;
stepOut(): Thenable<boolean>;
loadBreakPoints(breakpoints: Breakpoint[]): Thenable<[boolean, Breakpoint][]>;
addBreakPoint(breakpoint: Breakpoint): Thenable<[boolean, Breakpoint]>;
loadBreakPoints(breakpoints: Breakpoint[]): Thenable<ResultBreakpoint[]>;
addBreakPoint(breakpoint: Breakpoint): Thenable<ResultBreakpoint>;
removeBreakPoint(breakpoint: Breakpoint): Thenable<boolean>;
clearBreakPoints(source?: string): Thenable<any>;
getThreads(): Thenable<Thread[]>;
Expand Down Expand Up @@ -162,5 +164,5 @@ export const MIError: MIErrorConstructor = class MIError {
return `${this.message} (from ${this._source})`;
}
};
Object.setPrototypeOf(MIError as any, Object.create(Error.prototype));
Object.setPrototypeOf(MIError, Object.create(Error.prototype));
MIError.prototype.constructor = MIError;
2 changes: 1 addition & 1 deletion src/backend/gdb_expansion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function isExpandable(value: string): number {
else return 0;
}

export function expandValue(variableCreate: (arg: VariableObject | string, options?: any) => any, value: string, root: string = "", extra: any = undefined): any {
export function expandValue(variableCreate: (arg: VariableObject | string, options?: { "arg": boolean }) => any, value: string, root: string = "", extra: any = undefined): any {
const parseCString = () => {
value = value.trim();
if (value[0] != '"' && value[0] != '\'')
Expand Down
73 changes: 39 additions & 34 deletions src/backend/mi2/mi2.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Breakpoint, IBackend, Thread, Stack, SSHArguments, Variable, RegisterValue, VariableObject, MIError } from "../backend";
import { Breakpoint, IBackend, Thread, Stack, SSHArguments, Variable, RegisterValue, VariableObject, MIError, ResultBreakpoint } from "../backend";
import * as ChildProcess from "child_process";
import { EventEmitter } from "events";
import { parseMI, MINode } from '../mi_parse';
Expand Down Expand Up @@ -48,15 +48,15 @@ export class MI2 extends EventEmitter implements IBackend {
}
}

load(cwd: string, target: string, procArgs: string, separateConsole: string, autorun: string[]): Thenable<any> {
load(cwd: string, target: string, procArgs: string, separateConsole: string | undefined, autorun: string[]): Thenable<any> {
if (!path.isAbsolute(target))
target = path.join(cwd, target);
return new Promise((resolve, reject) => {
this.isSSH = false;
const args = this.preargs.concat(this.extraargs || []);
this.process = ChildProcess.spawn(this.application, args, { cwd: cwd, env: this.procEnv });
this.process.stdout.on("data", this.stdout.bind(this));
this.process.stderr.on("data", this.stderr.bind(this));
this.process.stdout?.on("data", this.stdout.bind(this));
this.process.stderr?.on("data", this.stderr.bind(this));
this.process.on("exit", () => this.emit("quit"));
this.process.on("error", err => this.emit("launcherror", err));
const promises = this.initCommands(target, cwd);
Expand Down Expand Up @@ -91,7 +91,7 @@ export class MI2 extends EventEmitter implements IBackend {
});
}

ssh(args: SSHArguments, cwd: string, target: string, procArgs: string, separateConsole: string, attach: boolean, autorun: string[]): Thenable<any> {
ssh(args: SSHArguments, cwd: string, target: string, procArgs: string, separateConsole: string | undefined, attach: boolean, autorun: string[]): Thenable<any> {
return new Promise((resolve, reject) => {
this.isSSH = true;
this.sshReady = false;
Expand Down Expand Up @@ -233,8 +233,8 @@ export class MI2 extends EventEmitter implements IBackend {
executable = path.join(cwd, executable);
args = this.preargs.concat(this.extraargs || []);
this.process = ChildProcess.spawn(this.application, args, { cwd: cwd, env: this.procEnv });
this.process.stdout.on("data", this.stdout.bind(this));
this.process.stderr.on("data", this.stderr.bind(this));
this.process.stdout?.on("data", this.stdout.bind(this));
this.process.stderr?.on("data", this.stderr.bind(this));
this.process.on("exit", () => this.emit("quit"));
this.process.on("error", err => this.emit("launcherror", err));
const promises = this.initCommands(target, cwd, true);
Expand Down Expand Up @@ -265,8 +265,8 @@ export class MI2 extends EventEmitter implements IBackend {
if (executable)
args = args.concat([executable]);
this.process = ChildProcess.spawn(this.application, args, { cwd: cwd, env: this.procEnv });
this.process.stdout.on("data", this.stdout.bind(this));
this.process.stderr.on("data", this.stderr.bind(this));
this.process.stdout?.on("data", this.stdout.bind(this));
this.process.stderr?.on("data", this.stderr.bind(this));
this.process.on("exit", () => this.emit("quit"));
this.process.on("error", err => this.emit("launcherror", err));
const promises = this.initCommands(target, cwd, true);
Expand Down Expand Up @@ -450,8 +450,8 @@ export class MI2 extends EventEmitter implements IBackend {
return new Promise((resolve, reject) => {
this.log("console", "Running executable");
this.sendCommand(startCommand).then((info) => {
if (info.resultRecords.resultClass == "running")
resolve(undefined);
if (info.resultRecords?.resultClass == "running")
resolve(false);
else
reject();
}, reject);
Expand Down Expand Up @@ -496,7 +496,7 @@ export class MI2 extends EventEmitter implements IBackend {
this.log("stderr", "interrupt");
return new Promise((resolve, reject) => {
this.sendCommand("exec-interrupt").then((info) => {
resolve(info.resultRecords.resultClass == "done");
resolve(info.resultRecords?.resultClass == "done");
}, reject);
});
}
Expand All @@ -506,7 +506,7 @@ export class MI2 extends EventEmitter implements IBackend {
this.log("stderr", "continue");
return new Promise((resolve, reject) => {
this.sendCommand("exec-continue" + (reverse ? " --reverse" : "")).then((info) => {
resolve(info.resultRecords.resultClass == "running");
resolve(info.resultRecords?.resultClass == "running");
}, reject);
});
}
Expand All @@ -516,7 +516,7 @@ export class MI2 extends EventEmitter implements IBackend {
this.log("stderr", "next");
return new Promise((resolve, reject) => {
this.sendCommand("exec-next" + (reverse ? " --reverse" : "")).then((info) => {
resolve(info.resultRecords.resultClass == "running");
resolve(info.resultRecords?.resultClass == "running");
}, reject);
});
}
Expand All @@ -526,7 +526,7 @@ export class MI2 extends EventEmitter implements IBackend {
this.log("stderr", "step");
return new Promise((resolve, reject) => {
this.sendCommand("exec-step" + (reverse ? " --reverse" : "")).then((info) => {
resolve(info.resultRecords.resultClass == "running");
resolve(info.resultRecords?.resultClass == "running");
}, reject);
});
}
Expand All @@ -536,7 +536,7 @@ export class MI2 extends EventEmitter implements IBackend {
this.log("stderr", "stepOut");
return new Promise((resolve, reject) => {
this.sendCommand("exec-finish" + (reverse ? " --reverse" : "")).then((info) => {
resolve(info.resultRecords.resultClass == "running");
resolve(info.resultRecords?.resultClass == "running");
}, reject);
});
}
Expand All @@ -548,7 +548,7 @@ export class MI2 extends EventEmitter implements IBackend {
const target: string = '"' + (filename ? escape(filename) + ":" : "") + line + '"';
this.sendCommand("break-insert -t " + target).then(() => {
this.sendCommand("exec-jump " + target).then((info) => {
resolve(info.resultRecords.resultClass == "running");
resolve(info.resultRecords?.resultClass == "running");
}, reject);
}, reject);
});
Expand All @@ -560,14 +560,14 @@ export class MI2 extends EventEmitter implements IBackend {
return this.sendCommand("gdb-set var " + name + "=" + rawValue);
}

loadBreakPoints(breakpoints: Breakpoint[]): Thenable<[boolean, Breakpoint][]> {
loadBreakPoints(breakpoints: Breakpoint[]): Thenable<ResultBreakpoint[]> {
if (trace)
this.log("stderr", "loadBreakPoints");
const promisses: Thenable<[boolean, Breakpoint]>[] = [];
const promises: Thenable<ResultBreakpoint>[] = [];
breakpoints.forEach(breakpoint => {
promisses.push(this.addBreakPoint(breakpoint));
promises.push(this.addBreakPoint(breakpoint));
});
return Promise.all(promisses);
return Promise.all(promises);
}

setBreakPointCondition(bkptNum: number, condition: string): Thenable<any> {
Expand All @@ -580,31 +580,36 @@ export class MI2 extends EventEmitter implements IBackend {
return this.sendCommand("break-insert -t -f " + entryPoint);
}

addBreakPoint(breakpoint: Breakpoint): Thenable<[boolean, Breakpoint]> {
addBreakPoint(breakpoint: Breakpoint): Thenable<ResultBreakpoint> {
if (trace)
this.log("stderr", "addBreakPoint");
return new Promise((resolve, reject) => {
if (this.breakpoints.has(breakpoint))
return resolve([false, undefined]);
let location = "";
if (breakpoint.countCondition) {
if (breakpoint.countCondition[0] == ">")
location += "-i " + numRegex.exec(breakpoint.countCondition.substring(1))[0] + " ";
if (breakpoint.countCondition[0] == ">") {
const match = numRegex.exec(breakpoint.countCondition.substring(1));
if (match)
location += "-i " + match[0] + " ";
else
this.log("stderr", "Unsupported break count expression: '" + breakpoint.countCondition + "'. Only supports 'X' for breaking once after X times or '>X' for ignoring the first X breaks");
}
else {
const match = numRegex.exec(breakpoint.countCondition)[0];
if (match.length != breakpoint.countCondition.length) {
const match = numRegex.exec(breakpoint.countCondition);
if (!match || match[0].length != breakpoint.countCondition.length) {
this.log("stderr", "Unsupported break count expression: '" + breakpoint.countCondition + "'. Only supports 'X' for breaking once after X times or '>X' for ignoring the first X breaks");
location += "-t ";
} else if (parseInt(match) != 0)
location += "-t -i " + parseInt(match) + " ";
} else if (parseInt(match[0]) != 0)
location += "-t -i " + parseInt(match[0]) + " ";
}
}
if (breakpoint.raw)
location += '"' + escape(breakpoint.raw) + '"';
else
location += '"' + escape(breakpoint.file) + ":" + breakpoint.line + '"';
location += '"' + escape(breakpoint.file ?? "") + ":" + breakpoint.line + '"';
this.sendCommand("break-insert -f " + location).then((result) => {
if (result.resultRecords.resultClass == "done") {
if (result.resultRecords?.resultClass == "done") {
const bkptNum = parseInt(result.result("bkpt.number"));
const newBrk = {
file: breakpoint.file ? breakpoint.file : result.result("bkpt.file"),
Expand Down Expand Up @@ -639,7 +644,7 @@ export class MI2 extends EventEmitter implements IBackend {
if (!this.breakpoints.has(breakpoint))
return resolve(false);
this.sendCommand("break-delete " + this.breakpoints.get(breakpoint)).then((result) => {
if (result.resultRecords.resultClass == "done") {
if (result.resultRecords?.resultClass == "done") {
this.breakpoints.delete(breakpoint);
resolve(true);
} else resolve(false);
Expand All @@ -657,7 +662,7 @@ export class MI2 extends EventEmitter implements IBackend {
breakpoints.forEach((k, index) => {
if (index.file === source) {
promises.push(this.sendCommand("break-delete " + k).then((result) => {
if (result.resultRecords.resultClass == "done") resolve(true);
if (result.resultRecords?.resultClass == "done") resolve(true);
else resolve(false);
}));
} else {
Expand Down Expand Up @@ -689,7 +694,7 @@ export class MI2 extends EventEmitter implements IBackend {
});
}

async getStack(startFrame: number, maxLevels: number, thread: number): Promise<Stack[]> {
async getStack(startFrame: number | undefined, maxLevels: number | undefined, thread: number): Promise<Stack[]> {
if (trace) this.log("stderr", "getStack");

const options: string[] = [];
Expand Down Expand Up @@ -894,7 +899,7 @@ export class MI2 extends EventEmitter implements IBackend {
if (this.isSSH)
this.stream.write(raw + "\n");
else
this.process.stdin.write(raw + "\n");
this.process.stdin?.write(raw + "\n");
}

sendCliCommand(command: string, threadId: number = 0, frameLevel: number = 0): Thenable<MINode> {
Expand Down
5 changes: 2 additions & 3 deletions src/backend/mi2/mi2lldb.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { MI2, escape } from "./mi2";
import { Breakpoint } from "../backend";
import * as ChildProcess from "child_process";
import * as path from "path";

Expand Down Expand Up @@ -39,8 +38,8 @@ export class MI2_LLDB extends MI2 {
return new Promise((resolve, reject) => {
const args = this.preargs.concat(this.extraargs || []);
this.process = ChildProcess.spawn(this.application, args, { cwd: cwd, env: this.procEnv });
this.process.stdout.on("data", this.stdout.bind(this));
this.process.stderr.on("data", this.stderr.bind(this));
this.process.stdout?.on("data", this.stdout.bind(this));
this.process.stderr?.on("data", this.stderr.bind(this));
this.process.on("exit", () => this.emit("quit"));
this.process.on("error", err => this.emit("launcherror", err));
const promises = this.initCommands(target, cwd, true);
Expand Down
4 changes: 2 additions & 2 deletions src/backend/mi2/mi2mago.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class MI2_Mago extends MI2_LLDB {
return new Promise((resolve, reject) => {
const command = "stack-list-frames";
this.sendCommand(command).then((result) => {
const stack = result.resultRecords.results;
const stack = result.resultRecords?.results;
const ret: Stack[] = [];
const remaining: any = [];
const addToStack = (element: any) => {
Expand All @@ -30,7 +30,7 @@ export class MI2_Mago extends MI2_LLDB {
line: line
});
};
stack.forEach(element => {
stack && stack.forEach(element => {
if (element)
if (element[0] == "stack") {
addToStack(element[1]);
Expand Down
34 changes: 22 additions & 12 deletions src/backend/mi_parse.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
type MIOutOfBandRecord = {
isStream: boolean;
type: string;
asyncClass: string;
output: [string, any][];
content: string;
};
type MIResultClass = "done" | "running" | "connected" | "error" | "exit";
type MIResultRecord = { resultClass: MIResultClass, results: [string, any][] } | undefined;

export interface MIInfo {
token: number;
outOfBandRecord: { isStream: boolean, type: string, asyncClass: string, output: [string, any][], content: string }[];
resultRecords: { resultClass: string, results: [string, any][] };
token: number | undefined;
outOfBandRecord: MIOutOfBandRecord[];
resultRecords: MIResultRecord;
}

const octalMatch = /^[0-7]{3}/;
Expand Down Expand Up @@ -55,11 +65,11 @@ function parseString(str: string): string {
}

export class MINode implements MIInfo {
token: number;
outOfBandRecord: { isStream: boolean, type: string, asyncClass: string, output: [string, any][], content: string }[];
resultRecords: { resultClass: string, results: [string, any][] };
token: number | undefined;
outOfBandRecord: MIOutOfBandRecord[];
resultRecords: MIResultRecord;

constructor(token: number, info: { isStream: boolean, type: string, asyncClass: string, output: [string, any][], content: string }[], result: { resultClass: string, results: [string, any][] }) {
constructor(token: number | undefined, info: MIOutOfBandRecord[], result: MIResultRecord) {
this.token = token;
this.outOfBandRecord = info;
this.resultRecords = result;
Expand Down Expand Up @@ -150,8 +160,8 @@ export function parseMI(output: string): MINode {
*/

let token = undefined;
const outOfBandRecord: { isStream: boolean, type: string, asyncClass: string, output: [string, any][], content: string }[] = [];
let resultRecords = undefined;
const outOfBandRecord: MIOutOfBandRecord[] = [];
let resultRecords: MIResultRecord = undefined;

const asyncRecordType = {
"*": "exec",
Expand Down Expand Up @@ -271,11 +281,11 @@ export function parseMI(output: string): MINode {

if (match[2]) {
const classMatch = asyncClassRegex.exec(output);
output = output.substring(classMatch[0].length);
output = output.substring(classMatch?.[0].length ?? 0);
const asyncRecord = {
isStream: false,
type: asyncRecordType[match[2] as keyof typeof asyncRecordType],
asyncClass: classMatch[0],
asyncClass: classMatch?.[0] ?? "",
output: [] as any,
content: ""
};
Expand Down Expand Up @@ -303,7 +313,7 @@ export function parseMI(output: string): MINode {
token = parseInt(match[1]);
}
resultRecords = {
resultClass: match[2],
resultClass: match[2] as MIResultClass,
results: []
};
let result;
Expand Down
6 changes: 3 additions & 3 deletions src/frontend/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ function examineMemory() {
return vscode.window.showErrorMessage("No debugging sessions available");
}
const pickedFile = (file: string) => {
vscode.window.showInputBox({ placeHolder: "Memory Location or Range", validateInput: range => getMemoryRange(range) === undefined ? "Range must either be in format 0xF00-0xF01, 0xF100+32 or 0xABC154" : "" }).then(range => {
vscode.window.showTextDocument(vscode.Uri.parse("debugmemory://" + file + "?" + getMemoryRange(range)));
vscode.window.showInputBox({ placeHolder: "Memory Location or Range", validateInput: range => getMemoryRange(range) === undefined ? "Range must either be in format 0xF00-0xF01, 0xF100+32 or 0xABC154" : "" }).then((range: string | undefined) => {
range && vscode.window.showTextDocument(vscode.Uri.parse("debugmemory://" + file + "?" + getMemoryRange(range)));
});
};
if (files.length == 1)
pickedFile(files[0]);
else if (files.length > 0)
vscode.window.showQuickPick(files, { placeHolder: "Running debugging instance" }).then(file => pickedFile(file));
vscode.window.showQuickPick(files, { placeHolder: "Running debugging instance" }).then(file => file && pickedFile(file));
else if (process.platform == "win32")
return vscode.window.showErrorMessage("This command is not available on windows");
else
Expand Down
Loading