diff options
author | Aleksey Kladov <[email protected]> | 2018-09-02 14:36:03 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-09-02 14:36:03 +0100 |
commit | e98d8cd255ab5c2fee873a58af6c2c3ad561dab4 (patch) | |
tree | 04869b8fe93e724d8aa266177e48644051331ab9 | |
parent | 1329dd4e287c137ec0a90abeec0272275b2b2c8d (diff) |
nail down runnables
-rw-r--r-- | crates/libanalysis/src/imp.rs | 6 | ||||
-rw-r--r-- | crates/libanalysis/src/lib.rs | 7 | ||||
-rw-r--r-- | crates/libanalysis/tests/tests.rs | 4 | ||||
-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 |
8 files changed, 142 insertions, 25 deletions
diff --git a/crates/libanalysis/src/imp.rs b/crates/libanalysis/src/imp.rs index f1d72da15..b80ce1ab5 100644 --- a/crates/libanalysis/src/imp.rs +++ b/crates/libanalysis/src/imp.rs | |||
@@ -151,7 +151,7 @@ impl AnalysisImpl { | |||
151 | .collect() | 151 | .collect() |
152 | } | 152 | } |
153 | 153 | ||
154 | pub fn crate_root(&self, id: FileId) -> Vec<CrateId> { | 154 | pub fn crate_for(&self, id: FileId) -> Vec<CrateId> { |
155 | let module_map = &self.data.module_map; | 155 | let module_map = &self.data.module_map; |
156 | let crate_graph = &self.data.crate_graph; | 156 | let crate_graph = &self.data.crate_graph; |
157 | let mut res = Vec::new(); | 157 | let mut res = Vec::new(); |
@@ -177,7 +177,9 @@ impl AnalysisImpl { | |||
177 | } | 177 | } |
178 | res | 178 | res |
179 | } | 179 | } |
180 | 180 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { | |
181 | self.data.crate_graph.crate_roots[&crate_id] | ||
182 | } | ||
181 | pub fn approximately_resolve_symbol( | 183 | pub fn approximately_resolve_symbol( |
182 | &self, | 184 | &self, |
183 | id: FileId, | 185 | id: FileId, |
diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index 041abbb89..ba290f1e0 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs | |||
@@ -182,8 +182,11 @@ impl Analysis { | |||
182 | pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { | 182 | pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { |
183 | self.imp.parent_module(file_id) | 183 | self.imp.parent_module(file_id) |
184 | } | 184 | } |
185 | pub fn crate_root(&self, file_id: FileId) -> Vec<CrateId> { | 185 | pub fn crate_for(&self, file_id: FileId) -> Vec<CrateId> { |
186 | self.imp.crate_root(file_id) | 186 | self.imp.crate_for(file_id) |
187 | } | ||
188 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { | ||
189 | self.imp.crate_root(crate_id) | ||
187 | } | 190 | } |
188 | pub fn runnables(&self, file_id: FileId) -> Vec<Runnable> { | 191 | pub fn runnables(&self, file_id: FileId) -> Vec<Runnable> { |
189 | let file = self.file_syntax(file_id); | 192 | let file = self.file_syntax(file_id); |
diff --git a/crates/libanalysis/tests/tests.rs b/crates/libanalysis/tests/tests.rs index c098c8e8c..4fae7c313 100644 --- a/crates/libanalysis/tests/tests.rs +++ b/crates/libanalysis/tests/tests.rs | |||
@@ -126,7 +126,7 @@ fn test_resolve_crate_root() { | |||
126 | (1, "/lib.rs"), | 126 | (1, "/lib.rs"), |
127 | (2, "/foo.rs"), | 127 | (2, "/foo.rs"), |
128 | ])); | 128 | ])); |
129 | assert!(snap.crate_root(FileId(2)).is_empty()); | 129 | assert!(snap.crate_for(FileId(2)).is_empty()); |
130 | 130 | ||
131 | let crate_graph = CrateGraph { | 131 | let crate_graph = CrateGraph { |
132 | crate_roots: { | 132 | crate_roots: { |
@@ -142,7 +142,7 @@ fn test_resolve_crate_root() { | |||
142 | (2, "/foo.rs"), | 142 | (2, "/foo.rs"), |
143 | ])); | 143 | ])); |
144 | assert_eq!( | 144 | assert_eq!( |
145 | snap.crate_root(FileId(2)), | 145 | snap.crate_for(FileId(2)), |
146 | vec![CrateId(1)], | 146 | vec![CrateId(1)], |
147 | ); | 147 | ); |
148 | } | 148 | } |
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(); |