aboutsummaryrefslogtreecommitdiff
path: root/editors/code/src/cargo.ts
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src/cargo.ts')
-rw-r--r--editors/code/src/cargo.ts57
1 files changed, 34 insertions, 23 deletions
diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts
index 6a41873d0..a55b2f860 100644
--- a/editors/code/src/cargo.ts
+++ b/editors/code/src/cargo.ts
@@ -12,14 +12,44 @@ interface CompilationArtifact {
12 isTest: boolean; 12 isTest: boolean;
13} 13}
14 14
15export interface ArtifactSpec {
16 cargoArgs: string[];
17 filter?: (artifacts: CompilationArtifact[]) => CompilationArtifact[];
18}
19
20export function artifactSpec(args: readonly string[]): ArtifactSpec {
21 const cargoArgs = [...args, "--message-format=json"];
22
23 // arguments for a runnable from the quick pick should be updated.
24 // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_code_lens
25 switch (cargoArgs[0]) {
26 case "run": cargoArgs[0] = "build"; break;
27 case "test": {
28 if (!cargoArgs.includes("--no-run")) {
29 cargoArgs.push("--no-run");
30 }
31 break;
32 }
33 }
34
35 const result: ArtifactSpec = { cargoArgs: cargoArgs };
36 if (cargoArgs[0] === "test") {
37 // for instance, `crates\rust-analyzer\tests\heavy_tests\main.rs` tests
38 // produce 2 artifacts: {"kind": "bin"} and {"kind": "test"}
39 result.filter = (artifacts) => artifacts.filter(it => it.isTest);
40 }
41
42 return result;
43}
44
15export class Cargo { 45export class Cargo {
16 constructor(readonly rootFolder: string, readonly output: OutputChannel) { } 46 constructor(readonly rootFolder: string, readonly output: OutputChannel) { }
17 47
18 private async artifactsFromArgs(cargoArgs: string[]): Promise<CompilationArtifact[]> { 48 private async getArtifacts(spec: ArtifactSpec): Promise<CompilationArtifact[]> {
19 const artifacts: CompilationArtifact[] = []; 49 const artifacts: CompilationArtifact[] = [];
20 50
21 try { 51 try {
22 await this.runCargo(cargoArgs, 52 await this.runCargo(spec.cargoArgs,
23 message => { 53 message => {
24 if (message.reason === 'compiler-artifact' && message.executable) { 54 if (message.reason === 'compiler-artifact' && message.executable) {
25 const isBinary = message.target.crate_types.includes('bin'); 55 const isBinary = message.target.crate_types.includes('bin');
@@ -43,30 +73,11 @@ export class Cargo {
43 throw new Error(`Cargo invocation has failed: ${err}`); 73 throw new Error(`Cargo invocation has failed: ${err}`);
44 } 74 }
45 75
46 return artifacts; 76 return spec.filter?.(artifacts) ?? artifacts;
47 } 77 }
48 78
49 async executableFromArgs(args: readonly string[]): Promise<string> { 79 async executableFromArgs(args: readonly string[]): Promise<string> {
50 const cargoArgs = [...args, "--message-format=json"]; 80 const artifacts = await this.getArtifacts(artifactSpec(args));
51
52 // arguments for a runnable from the quick pick should be updated.
53 // see crates\rust-analyzer\src\main_loop\handlers.rs, handle_code_lens
54 switch (cargoArgs[0]) {
55 case "run": cargoArgs[0] = "build"; break;
56 case "test": {
57 if (cargoArgs.indexOf("--no-run") === -1) {
58 cargoArgs.push("--no-run");
59 }
60 break;
61 }
62 }
63
64 let artifacts = await this.artifactsFromArgs(cargoArgs);
65 if (cargoArgs[0] === "test") {
66 // for instance, `crates\rust-analyzer\tests\heavy_tests\main.rs` tests
67 // produce 2 artifacts: {"kind": "bin"} and {"kind": "test"}
68 artifacts = artifacts.filter(a => a.isTest);
69 }
70 81
71 if (artifacts.length === 0) { 82 if (artifacts.length === 0) {
72 throw new Error('No compilation artifacts'); 83 throw new Error('No compilation artifacts');