aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/server/src/handlers.rs5
-rw-r--r--crates/server/src/main.rs97
-rw-r--r--crates/server/src/util.rs42
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};
3use libanalysis::World; 3use libanalysis::World;
4use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit}; 4use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit};
5 5
6use {req, Result, FilePath}; 6use ::{
7 req, Result,
8 util::FilePath,
9};
7 10
8pub fn handle_syntax_tree( 11pub 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;
21mod req; 21mod req;
22mod dispatch; 22mod dispatch;
23mod handlers; 23mod handlers;
24 24mod util;
25use std::path::PathBuf;
26 25
27use threadpool::ThreadPool; 26use threadpool::ThreadPool;
28use crossbeam_channel::{bounded, Sender, Receiver}; 27use crossbeam_channel::{bounded, Sender, Receiver};
29use flexi_logger::Logger; 28use flexi_logger::Logger;
30use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, TextDocumentIdentifier}; 29use url::Url;
31use libanalysis::{WorldState, World}; 30use libanalysis::{WorldState, World};
32 31
33use ::{ 32use ::{
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
38pub type Result<T> = ::std::result::Result<T, ::failure::Error>; 38pub 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
281trait FnBox<A, R>: Send { 257fn 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>,
285impl<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)
291trait 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)
295impl FilePath for TextDocumentItem { 271 }))
296 fn file_path(&self) -> Result<PathBuf> { 272 }
297 self.uri.file_path() 273 }
298 } 274 });
299}
300
301impl FilePath for VersionedTextDocumentIdentifier {
302 fn file_path(&self) -> Result<PathBuf> {
303 self.uri.file_path()
304 }
305}
306
307impl FilePath for TextDocumentIdentifier {
308 fn file_path(&self) -> Result<PathBuf> {
309 self.uri.file_path()
310 }
311}
312
313impl 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 @@
1use std::path::PathBuf;
2use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, TextDocumentIdentifier};
3use ::{Result};
4
5pub trait FnBox<A, R>: Send {
6 fn call_box(self: Box<Self>, a: A) -> R;
7}
8
9impl<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
15pub trait FilePath {
16 fn file_path(&self) -> Result<PathBuf>;
17}
18
19impl FilePath for TextDocumentItem {
20 fn file_path(&self) -> Result<PathBuf> {
21 self.uri.file_path()
22 }
23}
24
25impl FilePath for VersionedTextDocumentIdentifier {
26 fn file_path(&self) -> Result<PathBuf> {
27 self.uri.file_path()
28 }
29}
30
31impl FilePath for TextDocumentIdentifier {
32 fn file_path(&self) -> Result<PathBuf> {
33 self.uri.file_path()
34 }
35}
36
37impl 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}