diff options
-rw-r--r-- | crates/server/src/handlers.rs | 5 | ||||
-rw-r--r-- | crates/server/src/main.rs | 97 | ||||
-rw-r--r-- | crates/server/src/util.rs | 42 |
3 files changed, 73 insertions, 71 deletions
diff --git a/crates/server/src/handlers.rs b/crates/server/src/handlers.rs index 1f55e8669..de1fd557d 100644 --- a/crates/server/src/handlers.rs +++ b/crates/server/src/handlers.rs | |||
@@ -3,7 +3,10 @@ use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity}; | |||
3 | use libanalysis::World; | 3 | use libanalysis::World; |
4 | use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit}; | 4 | use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit}; |
5 | 5 | ||
6 | use {req, Result, FilePath}; | 6 | use ::{ |
7 | req, Result, | ||
8 | util::FilePath, | ||
9 | }; | ||
7 | 10 | ||
8 | pub fn handle_syntax_tree( | 11 | pub fn handle_syntax_tree( |
9 | world: World, | 12 | world: World, |
diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs index dfde8afb1..0e4f5f86a 100644 --- a/crates/server/src/main.rs +++ b/crates/server/src/main.rs | |||
@@ -21,18 +21,18 @@ mod caps; | |||
21 | mod req; | 21 | mod req; |
22 | mod dispatch; | 22 | mod dispatch; |
23 | mod handlers; | 23 | mod handlers; |
24 | 24 | mod util; | |
25 | use std::path::PathBuf; | ||
26 | 25 | ||
27 | use threadpool::ThreadPool; | 26 | use threadpool::ThreadPool; |
28 | use crossbeam_channel::{bounded, Sender, Receiver}; | 27 | use crossbeam_channel::{bounded, Sender, Receiver}; |
29 | use flexi_logger::Logger; | 28 | use flexi_logger::Logger; |
30 | use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, TextDocumentIdentifier}; | 29 | use url::Url; |
31 | use libanalysis::{WorldState, World}; | 30 | use libanalysis::{WorldState, World}; |
32 | 31 | ||
33 | use ::{ | 32 | use ::{ |
34 | io::{Io, RawMsg, RawRequest}, | 33 | io::{Io, RawMsg, RawRequest}, |
35 | handlers::{handle_syntax_tree, handle_extend_selection, publish_diagnostics}, | 34 | handlers::{handle_syntax_tree, handle_extend_selection, publish_diagnostics}, |
35 | util::{FilePath, FnBox} | ||
36 | }; | 36 | }; |
37 | 37 | ||
38 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; | 38 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; |
@@ -198,21 +198,9 @@ fn main_loop( | |||
198 | dispatch::handle_notification::<req::DidOpenTextDocument, _>(&mut not, |params| { | 198 | dispatch::handle_notification::<req::DidOpenTextDocument, _>(&mut not, |params| { |
199 | let path = params.text_document.file_path()?; | 199 | let path = params.text_document.file_path()?; |
200 | world.change_overlay(path, Some(params.text_document.text)); | 200 | world.change_overlay(path, Some(params.text_document.text)); |
201 | let world = world.snapshot(); | 201 | update_diagnostics_on_threadpool( |
202 | let sender = sender.clone(); | 202 | pool, world.snapshot(), sender.clone(), params.text_document.uri, |
203 | let uri = params.text_document.uri; | 203 | ); |
204 | pool.execute(move || { | ||
205 | match publish_diagnostics(world, uri) { | ||
206 | Err(e) => { | ||
207 | error!("failed to compute diagnostics: {:?}", e) | ||
208 | } | ||
209 | Ok(params) => { | ||
210 | sender.send(Box::new(|io: &mut Io| { | ||
211 | dispatch::send_notification::<req::PublishDiagnostics>(io, params) | ||
212 | })) | ||
213 | } | ||
214 | } | ||
215 | }); | ||
216 | Ok(()) | 204 | Ok(()) |
217 | })?; | 205 | })?; |
218 | dispatch::handle_notification::<req::DidChangeTextDocument, _>(&mut not, |mut params| { | 206 | dispatch::handle_notification::<req::DidChangeTextDocument, _>(&mut not, |mut params| { |
@@ -221,21 +209,9 @@ fn main_loop( | |||
221 | .ok_or_else(|| format_err!("empty changes"))? | 209 | .ok_or_else(|| format_err!("empty changes"))? |
222 | .text; | 210 | .text; |
223 | world.change_overlay(path, Some(text)); | 211 | world.change_overlay(path, Some(text)); |
224 | let world = world.snapshot(); | 212 | update_diagnostics_on_threadpool( |
225 | let sender = sender.clone(); | 213 | pool, world.snapshot(), sender.clone(), params.text_document.uri, |
226 | let uri = params.text_document.uri; | 214 | ); |
227 | pool.execute(move || { | ||
228 | match publish_diagnostics(world, uri) { | ||
229 | Err(e) => { | ||
230 | error!("failed to compute diagnostics: {:?}", e) | ||
231 | } | ||
232 | Ok(params) => { | ||
233 | sender.send(Box::new(|io: &mut Io| { | ||
234 | dispatch::send_notification::<req::PublishDiagnostics>(io, params) | ||
235 | })) | ||
236 | } | ||
237 | } | ||
238 | }); | ||
239 | Ok(()) | 215 | Ok(()) |
240 | })?; | 216 | })?; |
241 | dispatch::handle_notification::<req::DidCloseTextDocument, _>(&mut not, |params| { | 217 | dispatch::handle_notification::<req::DidCloseTextDocument, _>(&mut not, |params| { |
@@ -278,41 +254,22 @@ fn handle_request_on_threadpool<R: req::ClientRequest>( | |||
278 | }) | 254 | }) |
279 | } | 255 | } |
280 | 256 | ||
281 | trait FnBox<A, R>: Send { | 257 | fn update_diagnostics_on_threadpool( |
282 | fn call_box(self: Box<Self>, a: A) -> R; | 258 | pool: &ThreadPool, |
283 | } | 259 | world: World, |
284 | 260 | sender: Sender<Thunk>, | |
285 | impl<A, R, F: FnOnce(A) -> R + Send> FnBox<A, R> for F { | 261 | uri: Url, |
286 | fn call_box(self: Box<F>, a: A) -> R { | 262 | ) { |
287 | (*self)(a) | 263 | pool.execute(move || { |
288 | } | 264 | match publish_diagnostics(world, uri) { |
289 | } | 265 | Err(e) => { |
290 | 266 | error!("failed to compute diagnostics: {:?}", e) | |
291 | trait FilePath { | 267 | } |
292 | fn file_path(&self) -> Result<PathBuf>; | 268 | Ok(params) => { |
293 | } | 269 | sender.send(Box::new(|io: &mut Io| { |
294 | 270 | dispatch::send_notification::<req::PublishDiagnostics>(io, params) | |
295 | impl FilePath for TextDocumentItem { | 271 | })) |
296 | fn file_path(&self) -> Result<PathBuf> { | 272 | } |
297 | self.uri.file_path() | 273 | } |
298 | } | 274 | }); |
299 | } | ||
300 | |||
301 | impl FilePath for VersionedTextDocumentIdentifier { | ||
302 | fn file_path(&self) -> Result<PathBuf> { | ||
303 | self.uri.file_path() | ||
304 | } | ||
305 | } | ||
306 | |||
307 | impl FilePath for TextDocumentIdentifier { | ||
308 | fn file_path(&self) -> Result<PathBuf> { | ||
309 | self.uri.file_path() | ||
310 | } | ||
311 | } | ||
312 | |||
313 | impl FilePath for ::url::Url { | ||
314 | fn file_path(&self) -> Result<PathBuf> { | ||
315 | self.to_file_path() | ||
316 | .map_err(|()| format_err!("invalid uri: {}", self)) | ||
317 | } | ||
318 | } | 275 | } |
diff --git a/crates/server/src/util.rs b/crates/server/src/util.rs new file mode 100644 index 000000000..3691852f0 --- /dev/null +++ b/crates/server/src/util.rs | |||
@@ -0,0 +1,42 @@ | |||
1 | use std::path::PathBuf; | ||
2 | use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, TextDocumentIdentifier}; | ||
3 | use ::{Result}; | ||
4 | |||
5 | pub trait FnBox<A, R>: Send { | ||
6 | fn call_box(self: Box<Self>, a: A) -> R; | ||
7 | } | ||
8 | |||
9 | impl<A, R, F: FnOnce(A) -> R + Send> FnBox<A, R> for F { | ||
10 | fn call_box(self: Box<F>, a: A) -> R { | ||
11 | (*self)(a) | ||
12 | } | ||
13 | } | ||
14 | |||
15 | pub trait FilePath { | ||
16 | fn file_path(&self) -> Result<PathBuf>; | ||
17 | } | ||
18 | |||
19 | impl FilePath for TextDocumentItem { | ||
20 | fn file_path(&self) -> Result<PathBuf> { | ||
21 | self.uri.file_path() | ||
22 | } | ||
23 | } | ||
24 | |||
25 | impl FilePath for VersionedTextDocumentIdentifier { | ||
26 | fn file_path(&self) -> Result<PathBuf> { | ||
27 | self.uri.file_path() | ||
28 | } | ||
29 | } | ||
30 | |||
31 | impl FilePath for TextDocumentIdentifier { | ||
32 | fn file_path(&self) -> Result<PathBuf> { | ||
33 | self.uri.file_path() | ||
34 | } | ||
35 | } | ||
36 | |||
37 | impl FilePath for ::url::Url { | ||
38 | fn file_path(&self) -> Result<PathBuf> { | ||
39 | self.to_file_path() | ||
40 | .map_err(|()| format_err!("invalid uri: {}", self)) | ||
41 | } | ||
42 | } | ||