diff options
Diffstat (limited to 'crates/server')
-rw-r--r-- | crates/server/src/main_loop/handlers.rs | 76 | ||||
-rw-r--r-- | crates/server/src/project_model.rs | 4 | ||||
-rw-r--r-- | crates/server/src/server_world.rs | 17 | ||||
-rw-r--r-- | crates/server/tests/heavy_tests/main.rs | 40 | ||||
-rw-r--r-- | crates/server/tests/heavy_tests/support.rs | 13 |
5 files changed, 131 insertions, 19 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 | ||
21 | pub fn handle_syntax_tree( | 22 | pub 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 | ||
270 | pub fn handle_decorations( | 324 | pub 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 | ||
58 | impl Target { | 58 | impl 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 | ||
8 | use languageserver_types::Url; | 8 | use languageserver_types::Url; |
9 | use libanalysis::{FileId, AnalysisHost, Analysis}; | 9 | use libanalysis::{FileId, AnalysisHost, Analysis, CrateGraph, CrateId}; |
10 | 10 | ||
11 | use { | 11 | use { |
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 { |
diff --git a/crates/server/tests/heavy_tests/main.rs b/crates/server/tests/heavy_tests/main.rs index 9c0196f22..0dc6074b2 100644 --- a/crates/server/tests/heavy_tests/main.rs +++ b/crates/server/tests/heavy_tests/main.rs | |||
@@ -14,10 +14,10 @@ use m::req::{Runnables, RunnablesParams, DidReloadWorkspace}; | |||
14 | 14 | ||
15 | use support::project; | 15 | use support::project; |
16 | 16 | ||
17 | const LOG: &'static str = "WARN"; | 17 | const LOG: &'static str = ""; |
18 | 18 | ||
19 | #[test] | 19 | #[test] |
20 | fn test_runnables() { | 20 | fn test_runnables_no_project() { |
21 | let server = project(r" | 21 | let server = project(r" |
22 | //- lib.rs | 22 | //- lib.rs |
23 | #[test] | 23 | #[test] |
@@ -45,6 +45,42 @@ fn foo() { | |||
45 | } | 45 | } |
46 | 46 | ||
47 | #[test] | 47 | #[test] |
48 | fn test_runnables_project() { | ||
49 | let server = project(r#" | ||
50 | //- Cargo.toml | ||
51 | [package] | ||
52 | name = "foo" | ||
53 | version = "0.0.0" | ||
54 | |||
55 | //- src/lib.rs | ||
56 | pub fn foo() {} | ||
57 | |||
58 | //- tests/spam.rs | ||
59 | #[test] | ||
60 | fn test_eggs() {} | ||
61 | "#); | ||
62 | server.wait_for_notification::<DidReloadWorkspace>(); | ||
63 | server.request::<Runnables>( | ||
64 | RunnablesParams { | ||
65 | text_document: server.doc_id("tests/spam.rs"), | ||
66 | position: None, | ||
67 | }, | ||
68 | r#"[ | ||
69 | { | ||
70 | "args": [ "test", "--package", "foo", "--test", "spam", "--", "test_eggs", "--nocapture" ], | ||
71 | "bin": "cargo", | ||
72 | "env": { "RUST_BACKTRACE": "short" }, | ||
73 | "label": "test test_eggs", | ||
74 | "range": { | ||
75 | "end": { "character": 17, "line": 1 }, | ||
76 | "start": { "character": 0, "line": 0 } | ||
77 | } | ||
78 | } | ||
79 | ]"# | ||
80 | ); | ||
81 | } | ||
82 | |||
83 | #[test] | ||
48 | fn test_project_model() { | 84 | fn test_project_model() { |
49 | let server = project(r#" | 85 | let server = project(r#" |
50 | //- Cargo.toml | 86 | //- Cargo.toml |
diff --git a/crates/server/tests/heavy_tests/support.rs b/crates/server/tests/heavy_tests/support.rs index 76cbd56ea..38a9e6c76 100644 --- a/crates/server/tests/heavy_tests/support.rs +++ b/crates/server/tests/heavy_tests/support.rs | |||
@@ -134,7 +134,7 @@ impl Server { | |||
134 | { | 134 | { |
135 | let expected = expected.replace("$PROJECT_ROOT$", &self.dir.path().display().to_string()); | 135 | let expected = expected.replace("$PROJECT_ROOT$", &self.dir.path().display().to_string()); |
136 | let expected: Value = from_str(&expected).unwrap(); | 136 | let expected: Value = from_str(&expected).unwrap(); |
137 | let actual = self.wait_for_notification(N::METHOD); | 137 | let actual = self.wait_for_notification::<N>(); |
138 | assert_eq!( | 138 | assert_eq!( |
139 | expected, actual, | 139 | expected, actual, |
140 | "Expected:\n{}\n\ | 140 | "Expected:\n{}\n\ |
@@ -150,6 +150,11 @@ impl Server { | |||
150 | R::Params: Serialize, | 150 | R::Params: Serialize, |
151 | { | 151 | { |
152 | let r = RawRequest::new::<R>(id, ¶ms); | 152 | let r = RawRequest::new::<R>(id, ¶ms); |
153 | self.send_request_(r) | ||
154 | } | ||
155 | fn send_request_(&self, r: RawRequest) -> Value | ||
156 | { | ||
157 | let id = r.id; | ||
153 | self.sender.as_ref() | 158 | self.sender.as_ref() |
154 | .unwrap() | 159 | .unwrap() |
155 | .send(RawMessage::Request(r)); | 160 | .send(RawMessage::Request(r)); |
@@ -168,7 +173,10 @@ impl Server { | |||
168 | } | 173 | } |
169 | panic!("no response"); | 174 | panic!("no response"); |
170 | } | 175 | } |
171 | fn wait_for_notification(&self, method: &str) -> Value { | 176 | pub fn wait_for_notification<N: Notification>(&self) -> Value { |
177 | self.wait_for_notification_(N::METHOD) | ||
178 | } | ||
179 | fn wait_for_notification_(&self, method: &str) -> Value { | ||
172 | let f = |msg: &RawMessage| match msg { | 180 | let f = |msg: &RawMessage| match msg { |
173 | RawMessage::Notification(n) if n.method == method => { | 181 | RawMessage::Notification(n) if n.method == method => { |
174 | Some(n.params.clone()) | 182 | Some(n.params.clone()) |
@@ -215,7 +223,6 @@ impl Drop for Server { | |||
215 | drop(msg); | 223 | drop(msg); |
216 | } | 224 | } |
217 | } | 225 | } |
218 | eprintln!("joining server"); | ||
219 | self.server.take() | 226 | self.server.take() |
220 | .unwrap() | 227 | .unwrap() |
221 | .join().unwrap().unwrap(); | 228 | .join().unwrap().unwrap(); |