diff options
author | Aleksey Kladov <[email protected]> | 2018-08-29 16:03:14 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-29 16:03:14 +0100 |
commit | 8abf5363433e977c5393bb569e2a5d559cb0a602 (patch) | |
tree | 8bb7bc3097cb9e22af9e3be8605cb4745c2fae5f /crates/server/src/main_loop/mod.rs | |
parent | 2007ccfcfe0bf01c934589dd3c87fda83b06b272 (diff) |
Grand refactoring
Diffstat (limited to 'crates/server/src/main_loop/mod.rs')
-rw-r--r-- | crates/server/src/main_loop/mod.rs | 169 |
1 files changed, 48 insertions, 121 deletions
diff --git a/crates/server/src/main_loop/mod.rs b/crates/server/src/main_loop/mod.rs index accb13878..0f66248a5 100644 --- a/crates/server/src/main_loop/mod.rs +++ b/crates/server/src/main_loop/mod.rs | |||
@@ -7,7 +7,6 @@ use std::{ | |||
7 | use threadpool::ThreadPool; | 7 | use threadpool::ThreadPool; |
8 | use crossbeam_channel::{Sender, Receiver}; | 8 | use crossbeam_channel::{Sender, Receiver}; |
9 | use languageserver_types::Url; | 9 | use languageserver_types::Url; |
10 | use serde_json::to_value; | ||
11 | 10 | ||
12 | use { | 11 | use { |
13 | req, dispatch, | 12 | req, dispatch, |
@@ -15,24 +14,6 @@ use { | |||
15 | io::{Io, RawMsg, RawRequest, RawNotification}, | 14 | io::{Io, RawMsg, RawRequest, RawNotification}, |
16 | vfs::FileEvent, | 15 | vfs::FileEvent, |
17 | server_world::{ServerWorldState, ServerWorld}, | 16 | server_world::{ServerWorldState, ServerWorld}, |
18 | main_loop::handlers::{ | ||
19 | handle_syntax_tree, | ||
20 | handle_extend_selection, | ||
21 | publish_diagnostics, | ||
22 | publish_decorations, | ||
23 | handle_document_symbol, | ||
24 | handle_code_action, | ||
25 | handle_execute_command, | ||
26 | handle_workspace_symbol, | ||
27 | handle_goto_definition, | ||
28 | handle_find_matching_brace, | ||
29 | handle_parent_module, | ||
30 | handle_join_lines, | ||
31 | handle_completion, | ||
32 | handle_runnables, | ||
33 | handle_decorations, | ||
34 | handle_on_type_formatting, | ||
35 | }, | ||
36 | }; | 17 | }; |
37 | 18 | ||
38 | pub(super) fn main_loop( | 19 | pub(super) fn main_loop( |
@@ -45,7 +26,6 @@ pub(super) fn main_loop( | |||
45 | info!("server initialized, serving requests"); | 26 | info!("server initialized, serving requests"); |
46 | let mut state = ServerWorldState::new(); | 27 | let mut state = ServerWorldState::new(); |
47 | 28 | ||
48 | let mut next_request_id = 0; | ||
49 | let mut pending_requests: HashSet<u64> = HashSet::new(); | 29 | let mut pending_requests: HashSet<u64> = HashSet::new(); |
50 | let mut fs_events_receiver = Some(&fs_events_receiver); | 30 | let mut fs_events_receiver = Some(&fs_events_receiver); |
51 | loop { | 31 | loop { |
@@ -78,12 +58,6 @@ pub(super) fn main_loop( | |||
78 | } | 58 | } |
79 | Event::Task(task) => { | 59 | Event::Task(task) => { |
80 | match task { | 60 | match task { |
81 | Task::Request(mut request) => { | ||
82 | request.id = next_request_id; | ||
83 | pending_requests.insert(next_request_id); | ||
84 | next_request_id += 1; | ||
85 | io.send(RawMsg::Request(request)); | ||
86 | } | ||
87 | Task::Respond(response) => | 61 | Task::Respond(response) => |
88 | io.send(RawMsg::Response(response)), | 62 | io.send(RawMsg::Response(response)), |
89 | Task::Notify(n) => | 63 | Task::Notify(n) => |
@@ -125,79 +99,26 @@ fn on_request( | |||
125 | sender: &Sender<Task>, | 99 | sender: &Sender<Task>, |
126 | req: RawRequest, | 100 | req: RawRequest, |
127 | ) -> Result<bool> { | 101 | ) -> Result<bool> { |
128 | let mut req = Some(req); | 102 | let mut pool_dispatcher = PoolDispatcher { |
129 | handle_request_on_threadpool::<req::SyntaxTree>( | 103 | req: Some(req), |
130 | &mut req, pool, world, sender, handle_syntax_tree, | 104 | pool, world, sender |
131 | )?; | 105 | }; |
132 | handle_request_on_threadpool::<req::ExtendSelection>( | 106 | pool_dispatcher |
133 | &mut req, pool, world, sender, handle_extend_selection, | 107 | .on::<req::SyntaxTree>(handlers::handle_syntax_tree)? |
134 | )?; | 108 | .on::<req::ExtendSelection>(handlers::handle_extend_selection)? |
135 | handle_request_on_threadpool::<req::FindMatchingBrace>( | 109 | .on::<req::FindMatchingBrace>(handlers::handle_find_matching_brace)? |
136 | &mut req, pool, world, sender, handle_find_matching_brace, | 110 | .on::<req::JoinLines>(handlers::handle_join_lines)? |
137 | )?; | 111 | .on::<req::OnTypeFormatting>(handlers::handle_on_type_formatting)? |
138 | handle_request_on_threadpool::<req::DocumentSymbolRequest>( | 112 | .on::<req::DocumentSymbolRequest>(handlers::handle_document_symbol)? |
139 | &mut req, pool, world, sender, handle_document_symbol, | 113 | .on::<req::WorkspaceSymbol>(handlers::handle_workspace_symbol)? |
140 | )?; | 114 | .on::<req::GotoDefinition>(handlers::handle_goto_definition)? |
141 | handle_request_on_threadpool::<req::CodeActionRequest>( | 115 | .on::<req::ParentModule>(handlers::handle_parent_module)? |
142 | &mut req, pool, world, sender, handle_code_action, | 116 | .on::<req::Runnables>(handlers::handle_runnables)? |
143 | )?; | 117 | .on::<req::DecorationsRequest>(handlers::handle_decorations)? |
144 | handle_request_on_threadpool::<req::Runnables>( | 118 | .on::<req::Completion>(handlers::handle_completion)? |
145 | &mut req, pool, world, sender, handle_runnables, | 119 | .on::<req::CodeActionRequest>(handlers::handle_code_action)?; |
146 | )?; | ||
147 | handle_request_on_threadpool::<req::WorkspaceSymbol>( | ||
148 | &mut req, pool, world, sender, handle_workspace_symbol, | ||
149 | )?; | ||
150 | handle_request_on_threadpool::<req::GotoDefinition>( | ||
151 | &mut req, pool, world, sender, handle_goto_definition, | ||
152 | )?; | ||
153 | handle_request_on_threadpool::<req::Completion>( | ||
154 | &mut req, pool, world, sender, handle_completion, | ||
155 | )?; | ||
156 | handle_request_on_threadpool::<req::ParentModule>( | ||
157 | &mut req, pool, world, sender, handle_parent_module, | ||
158 | )?; | ||
159 | handle_request_on_threadpool::<req::JoinLines>( | ||
160 | &mut req, pool, world, sender, handle_join_lines, | ||
161 | )?; | ||
162 | handle_request_on_threadpool::<req::DecorationsRequest>( | ||
163 | &mut req, pool, world, sender, handle_decorations, | ||
164 | )?; | ||
165 | handle_request_on_threadpool::<req::OnTypeFormatting>( | ||
166 | &mut req, pool, world, sender, handle_on_type_formatting, | ||
167 | )?; | ||
168 | dispatch::handle_request::<req::ExecuteCommand, _>(&mut req, |params, resp| { | ||
169 | io.send(RawMsg::Response(resp.into_response(Ok(None))?)); | ||
170 | |||
171 | let world = world.snapshot(); | ||
172 | let sender = sender.clone(); | ||
173 | pool.execute(move || { | ||
174 | let (edit, cursor) = match handle_execute_command(world, params) { | ||
175 | Ok(res) => res, | ||
176 | Err(e) => return sender.send(Task::Die(e)), | ||
177 | }; | ||
178 | match to_value(edit) { | ||
179 | Err(e) => return sender.send(Task::Die(e.into())), | ||
180 | Ok(params) => { | ||
181 | let request = RawRequest { | ||
182 | id: 0, | ||
183 | method: <req::ApplyWorkspaceEdit as req::ClientRequest>::METHOD.to_string(), | ||
184 | params, | ||
185 | }; | ||
186 | sender.send(Task::Request(request)) | ||
187 | } | ||
188 | } | ||
189 | if let Some(cursor) = cursor { | ||
190 | let request = RawRequest { | ||
191 | id: 0, | ||
192 | method: <req::MoveCursor as req::ClientRequest>::METHOD.to_string(), | ||
193 | params: to_value(cursor).unwrap(), | ||
194 | }; | ||
195 | sender.send(Task::Request(request)) | ||
196 | } | ||
197 | }); | ||
198 | Ok(()) | ||
199 | })?; | ||
200 | 120 | ||
121 | let mut req = pool_dispatcher.req; | ||
201 | let mut shutdown = false; | 122 | let mut shutdown = false; |
202 | dispatch::handle_request::<req::Shutdown, _>(&mut req, |(), resp| { | 123 | dispatch::handle_request::<req::Shutdown, _>(&mut req, |(), resp| { |
203 | let resp = resp.into_response(Ok(()))?; | 124 | let resp = resp.into_response(Ok(()))?; |
@@ -273,27 +194,33 @@ fn on_notification( | |||
273 | Ok(()) | 194 | Ok(()) |
274 | } | 195 | } |
275 | 196 | ||
276 | fn handle_request_on_threadpool<R: req::ClientRequest>( | 197 | struct PoolDispatcher<'a> { |
277 | req: &mut Option<RawRequest>, | 198 | req: Option<RawRequest>, |
278 | pool: &ThreadPool, | 199 | pool: &'a ThreadPool, |
279 | world: &ServerWorldState, | 200 | world: &'a ServerWorldState, |
280 | sender: &Sender<Task>, | 201 | sender: &'a Sender<Task>, |
281 | f: fn(ServerWorld, R::Params) -> Result<R::Result>, | 202 | } |
282 | ) -> Result<()> | 203 | |
283 | { | 204 | impl<'a> PoolDispatcher<'a> { |
284 | dispatch::handle_request::<R, _>(req, |params, resp| { | 205 | fn on<'b, R: req::ClientRequest>(&'b mut self, f: fn(ServerWorld, R::Params) -> Result<R::Result>) -> Result<&'b mut Self> { |
285 | let world = world.snapshot(); | 206 | let world = self.world; |
286 | let sender = sender.clone(); | 207 | let sender = self.sender; |
287 | pool.execute(move || { | 208 | let pool = self.pool; |
288 | let res = f(world, params); | 209 | dispatch::handle_request::<R, _>(&mut self.req, |params, resp| { |
289 | let task = match resp.into_response(res) { | 210 | let world = world.snapshot(); |
290 | Ok(resp) => Task::Respond(resp), | 211 | let sender = sender.clone(); |
291 | Err(e) => Task::Die(e), | 212 | pool.execute(move || { |
292 | }; | 213 | let res = f(world, params); |
293 | sender.send(task); | 214 | let task = match resp.into_response(res) { |
294 | }); | 215 | Ok(resp) => Task::Respond(resp), |
295 | Ok(()) | 216 | Err(e) => Task::Die(e), |
296 | }) | 217 | }; |
218 | sender.send(task); | ||
219 | }); | ||
220 | Ok(()) | ||
221 | })?; | ||
222 | Ok(self) | ||
223 | } | ||
297 | } | 224 | } |
298 | 225 | ||
299 | fn update_file_notifications_on_threadpool( | 226 | fn update_file_notifications_on_threadpool( |
@@ -303,7 +230,7 @@ fn update_file_notifications_on_threadpool( | |||
303 | uri: Url, | 230 | uri: Url, |
304 | ) { | 231 | ) { |
305 | pool.execute(move || { | 232 | pool.execute(move || { |
306 | match publish_diagnostics(world.clone(), uri.clone()) { | 233 | match handlers::publish_diagnostics(world.clone(), uri.clone()) { |
307 | Err(e) => { | 234 | Err(e) => { |
308 | error!("failed to compute diagnostics: {:?}", e) | 235 | error!("failed to compute diagnostics: {:?}", e) |
309 | } | 236 | } |
@@ -312,7 +239,7 @@ fn update_file_notifications_on_threadpool( | |||
312 | sender.send(Task::Notify(not)); | 239 | sender.send(Task::Notify(not)); |
313 | } | 240 | } |
314 | } | 241 | } |
315 | match publish_decorations(world, uri) { | 242 | match handlers::publish_decorations(world, uri) { |
316 | Err(e) => { | 243 | Err(e) => { |
317 | error!("failed to compute decorations: {:?}", e) | 244 | error!("failed to compute decorations: {:?}", e) |
318 | } | 245 | } |