From 48d6e828f1878436bb8633a1e7df02a6383d991a Mon Sep 17 00:00:00 2001 From: vsrs Date: Tue, 28 Apr 2020 17:30:49 +0300 Subject: ms-vscode.cpptools debugger support, initial version. --- editors/code/src/cargo.ts | 103 +++++++++++++++++++++++++++++++++ editors/code/src/commands/runnables.ts | 47 +++++++++++---- 2 files changed, 138 insertions(+), 12 deletions(-) create mode 100644 editors/code/src/cargo.ts (limited to 'editors/code/src') diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts new file mode 100644 index 000000000..d119b6225 --- /dev/null +++ b/editors/code/src/cargo.ts @@ -0,0 +1,103 @@ +import { window } from 'vscode'; +import * as cp from 'child_process'; +import * as readline from 'readline'; + +interface CompilationArtifact { + fileName: string; + name: string; + kind: string; + isTest: boolean; +} + +export class Cargo { + rootFolder: string; + env?: { [key: string]: string }; + + public constructor(cargoTomlFolder: string) { + this.rootFolder = cargoTomlFolder; + } + + public async artifactsFromArgs(cargoArgs: string[]): Promise { + let artifacts: CompilationArtifact[] = []; + + try { + await this.runCargo(cargoArgs, + message => { + if (message.reason == 'compiler-artifact' && message.executable) { + let isBinary = message.target.crate_types.includes('bin'); + let isBuildScript = message.target.kind.includes('custom-build'); + if ((isBinary && !isBuildScript) || message.profile.test) { + artifacts.push({ + fileName: message.executable, + name: message.target.name, + kind: message.target.kind[0], + isTest: message.profile.test + }) + } + } + }, + _stderr => { + // TODO: to output + } + ); + } + catch (err) { + // TODO: to output + throw new Error(`Cargo invocation has failed: ${err}`); + } + + return artifacts; + } + + public async executableFromArgs(cargoArgs: string[], extraArgs?: string[]): Promise { + cargoArgs.push("--message-format=json"); + if (extraArgs) { + cargoArgs.push('--'); + cargoArgs.push(...extraArgs); + } + + let artifacts = await this.artifactsFromArgs(cargoArgs); + + if (artifacts.length == 0 ) { + throw new Error('No compilation artifacts'); + } else if (artifacts.length > 1) { + throw new Error('Multiple compilation artifacts are not supported.'); + } + + return artifacts[0].fileName; + } + + runCargo( + cargoArgs: string[], + onStdoutJson: (obj: any) => void, + onStderrString: (data: string) => void + ): Promise { + return new Promise((resolve, reject) => { + let cargo = cp.spawn('cargo', cargoArgs, { + stdio: ['ignore', 'pipe', 'pipe'], + cwd: this.rootFolder, + env: this.env, + }); + + cargo.on('error', err => { + reject(new Error(`could not launch cargo: ${err}`)); + }); + cargo.stderr.on('data', chunk => { + onStderrString(chunk.toString()); + }); + + let rl = readline.createInterface({ input: cargo.stdout }); + rl.on('line', line => { + let message = JSON.parse(line); + onStdoutJson(message); + }); + + cargo.on('exit', (exitCode, _) => { + if (exitCode == 0) + resolve(exitCode); + else + reject(new Error(`exit code: ${exitCode}.`)); + }); + }); + } +} \ No newline at end of file diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index 2635a1440..26db18156 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -3,6 +3,7 @@ import * as lc from 'vscode-languageclient'; import * as ra from '../rust-analyzer-api'; import { Ctx, Cmd } from '../ctx'; +import { Cargo } from '../cargo'; export function run(ctx: Ctx): Cmd { let prevRunnable: RunnableQuickPick | undefined; @@ -62,25 +63,47 @@ export function runSingle(ctx: Ctx): Cmd { }; } +function getLldbDebugConfig(config: ra.Runnable) : vscode.DebugConfiguration { + return { + type: "lldb", + request: "launch", + name: config.label, + cargo: { + args: config.args, + }, + args: config.extraArgs, + cwd: config.cwd + }; +} + +async function getCppvsDebugConfig(config: ra.Runnable) : Promise { + let cargo = new Cargo(config.cwd || '.'); + let executable = await cargo.executableFromArgs(config.args, config.extraArgs); + + return { + type: "cppvsdbg", + request: "launch", + name: config.label, + program: executable, + args: config.extraArgs, + cwd: config.cwd, + }; +} + export function debugSingle(ctx: Ctx): Cmd { return async (config: ra.Runnable) => { const editor = ctx.activeRustEditor; if (!editor) return; - if (!vscode.extensions.getExtension("vadimcn.vscode-lldb")) { - vscode.window.showErrorMessage("Install `vadimcn.vscode-lldb` extension for debugging"); + + const mscpp = vscode.extensions.getExtension("ms-vscode.cpptools"); + const lldb = vscode.extensions.getExtension("vadimcn.vscode-lldb"); + + if (!(lldb || mscpp)) { + vscode.window.showErrorMessage("Install `vadimcn.vscode-lldb` or `ms-vscode.cpptools` extension for debugging"); return; } - const debugConfig = { - type: "lldb", - request: "launch", - name: config.label, - cargo: { - args: config.args, - }, - args: config.extraArgs, - cwd: config.cwd - }; + const debugConfig = lldb ? getLldbDebugConfig(config) : await getCppvsDebugConfig(config); return vscode.debug.startDebugging(undefined, debugConfig); }; -- cgit v1.2.3 From 042917e6e3bc3cb05e08e487ee8a7d0d4ae3af6b Mon Sep 17 00:00:00 2001 From: vsrs Date: Wed, 29 Apr 2020 13:10:42 +0300 Subject: Configuration settings and source maps support --- editors/code/src/cargo.ts | 1 - editors/code/src/commands/runnables.ts | 33 +++++++++++++++++++++++++-------- editors/code/src/config.ts | 9 ++++++++- 3 files changed, 33 insertions(+), 10 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts index d119b6225..5999187f4 100644 --- a/editors/code/src/cargo.ts +++ b/editors/code/src/cargo.ts @@ -1,4 +1,3 @@ -import { window } from 'vscode'; import * as cp from 'child_process'; import * as readline from 'readline'; diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index 26db18156..befb8b366 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -63,7 +63,7 @@ export function runSingle(ctx: Ctx): Cmd { }; } -function getLldbDebugConfig(config: ra.Runnable) : vscode.DebugConfiguration { +function getLldbDebugConfig(config: ra.Runnable, sourceFileMap: Record): vscode.DebugConfiguration { return { type: "lldb", request: "launch", @@ -72,11 +72,12 @@ function getLldbDebugConfig(config: ra.Runnable) : vscode.DebugConfiguration { args: config.args, }, args: config.extraArgs, - cwd: config.cwd + cwd: config.cwd, + sourceMap: sourceFileMap }; } -async function getCppvsDebugConfig(config: ra.Runnable) : Promise { +async function getCppvsDebugConfig(config: ra.Runnable, sourceFileMap: Record): Promise { let cargo = new Cargo(config.cwd || '.'); let executable = await cargo.executableFromArgs(config.args, config.extraArgs); @@ -87,6 +88,7 @@ async function getCppvsDebugConfig(config: ra.Runnable) : Promise("updates.askBeforeDownload"); } get traceExtension() { return this.get("trace.extension"); } - get inlayHints() { return { typeHints: this.get("inlayHints.typeHints"), @@ -107,4 +106,12 @@ export class Config { command: this.get("checkOnSave.command"), }; } + + get debug() { + return { + engine: this.get("debug.engine"), + sourceFileMap: this.get>("debug.sourceFileMap"), + }; + } + } -- cgit v1.2.3 From 9153e96e88236e2f867dee8f0f291af5cfaf90f4 Mon Sep 17 00:00:00 2001 From: vsrs Date: Wed, 29 Apr 2020 14:13:57 +0300 Subject: better configuration enum items --- editors/code/src/commands/runnables.ts | 2 +- editors/code/src/config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index befb8b366..2238a5a73 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -102,7 +102,7 @@ export function debugSingle(ctx: Ctx): Cmd { let debugEngineId = ctx.config.debug.engine; let debugEngine = null; - if (!debugEngineId) { + if ( debugEngineId === "auto" ) { debugEngine = vscode.extensions.getExtension(lldbId); if (!debugEngine) { debugEngine = vscode.extensions.getExtension(cpptoolsId); diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index 7764a2179..110e54180 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -109,7 +109,7 @@ export class Config { get debug() { return { - engine: this.get("debug.engine"), + engine: this.get("debug.engine"), sourceFileMap: this.get>("debug.sourceFileMap"), }; } -- cgit v1.2.3 From 73a1947d19b4d3c29aa462e856e3d410d6e1e5dd Mon Sep 17 00:00:00 2001 From: vsrs Date: Wed, 29 Apr 2020 16:52:53 +0300 Subject: MS C++ tools on linux --- editors/code/src/commands/runnables.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index 2238a5a73..9b0780650 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -1,6 +1,7 @@ import * as vscode from 'vscode'; import * as lc from 'vscode-languageclient'; import * as ra from '../rust-analyzer-api'; +import * as os from "os"; import { Ctx, Cmd } from '../ctx'; import { Cargo } from '../cargo'; @@ -82,7 +83,7 @@ async function getCppvsDebugConfig(config: ra.Runnable, sourceFileMap: Record Date: Thu, 30 Apr 2020 15:25:04 +0300 Subject: pass Cargo errors to the Debug output channel --- editors/code/src/cargo.ts | 17 ++++++++++++----- editors/code/src/commands/runnables.ts | 7 ++++++- 2 files changed, 18 insertions(+), 6 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts index 5999187f4..857b84d59 100644 --- a/editors/code/src/cargo.ts +++ b/editors/code/src/cargo.ts @@ -1,5 +1,6 @@ import * as cp from 'child_process'; import * as readline from 'readline'; +import { OutputChannel } from 'vscode'; interface CompilationArtifact { fileName: string; @@ -10,10 +11,13 @@ interface CompilationArtifact { export class Cargo { rootFolder: string; - env?: { [key: string]: string }; + env?: Record; + output: OutputChannel; - public constructor(cargoTomlFolder: string) { + public constructor(cargoTomlFolder: string, output: OutputChannel, env: Record | undefined = undefined) { this.rootFolder = cargoTomlFolder; + this.output = output; + this.env = env; } public async artifactsFromArgs(cargoArgs: string[]): Promise { @@ -34,14 +38,17 @@ export class Cargo { }) } } + else if( message.reason == 'compiler-message') { + this.output.append(message.message.rendered); + } }, - _stderr => { - // TODO: to output + stderr => { + this.output.append(stderr); } ); } catch (err) { - // TODO: to output + this.output.show(true); throw new Error(`Cargo invocation has failed: ${err}`); } diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index 9b0780650..e8035c7d2 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -78,10 +78,15 @@ function getLldbDebugConfig(config: ra.Runnable, sourceFileMap: Record): Promise { - let cargo = new Cargo(config.cwd || '.'); + debugOutput.clear(); + + let cargo = new Cargo(config.cwd || '.', debugOutput); let executable = await cargo.executableFromArgs(config.args, config.extraArgs); + // if we are here, there were no compilation errors. return { type: (os.platform() === "win32") ? "cppvsdbg" : 'cppdbg', request: "launch", -- cgit v1.2.3 From 10836543d693675a9a2fd90130b1a816ede90fea Mon Sep 17 00:00:00 2001 From: vsrs Date: Thu, 30 Apr 2020 18:41:48 +0300 Subject: Fixed tsfmt and eslint errors. --- editors/code/src/cargo.ts | 24 ++++++++++++------------ editors/code/src/commands/runnables.ts | 14 +++++++------- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts index 857b84d59..50f93856d 100644 --- a/editors/code/src/cargo.ts +++ b/editors/code/src/cargo.ts @@ -21,24 +21,24 @@ export class Cargo { } public async artifactsFromArgs(cargoArgs: string[]): Promise { - let artifacts: CompilationArtifact[] = []; + const artifacts: CompilationArtifact[] = []; try { await this.runCargo(cargoArgs, message => { - if (message.reason == 'compiler-artifact' && message.executable) { - let isBinary = message.target.crate_types.includes('bin'); - let isBuildScript = message.target.kind.includes('custom-build'); + if (message.reason === 'compiler-artifact' && message.executable) { + const isBinary = message.target.crate_types.includes('bin'); + const isBuildScript = message.target.kind.includes('custom-build'); if ((isBinary && !isBuildScript) || message.profile.test) { artifacts.push({ fileName: message.executable, name: message.target.name, kind: message.target.kind[0], isTest: message.profile.test - }) + }); } } - else if( message.reason == 'compiler-message') { + else if (message.reason === 'compiler-message') { this.output.append(message.message.rendered); } }, @@ -62,9 +62,9 @@ export class Cargo { cargoArgs.push(...extraArgs); } - let artifacts = await this.artifactsFromArgs(cargoArgs); + const artifacts = await this.artifactsFromArgs(cargoArgs); - if (artifacts.length == 0 ) { + if (artifacts.length === 0) { throw new Error('No compilation artifacts'); } else if (artifacts.length > 1) { throw new Error('Multiple compilation artifacts are not supported.'); @@ -79,7 +79,7 @@ export class Cargo { onStderrString: (data: string) => void ): Promise { return new Promise((resolve, reject) => { - let cargo = cp.spawn('cargo', cargoArgs, { + const cargo = cp.spawn('cargo', cargoArgs, { stdio: ['ignore', 'pipe', 'pipe'], cwd: this.rootFolder, env: this.env, @@ -92,14 +92,14 @@ export class Cargo { onStderrString(chunk.toString()); }); - let rl = readline.createInterface({ input: cargo.stdout }); + const rl = readline.createInterface({ input: cargo.stdout }); rl.on('line', line => { - let message = JSON.parse(line); + const message = JSON.parse(line); onStdoutJson(message); }); cargo.on('exit', (exitCode, _) => { - if (exitCode == 0) + if (exitCode === 0) resolve(exitCode); else reject(new Error(`exit code: ${exitCode}.`)); diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index e8035c7d2..36d309334 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -82,9 +82,9 @@ const debugOutput = vscode.window.createOutputChannel("Debug"); async function getCppvsDebugConfig(config: ra.Runnable, sourceFileMap: Record): Promise { debugOutput.clear(); - - let cargo = new Cargo(config.cwd || '.', debugOutput); - let executable = await cargo.executableFromArgs(config.args, config.extraArgs); + + const cargo = new Cargo(config.cwd || '.', debugOutput); + const executable = await cargo.executableFromArgs(config.args, config.extraArgs); // if we are here, there were no compilation errors. return { @@ -106,9 +106,9 @@ export function debugSingle(ctx: Ctx): Cmd { const lldbId = "vadimcn.vscode-lldb"; const cpptoolsId = "ms-vscode.cpptools"; - let debugEngineId = ctx.config.debug.engine; + const debugEngineId = ctx.config.debug.engine; let debugEngine = null; - if ( debugEngineId === "auto" ) { + if (debugEngineId === "auto") { debugEngine = vscode.extensions.getExtension(lldbId); if (!debugEngine) { debugEngine = vscode.extensions.getExtension(cpptoolsId); @@ -120,11 +120,11 @@ export function debugSingle(ctx: Ctx): Cmd { if (!debugEngine) { vscode.window.showErrorMessage(`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=${lldbId})` - + ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=${cpptoolsId}) extension for debugging.`); + + ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=${cpptoolsId}) extension for debugging.`); return; } - const debugConfig = lldbId == debugEngine.id + const debugConfig = lldbId === debugEngine.id ? getLldbDebugConfig(config, ctx.config.debug.sourceFileMap) : await getCppvsDebugConfig(config, ctx.config.debug.sourceFileMap); -- cgit v1.2.3 From 11e9e4b1fb48fb24a206c65c43fb374fe57dc26f Mon Sep 17 00:00:00 2001 From: vsrs Date: Thu, 30 Apr 2020 18:53:34 +0300 Subject: Removed unnecessary extraArgs for cargo invocation --- editors/code/src/cargo.ts | 7 ++----- editors/code/src/commands/runnables.ts | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'editors/code/src') diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts index 50f93856d..3a7e70307 100644 --- a/editors/code/src/cargo.ts +++ b/editors/code/src/cargo.ts @@ -55,12 +55,9 @@ export class Cargo { return artifacts; } - public async executableFromArgs(cargoArgs: string[], extraArgs?: string[]): Promise { + public async executableFromArgs(args: string[]): Promise { + let cargoArgs = [...args]; // to remain args unchanged cargoArgs.push("--message-format=json"); - if (extraArgs) { - cargoArgs.push('--'); - cargoArgs.push(...extraArgs); - } const artifacts = await this.artifactsFromArgs(cargoArgs); diff --git a/editors/code/src/commands/runnables.ts b/editors/code/src/commands/runnables.ts index 36d309334..d77e8188c 100644 --- a/editors/code/src/commands/runnables.ts +++ b/editors/code/src/commands/runnables.ts @@ -84,7 +84,7 @@ async function getCppvsDebugConfig(config: ra.Runnable, sourceFileMap: Record Date: Thu, 30 Apr 2020 18:57:40 +0300 Subject: fixed lint warning --- editors/code/src/cargo.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/src') diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts index 3a7e70307..a328ba9bd 100644 --- a/editors/code/src/cargo.ts +++ b/editors/code/src/cargo.ts @@ -56,7 +56,7 @@ export class Cargo { } public async executableFromArgs(args: string[]): Promise { - let cargoArgs = [...args]; // to remain args unchanged + const cargoArgs = [...args]; // to remain args unchanged cargoArgs.push("--message-format=json"); const artifacts = await this.artifactsFromArgs(cargoArgs); -- cgit v1.2.3