aboutsummaryrefslogtreecommitdiff
path: root/crates/server/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/server/src')
-rw-r--r--crates/server/src/main_loop/handlers.rs76
-rw-r--r--crates/server/src/project_model.rs4
-rw-r--r--crates/server/src/server_world.rs17
3 files changed, 83 insertions, 14 deletions
diff --git a/crates/server/src/main_loop/handlers.rs b/crates/server/src/main_loop/handlers.rs
index ab8b6f799..93d8bd9fe 100644
--- a/crates/server/src/main_loop/handlers.rs
+++ b/crates/server/src/main_loop/handlers.rs
@@ -16,6 +16,7 @@ use ::{
16 req::{self, Decoration}, Result, 16 req::{self, Decoration}, Result,
17 conv::{Conv, ConvWith, TryConvWith, MapConvWith, to_location}, 17 conv::{Conv, ConvWith, TryConvWith, MapConvWith, to_location},
18 server_world::ServerWorld, 18 server_world::ServerWorld,
19 project_model::TargetKind,
19}; 20};
20 21
21pub fn handle_syntax_tree( 22pub fn handle_syntax_tree(
@@ -233,6 +234,8 @@ pub fn handle_runnables(
233 } 234 }
234 } 235 }
235 236
237 let args = runnable_args(&world, file_id, &runnable.kind);
238
236 let r = req::Runnable { 239 let r = req::Runnable {
237 range: runnable.range.conv_with(&line_index), 240 range: runnable.range.conv_with(&line_index),
238 label: match &runnable.kind { 241 label: match &runnable.kind {
@@ -242,17 +245,7 @@ pub fn handle_runnables(
242 "run binary".to_string(), 245 "run binary".to_string(),
243 }, 246 },
244 bin: "cargo".to_string(), 247 bin: "cargo".to_string(),
245 args: match runnable.kind { 248 args,
246 RunnableKind::Test { name } => {
247 vec![
248 "test".to_string(),
249 "--".to_string(),
250 name,
251 "--nocapture".to_string(),
252 ]
253 }
254 RunnableKind::Bin => vec!["run".to_string()]
255 },
256 env: { 249 env: {
257 let mut m = HashMap::new(); 250 let mut m = HashMap::new();
258 m.insert( 251 m.insert(
@@ -265,6 +258,67 @@ pub fn handle_runnables(
265 res.push(r); 258 res.push(r);
266 } 259 }
267 return Ok(res); 260 return Ok(res);
261
262 fn runnable_args(world: &ServerWorld, file_id: FileId, kind: &RunnableKind) -> Vec<String> {
263 let spec = if let Some(&crate_id) = world.analysis().crate_for(file_id).first() {
264 let file_id = world.analysis().crate_root(crate_id);
265 let path = world.path_map.get_path(file_id);
266 world.workspaces.iter()
267 .filter_map(|ws| {
268 let tgt = ws.target_by_root(path)?;
269 Some((tgt.package(ws).name(ws).clone(), tgt.name(ws).clone(), tgt.kind(ws)))
270 })
271 .next()
272 } else {
273 None
274 };
275 let mut res = Vec::new();
276 match kind {
277 RunnableKind::Test { name } => {
278 res.push("test".to_string());
279 if let Some((pkg_name, tgt_name, tgt_kind)) = spec {
280 spec_args(pkg_name, tgt_name, tgt_kind, &mut res);
281 }
282 res.push("--".to_string());
283 res.push(name.to_string());
284 res.push("--nocapture".to_string());
285 }
286 RunnableKind::Bin => {
287 res.push("run".to_string());
288 if let Some((pkg_name, tgt_name, tgt_kind)) = spec {
289 spec_args(pkg_name, tgt_name, tgt_kind, &mut res);
290 }
291 }
292 }
293 res
294 }
295
296 fn spec_args(pkg_name: &str, tgt_name: &str, tgt_kind: TargetKind, buf: &mut Vec<String>) {
297 buf.push("--package".to_string());
298 buf.push(pkg_name.to_string());
299 match tgt_kind {
300 TargetKind::Bin => {
301 buf.push("--bin".to_string());
302 buf.push(tgt_name.to_string());
303 }
304 TargetKind::Test => {
305 buf.push("--test".to_string());
306 buf.push(tgt_name.to_string());
307 }
308 TargetKind::Bench => {
309 buf.push("--bench".to_string());
310 buf.push(tgt_name.to_string());
311 }
312 TargetKind::Example => {
313 buf.push("--example".to_string());
314 buf.push(tgt_name.to_string());
315 }
316 TargetKind::Lib => {
317 buf.push("--lib".to_string());
318 }
319 TargetKind::Other => (),
320 }
321 }
268} 322}
269 323
270pub fn handle_decorations( 324pub fn handle_decorations(
diff --git a/crates/server/src/project_model.rs b/crates/server/src/project_model.rs
index 1c5954dad..12233f258 100644
--- a/crates/server/src/project_model.rs
+++ b/crates/server/src/project_model.rs
@@ -56,7 +56,7 @@ impl Package {
56} 56}
57 57
58impl Target { 58impl Target {
59 pub fn pkg(self, ws: &CargoWorkspace) -> Package { 59 pub fn package(self, ws: &CargoWorkspace) -> Package {
60 ws.tgt(self).pkg 60 ws.tgt(self).pkg
61 } 61 }
62 pub fn name(self, ws: &CargoWorkspace) -> &str { 62 pub fn name(self, ws: &CargoWorkspace) -> &str {
@@ -114,7 +114,7 @@ impl CargoWorkspace {
114 pub fn ws_members<'a>(&'a self) -> impl Iterator<Item=Package> + 'a { 114 pub fn ws_members<'a>(&'a self) -> impl Iterator<Item=Package> + 'a {
115 self.ws_members.iter().cloned() 115 self.ws_members.iter().cloned()
116 } 116 }
117 pub fn target_by_roo(&self, root: &Path) -> Option<Target> { 117 pub fn target_by_root(&self, root: &Path) -> Option<Target> {
118 self.packages() 118 self.packages()
119 .filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root)) 119 .filter_map(|pkg| pkg.targets(self).find(|it| it.root(self) == root))
120 .next() 120 .next()
diff --git a/crates/server/src/server_world.rs b/crates/server/src/server_world.rs
index 4d5c50428..f78b56cf8 100644
--- a/crates/server/src/server_world.rs
+++ b/crates/server/src/server_world.rs
@@ -6,7 +6,7 @@ use std::{
6}; 6};
7 7
8use languageserver_types::Url; 8use languageserver_types::Url;
9use libanalysis::{FileId, AnalysisHost, Analysis}; 9use libanalysis::{FileId, AnalysisHost, Analysis, CrateGraph, CrateId};
10 10
11use { 11use {
12 Result, 12 Result,
@@ -95,7 +95,22 @@ impl ServerWorldState {
95 Ok(file_id) 95 Ok(file_id)
96 } 96 }
97 pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) { 97 pub fn set_workspaces(&mut self, ws: Vec<CargoWorkspace>) {
98 let mut crate_roots = HashMap::new();
99 ws.iter()
100 .flat_map(|ws| {
101 ws.packages()
102 .flat_map(move |pkg| pkg.targets(ws))
103 .map(move |tgt| tgt.root(ws))
104 })
105 .for_each(|root| {
106 if let Some(file_id) = self.path_map.get_id(root) {
107 let crate_id = CrateId(crate_roots.len() as u32);
108 crate_roots.insert(crate_id, file_id);
109 }
110 });
111 let crate_graph = CrateGraph { crate_roots };
98 self.workspaces = Arc::new(ws); 112 self.workspaces = Arc::new(ws);
113 self.analysis_host.set_crate_graph(crate_graph);
99 } 114 }
100 pub fn snapshot(&self) -> ServerWorld { 115 pub fn snapshot(&self) -> ServerWorld {
101 ServerWorld { 116 ServerWorld {