diff options
Diffstat (limited to 'editors/code/src/cargo.ts')
-rw-r--r-- | editors/code/src/cargo.ts | 57 |
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 | ||
15 | export interface ArtifactSpec { | ||
16 | cargoArgs: string[]; | ||
17 | filter?: (artifacts: CompilationArtifact[]) => CompilationArtifact[]; | ||
18 | } | ||
19 | |||
20 | export 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 | |||
15 | export class Cargo { | 45 | export 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'); |