diff options
-rw-r--r-- | crates/server/src/main.rs | 2 | ||||
-rw-r--r-- | crates/server/src/main_loop/mod.rs | 14 | ||||
-rw-r--r-- | crates/server/src/project_model.rs | 11 | ||||
-rw-r--r-- | crates/server/src/req.rs | 9 | ||||
-rw-r--r-- | crates/server/tests/heavy_tests/main.rs | 33 | ||||
-rw-r--r-- | crates/server/tests/heavy_tests/support.rs | 45 |
6 files changed, 35 insertions, 79 deletions
diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs index 119f020d3..5c0166a61 100644 --- a/crates/server/src/main.rs +++ b/crates/server/src/main.rs | |||
@@ -34,7 +34,7 @@ fn main_inner() -> Result<()> { | |||
34 | let root = ::std::env::current_dir()?; | 34 | let root = ::std::env::current_dir()?; |
35 | run_server( | 35 | run_server( |
36 | m::server_capabilities(), | 36 | m::server_capabilities(), |
37 | |r, s| m::main_loop(root, r, s), | 37 | |r, s| m::main_loop(false, root, r, s), |
38 | receiver, | 38 | receiver, |
39 | sender, | 39 | sender, |
40 | )?; | 40 | )?; |
diff --git a/crates/server/src/main_loop/mod.rs b/crates/server/src/main_loop/mod.rs index 3d131274f..b66a24de1 100644 --- a/crates/server/src/main_loop/mod.rs +++ b/crates/server/src/main_loop/mod.rs | |||
@@ -32,6 +32,7 @@ enum Task { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | pub fn main_loop( | 34 | pub fn main_loop( |
35 | internal_mode: bool, | ||
35 | root: PathBuf, | 36 | root: PathBuf, |
36 | msg_receriver: &mut Receiver<RawMessage>, | 37 | msg_receriver: &mut Receiver<RawMessage>, |
37 | msg_sender: &mut Sender<RawMessage>, | 38 | msg_sender: &mut Sender<RawMessage>, |
@@ -47,6 +48,7 @@ pub fn main_loop( | |||
47 | let mut pending_requests = HashMap::new(); | 48 | let mut pending_requests = HashMap::new(); |
48 | let mut subs = Subscriptions::new(); | 49 | let mut subs = Subscriptions::new(); |
49 | let main_res = main_loop_inner( | 50 | let main_res = main_loop_inner( |
51 | internal_mode, | ||
50 | root, | 52 | root, |
51 | &pool, | 53 | &pool, |
52 | msg_sender, | 54 | msg_sender, |
@@ -80,6 +82,7 @@ pub fn main_loop( | |||
80 | } | 82 | } |
81 | 83 | ||
82 | fn main_loop_inner( | 84 | fn main_loop_inner( |
85 | internal_mode: bool, | ||
83 | ws_root: PathBuf, | 86 | ws_root: PathBuf, |
84 | pool: &ThreadPool, | 87 | pool: &ThreadPool, |
85 | msg_sender: &mut Sender<RawMessage>, | 88 | msg_sender: &mut Sender<RawMessage>, |
@@ -145,8 +148,7 @@ fn main_loop_inner( | |||
145 | match ws { | 148 | match ws { |
146 | Ok(ws) => { | 149 | Ok(ws) => { |
147 | let workspaces = vec![ws]; | 150 | let workspaces = vec![ws]; |
148 | let not = RawNotification::new::<req::DidReloadWorkspace>(&workspaces); | 151 | feedback(internal_mode, "workspace loaded", msg_sender); |
149 | msg_sender.send(RawMessage::Notification(not)); | ||
150 | for ws in workspaces.iter() { | 152 | for ws in workspaces.iter() { |
151 | for pkg in ws.packages().filter(|pkg| !pkg.is_member(ws)) { | 153 | for pkg in ws.packages().filter(|pkg| !pkg.is_member(ws)) { |
152 | debug!("sending root, {}", pkg.root(ws).to_path_buf().display()); | 154 | debug!("sending root, {}", pkg.root(ws).to_path_buf().display()); |
@@ -404,3 +406,11 @@ fn update_file_notifications_on_threadpool( | |||
404 | } | 406 | } |
405 | }); | 407 | }); |
406 | } | 408 | } |
409 | |||
410 | fn feedback(intrnal_mode: bool, msg: &str, sender: &Sender<RawMessage>) { | ||
411 | if !intrnal_mode { | ||
412 | return; | ||
413 | } | ||
414 | let not = RawNotification::new::<req::InternalFeedback>(&msg.to_string()); | ||
415 | sender.send(RawMessage::Notification(not)); | ||
416 | } | ||
diff --git a/crates/server/src/project_model.rs b/crates/server/src/project_model.rs index 517836e62..a712106d9 100644 --- a/crates/server/src/project_model.rs +++ b/crates/server/src/project_model.rs | |||
@@ -11,7 +11,7 @@ use { | |||
11 | thread_watcher::ThreadWatcher, | 11 | thread_watcher::ThreadWatcher, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | #[derive(Debug, Serialize, Clone)] | 14 | #[derive(Debug, Clone)] |
15 | pub struct CargoWorkspace { | 15 | pub struct CargoWorkspace { |
16 | packages: Vec<PackageData>, | 16 | packages: Vec<PackageData>, |
17 | targets: Vec<TargetData>, | 17 | targets: Vec<TargetData>, |
@@ -22,7 +22,7 @@ pub struct Package(usize); | |||
22 | #[derive(Clone, Copy, Debug, Serialize)] | 22 | #[derive(Clone, Copy, Debug, Serialize)] |
23 | pub struct Target(usize); | 23 | pub struct Target(usize); |
24 | 24 | ||
25 | #[derive(Debug, Serialize, Clone)] | 25 | #[derive(Debug, Clone)] |
26 | struct PackageData { | 26 | struct PackageData { |
27 | name: SmolStr, | 27 | name: SmolStr, |
28 | manifest: PathBuf, | 28 | manifest: PathBuf, |
@@ -30,7 +30,7 @@ struct PackageData { | |||
30 | is_member: bool, | 30 | is_member: bool, |
31 | } | 31 | } |
32 | 32 | ||
33 | #[derive(Debug, Serialize, Clone)] | 33 | #[derive(Debug, Clone)] |
34 | struct TargetData { | 34 | struct TargetData { |
35 | pkg: Package, | 35 | pkg: Package, |
36 | name: SmolStr, | 36 | name: SmolStr, |
@@ -38,7 +38,7 @@ struct TargetData { | |||
38 | kind: TargetKind, | 38 | kind: TargetKind, |
39 | } | 39 | } |
40 | 40 | ||
41 | #[derive(Debug, Serialize, Clone, Copy, PartialEq, Eq)] | 41 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
42 | pub enum TargetKind { | 42 | pub enum TargetKind { |
43 | Bin, Lib, Example, Test, Bench, Other, | 43 | Bin, Lib, Example, Test, Bench, Other, |
44 | } | 44 | } |
@@ -47,9 +47,6 @@ impl Package { | |||
47 | pub fn name(self, ws: &CargoWorkspace) -> &str { | 47 | pub fn name(self, ws: &CargoWorkspace) -> &str { |
48 | ws.pkg(self).name.as_str() | 48 | ws.pkg(self).name.as_str() |
49 | } | 49 | } |
50 | pub fn manifest(self, ws: &CargoWorkspace) -> &Path { | ||
51 | ws.pkg(self).manifest.as_path() | ||
52 | } | ||
53 | pub fn root(self, ws: &CargoWorkspace) -> &Path { | 50 | pub fn root(self, ws: &CargoWorkspace) -> &Path { |
54 | ws.pkg(self).manifest.parent().unwrap() | 51 | ws.pkg(self).manifest.parent().unwrap() |
55 | } | 52 | } |
diff --git a/crates/server/src/req.rs b/crates/server/src/req.rs index b9e0c3796..4af61dbbd 100644 --- a/crates/server/src/req.rs +++ b/crates/server/src/req.rs | |||
@@ -1,7 +1,6 @@ | |||
1 | use std::collections::HashMap; | 1 | use std::collections::HashMap; |
2 | use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location}; | 2 | use languageserver_types::{TextDocumentIdentifier, Range, Url, Position, Location}; |
3 | use url_serde; | 3 | use url_serde; |
4 | use project_model::CargoWorkspace; | ||
5 | 4 | ||
6 | pub use languageserver_types::{ | 5 | pub use languageserver_types::{ |
7 | request::*, notification::*, | 6 | request::*, notification::*, |
@@ -169,9 +168,9 @@ pub enum FileSystemEdit { | |||
169 | } | 168 | } |
170 | } | 169 | } |
171 | 170 | ||
172 | pub enum DidReloadWorkspace {} | 171 | pub enum InternalFeedback {} |
173 | 172 | ||
174 | impl Notification for DidReloadWorkspace { | 173 | impl Notification for InternalFeedback { |
175 | const METHOD: &'static str = "m/didReloadWorkspace"; | 174 | const METHOD: &'static str = "internalFeedback"; |
176 | type Params = Vec<CargoWorkspace>; | 175 | type Params = String; |
177 | } | 176 | } |
diff --git a/crates/server/tests/heavy_tests/main.rs b/crates/server/tests/heavy_tests/main.rs index 78842e44f..d6e89bdf2 100644 --- a/crates/server/tests/heavy_tests/main.rs +++ b/crates/server/tests/heavy_tests/main.rs | |||
@@ -10,7 +10,7 @@ extern crate m; | |||
10 | 10 | ||
11 | mod support; | 11 | mod support; |
12 | 12 | ||
13 | use m::req::{Runnables, RunnablesParams, DidReloadWorkspace}; | 13 | use m::req::{Runnables, RunnablesParams}; |
14 | 14 | ||
15 | use support::project; | 15 | use support::project; |
16 | 16 | ||
@@ -59,7 +59,7 @@ pub fn foo() {} | |||
59 | #[test] | 59 | #[test] |
60 | fn test_eggs() {} | 60 | fn test_eggs() {} |
61 | "#); | 61 | "#); |
62 | server.wait_for_notification::<DidReloadWorkspace>(); | 62 | server.wait_for_feedback("workspace loaded"); |
63 | server.request::<Runnables>( | 63 | server.request::<Runnables>( |
64 | RunnablesParams { | 64 | RunnablesParams { |
65 | text_document: server.doc_id("tests/spam.rs"), | 65 | text_document: server.doc_id("tests/spam.rs"), |
@@ -79,32 +79,3 @@ fn test_eggs() {} | |||
79 | ]"# | 79 | ]"# |
80 | ); | 80 | ); |
81 | } | 81 | } |
82 | |||
83 | #[test] | ||
84 | fn test_project_model() { | ||
85 | let server = project(r#" | ||
86 | //- Cargo.toml | ||
87 | [package] | ||
88 | name = "foo" | ||
89 | version = "0.0.0" | ||
90 | |||
91 | //- src/lib.rs | ||
92 | pub fn foo() {} | ||
93 | "#); | ||
94 | server.notification::<DidReloadWorkspace>(r#"[ | ||
95 | { | ||
96 | "packages": [ | ||
97 | { | ||
98 | "is_member": true, | ||
99 | "manifest": "$PROJECT_ROOT$/Cargo.toml", | ||
100 | "name": "foo", | ||
101 | "targets": [ 0 ] | ||
102 | } | ||
103 | ], | ||
104 | "targets": [ | ||
105 | { "kind": "Lib", "name": "foo", "pkg": 0, "root": "$PROJECT_ROOT$/src/lib.rs" } | ||
106 | ] | ||
107 | } | ||
108 | ]"# | ||
109 | ); | ||
110 | } | ||
diff --git a/crates/server/tests/heavy_tests/support.rs b/crates/server/tests/heavy_tests/support.rs index 38a9e6c76..99a784e8d 100644 --- a/crates/server/tests/heavy_tests/support.rs +++ b/crates/server/tests/heavy_tests/support.rs | |||
@@ -14,7 +14,7 @@ use languageserver_types::{ | |||
14 | Url, | 14 | Url, |
15 | TextDocumentIdentifier, | 15 | TextDocumentIdentifier, |
16 | request::{Request, Shutdown}, | 16 | request::{Request, Shutdown}, |
17 | notification::{Notification, DidOpenTextDocument}, | 17 | notification::DidOpenTextDocument, |
18 | DidOpenTextDocumentParams, | 18 | DidOpenTextDocumentParams, |
19 | TextDocumentItem, | 19 | TextDocumentItem, |
20 | }; | 20 | }; |
@@ -22,7 +22,7 @@ use serde::Serialize; | |||
22 | use serde_json::{Value, from_str, to_string_pretty}; | 22 | use serde_json::{Value, from_str, to_string_pretty}; |
23 | use gen_lsp_server::{RawMessage, RawRequest, RawNotification}; | 23 | use gen_lsp_server::{RawMessage, RawRequest, RawNotification}; |
24 | 24 | ||
25 | use m::{Result, main_loop}; | 25 | use m::{Result, main_loop, req}; |
26 | 26 | ||
27 | pub fn project(fixture: &str) -> Server { | 27 | pub fn project(fixture: &str) -> Server { |
28 | static INIT: Once = Once::new(); | 28 | static INIT: Once = Once::new(); |
@@ -72,7 +72,7 @@ impl Server { | |||
72 | let path = dir.path().to_path_buf(); | 72 | let path = dir.path().to_path_buf(); |
73 | let (client_sender, mut server_receiver) = bounded(1); | 73 | let (client_sender, mut server_receiver) = bounded(1); |
74 | let (mut server_sender, client_receiver) = bounded(1); | 74 | let (mut server_sender, client_receiver) = bounded(1); |
75 | let server = thread::spawn(move || main_loop(path, &mut server_receiver, &mut server_sender)); | 75 | let server = thread::spawn(move || main_loop(true, path, &mut server_receiver, &mut server_sender)); |
76 | let res = Server { | 76 | let res = Server { |
77 | req_id: Cell::new(1), | 77 | req_id: Cell::new(1), |
78 | dir, | 78 | dir, |
@@ -125,25 +125,6 @@ impl Server { | |||
125 | ); | 125 | ); |
126 | } | 126 | } |
127 | 127 | ||
128 | pub fn notification<N>( | ||
129 | &self, | ||
130 | expected: &str, | ||
131 | ) | ||
132 | where | ||
133 | N: Notification, | ||
134 | { | ||
135 | let expected = expected.replace("$PROJECT_ROOT$", &self.dir.path().display().to_string()); | ||
136 | let expected: Value = from_str(&expected).unwrap(); | ||
137 | let actual = self.wait_for_notification::<N>(); | ||
138 | assert_eq!( | ||
139 | expected, actual, | ||
140 | "Expected:\n{}\n\ | ||
141 | Actual:\n{}\n", | ||
142 | to_string_pretty(&expected).unwrap(), | ||
143 | to_string_pretty(&actual).unwrap(), | ||
144 | ); | ||
145 | } | ||
146 | |||
147 | fn send_request<R>(&self, id: u64, params: R::Params) -> Value | 128 | fn send_request<R>(&self, id: u64, params: R::Params) -> Value |
148 | where | 129 | where |
149 | R: Request, | 130 | R: Request, |
@@ -173,25 +154,23 @@ impl Server { | |||
173 | } | 154 | } |
174 | panic!("no response"); | 155 | panic!("no response"); |
175 | } | 156 | } |
176 | pub fn wait_for_notification<N: Notification>(&self) -> Value { | 157 | pub fn wait_for_feedback(&self, feedback: &str) { |
177 | self.wait_for_notification_(N::METHOD) | ||
178 | } | ||
179 | fn wait_for_notification_(&self, method: &str) -> Value { | ||
180 | let f = |msg: &RawMessage| match msg { | 158 | let f = |msg: &RawMessage| match msg { |
181 | RawMessage::Notification(n) if n.method == method => { | 159 | RawMessage::Notification(n) if n.method == "internalFeedback" => { |
182 | Some(n.params.clone()) | 160 | return n.clone().cast::<req::InternalFeedback>() |
161 | .unwrap() == feedback | ||
183 | } | 162 | } |
184 | _ => None, | 163 | _ => false, |
185 | }; | 164 | }; |
186 | 165 | ||
187 | for msg in self.messages.borrow().iter() { | 166 | for msg in self.messages.borrow().iter() { |
188 | if let Some(res) = f(msg) { | 167 | if f(msg) { |
189 | return res; | 168 | return; |
190 | } | 169 | } |
191 | } | 170 | } |
192 | while let Some(msg) = self.recv() { | 171 | while let Some(msg) = self.recv() { |
193 | if let Some(res) = f(&msg) { | 172 | if f(&msg) { |
194 | return res; | 173 | return; |
195 | } | 174 | } |
196 | } | 175 | } |
197 | panic!("no response") | 176 | panic!("no response") |