diff options
Diffstat (limited to 'editors/code/src/cargo.ts')
-rw-r--r-- | editors/code/src/cargo.ts | 53 |
1 files changed, 34 insertions, 19 deletions
diff --git a/editors/code/src/cargo.ts b/editors/code/src/cargo.ts index 28c7de992..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,26 +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 | if (cargoArgs[0] === "run") { | ||
55 | cargoArgs[0] = "build"; | ||
56 | } else if (cargoArgs.indexOf("--no-run") === -1) { | ||
57 | cargoArgs.push("--no-run"); | ||
58 | } | ||
59 | |||
60 | let artifacts = await this.artifactsFromArgs(cargoArgs); | ||
61 | if (cargoArgs[0] === "test") { | ||
62 | // for instance, `crates\rust-analyzer\tests\heavy_tests\main.rs` tests | ||
63 | // produce 2 artifacts: {"kind": "bin"} and {"kind": "test"} | ||
64 | artifacts = artifacts.filter(a => a.isTest); | ||
65 | } | ||
66 | 81 | ||
67 | if (artifacts.length === 0) { | 82 | if (artifacts.length === 0) { |
68 | throw new Error('No compilation artifacts'); | 83 | throw new Error('No compilation artifacts'); |