aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_lsp_server/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_lsp_server/src')
-rw-r--r--crates/ra_lsp_server/src/cargo_target_spec.rs100
-rw-r--r--crates/ra_lsp_server/src/lib.rs1
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs91
3 files changed, 102 insertions, 90 deletions
diff --git a/crates/ra_lsp_server/src/cargo_target_spec.rs b/crates/ra_lsp_server/src/cargo_target_spec.rs
new file mode 100644
index 000000000..a66f14b82
--- /dev/null
+++ b/crates/ra_lsp_server/src/cargo_target_spec.rs
@@ -0,0 +1,100 @@
1use crate::{
2 project_model::TargetKind,
3 server_world::ServerWorld,
4 Result
5};
6
7use ra_ide_api::{FileId, RunnableKind};
8
9pub(crate) fn runnable_args(
10 world: &ServerWorld,
11 file_id: FileId,
12 kind: &RunnableKind,
13) -> Result<Vec<String>> {
14 let spec = CargoTargetSpec::for_file(world, file_id)?;
15 let mut res = Vec::new();
16 match kind {
17 RunnableKind::Test { name } => {
18 res.push("test".to_string());
19 if let Some(spec) = spec {
20 spec.push_to(&mut res);
21 }
22 res.push("--".to_string());
23 res.push(name.to_string());
24 res.push("--nocapture".to_string());
25 }
26 RunnableKind::TestMod { path } => {
27 res.push("test".to_string());
28 if let Some(spec) = spec {
29 spec.push_to(&mut res);
30 }
31 res.push("--".to_string());
32 res.push(path.to_string());
33 res.push("--nocapture".to_string());
34 }
35 RunnableKind::Bin => {
36 res.push("run".to_string());
37 if let Some(spec) = spec {
38 spec.push_to(&mut res);
39 }
40 }
41 }
42 Ok(res)
43}
44
45pub struct CargoTargetSpec {
46 pub package: String,
47 pub target: String,
48 pub target_kind: TargetKind,
49}
50
51impl CargoTargetSpec {
52 pub fn for_file(world: &ServerWorld, file_id: FileId) -> Result<Option<CargoTargetSpec>> {
53 let &crate_id = match world.analysis().crate_for(file_id)?.first() {
54 Some(crate_id) => crate_id,
55 None => return Ok(None),
56 };
57 let file_id = world.analysis().crate_root(crate_id)?;
58 let path = world
59 .vfs
60 .read()
61 .file2path(ra_vfs::VfsFile(file_id.0.into()));
62 let res = world.workspaces.iter().find_map(|ws| {
63 let tgt = ws.cargo.target_by_root(&path)?;
64 let res = CargoTargetSpec {
65 package: tgt.package(&ws.cargo).name(&ws.cargo).to_string(),
66 target: tgt.name(&ws.cargo).to_string(),
67 target_kind: tgt.kind(&ws.cargo),
68 };
69 Some(res)
70 });
71 Ok(res)
72 }
73
74 pub fn push_to(self, buf: &mut Vec<String>) {
75 buf.push("--package".to_string());
76 buf.push(self.package);
77 match self.target_kind {
78 TargetKind::Bin => {
79 buf.push("--bin".to_string());
80 buf.push(self.target);
81 }
82 TargetKind::Test => {
83 buf.push("--test".to_string());
84 buf.push(self.target);
85 }
86 TargetKind::Bench => {
87 buf.push("--bench".to_string());
88 buf.push(self.target);
89 }
90 TargetKind::Example => {
91 buf.push("--example".to_string());
92 buf.push(self.target);
93 }
94 TargetKind::Lib => {
95 buf.push("--lib".to_string());
96 }
97 TargetKind::Other => (),
98 }
99 }
100}
diff --git a/crates/ra_lsp_server/src/lib.rs b/crates/ra_lsp_server/src/lib.rs
index 725b1258a..f93d4b37d 100644
--- a/crates/ra_lsp_server/src/lib.rs
+++ b/crates/ra_lsp_server/src/lib.rs
@@ -1,4 +1,5 @@
1mod caps; 1mod caps;
2mod cargo_target_spec;
2mod conv; 3mod conv;
3mod main_loop; 4mod main_loop;
4mod project_model; 5mod project_model;
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index f881bd703..7f6146b6c 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -17,8 +17,8 @@ use serde_json::to_value;
17use std::io::Write; 17use std::io::Write;
18 18
19use crate::{ 19use crate::{
20 cargo_target_spec::{CargoTargetSpec, runnable_args},
20 conv::{to_location, to_location_link, Conv, ConvWith, MapConvWith, TryConvWith}, 21 conv::{to_location, to_location_link, Conv, ConvWith, MapConvWith, TryConvWith},
21 project_model::TargetKind,
22 req::{self, Decoration}, 22 req::{self, Decoration},
23 server_world::ServerWorld, 23 server_world::ServerWorld,
24 LspError, Result, 24 LspError, Result,
@@ -293,95 +293,6 @@ pub fn handle_runnables(
293 return Ok(res); 293 return Ok(res);
294} 294}
295 295
296fn runnable_args(world: &ServerWorld, file_id: FileId, kind: &RunnableKind) -> Result<Vec<String>> {
297 let spec = CargoTargetSpec::for_file(world, file_id)?;
298 let mut res = Vec::new();
299 match kind {
300 RunnableKind::Test { name } => {
301 res.push("test".to_string());
302 if let Some(spec) = spec {
303 spec.push_to(&mut res);
304 }
305 res.push("--".to_string());
306 res.push(name.to_string());
307 res.push("--nocapture".to_string());
308 }
309 RunnableKind::TestMod { path } => {
310 res.push("test".to_string());
311 if let Some(spec) = spec {
312 spec.push_to(&mut res);
313 }
314 res.push("--".to_string());
315 res.push(path.to_string());
316 res.push("--nocapture".to_string());
317 }
318 RunnableKind::Bin => {
319 res.push("run".to_string());
320 if let Some(spec) = spec {
321 spec.push_to(&mut res);
322 }
323 }
324 }
325 Ok(res)
326}
327
328struct CargoTargetSpec {
329 package: String,
330 target: String,
331 target_kind: TargetKind,
332}
333
334impl CargoTargetSpec {
335 fn for_file(world: &ServerWorld, file_id: FileId) -> Result<Option<CargoTargetSpec>> {
336 let &crate_id = match world.analysis().crate_for(file_id)?.first() {
337 Some(crate_id) => crate_id,
338 None => return Ok(None),
339 };
340 let file_id = world.analysis().crate_root(crate_id)?;
341 let path = world
342 .vfs
343 .read()
344 .file2path(ra_vfs::VfsFile(file_id.0.into()));
345 let res = world.workspaces.iter().find_map(|ws| {
346 let tgt = ws.cargo.target_by_root(&path)?;
347 let res = CargoTargetSpec {
348 package: tgt.package(&ws.cargo).name(&ws.cargo).to_string(),
349 target: tgt.name(&ws.cargo).to_string(),
350 target_kind: tgt.kind(&ws.cargo),
351 };
352 Some(res)
353 });
354 Ok(res)
355 }
356
357 fn push_to(self, buf: &mut Vec<String>) {
358 buf.push("--package".to_string());
359 buf.push(self.package);
360 match self.target_kind {
361 TargetKind::Bin => {
362 buf.push("--bin".to_string());
363 buf.push(self.target);
364 }
365 TargetKind::Test => {
366 buf.push("--test".to_string());
367 buf.push(self.target);
368 }
369 TargetKind::Bench => {
370 buf.push("--bench".to_string());
371 buf.push(self.target);
372 }
373 TargetKind::Example => {
374 buf.push("--example".to_string());
375 buf.push(self.target);
376 }
377 TargetKind::Lib => {
378 buf.push("--lib".to_string());
379 }
380 TargetKind::Other => (),
381 }
382 }
383}
384
385pub fn handle_decorations( 296pub fn handle_decorations(
386 world: ServerWorld, 297 world: ServerWorld,
387 params: TextDocumentIdentifier, 298 params: TextDocumentIdentifier,