mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 06:03:58 +00:00
ms-vscode.cpptools debugger support, initial version.
This commit is contained in:
parent
7a9ba1657d
commit
48d6e828f1
2 changed files with 138 additions and 12 deletions
103
editors/code/src/cargo.ts
Normal file
103
editors/code/src/cargo.ts
Normal file
|
@ -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<CompilationArtifact[]> {
|
||||||
|
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<string> {
|
||||||
|
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<number> {
|
||||||
|
return new Promise<number>((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}.`));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import * as lc from 'vscode-languageclient';
|
||||||
import * as ra from '../rust-analyzer-api';
|
import * as ra from '../rust-analyzer-api';
|
||||||
|
|
||||||
import { Ctx, Cmd } from '../ctx';
|
import { Ctx, Cmd } from '../ctx';
|
||||||
|
import { Cargo } from '../cargo';
|
||||||
|
|
||||||
export function run(ctx: Ctx): Cmd {
|
export function run(ctx: Ctx): Cmd {
|
||||||
let prevRunnable: RunnableQuickPick | undefined;
|
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<vscode.DebugConfiguration> {
|
||||||
|
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 {
|
export function debugSingle(ctx: Ctx): Cmd {
|
||||||
return async (config: ra.Runnable) => {
|
return async (config: ra.Runnable) => {
|
||||||
const editor = ctx.activeRustEditor;
|
const editor = ctx.activeRustEditor;
|
||||||
if (!editor) return;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const debugConfig = {
|
const debugConfig = lldb ? getLldbDebugConfig(config) : await getCppvsDebugConfig(config);
|
||||||
type: "lldb",
|
|
||||||
request: "launch",
|
|
||||||
name: config.label,
|
|
||||||
cargo: {
|
|
||||||
args: config.args,
|
|
||||||
},
|
|
||||||
args: config.extraArgs,
|
|
||||||
cwd: config.cwd
|
|
||||||
};
|
|
||||||
|
|
||||||
return vscode.debug.startDebugging(undefined, debugConfig);
|
return vscode.debug.startDebugging(undefined, debugConfig);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue