This commit is contained in:
Aleksey Kladov 2018-08-11 00:12:31 +03:00
parent 46e4232cc6
commit 836e0c1863
3 changed files with 73 additions and 71 deletions

View file

@ -3,7 +3,10 @@ use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity};
use libanalysis::World; use libanalysis::World;
use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit}; use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit};
use {req, Result, FilePath}; use ::{
req, Result,
util::FilePath,
};
pub fn handle_syntax_tree( pub fn handle_syntax_tree(
world: World, world: World,

View file

@ -21,18 +21,18 @@ mod caps;
mod req; mod req;
mod dispatch; mod dispatch;
mod handlers; mod handlers;
mod util;
use std::path::PathBuf;
use threadpool::ThreadPool; use threadpool::ThreadPool;
use crossbeam_channel::{bounded, Sender, Receiver}; use crossbeam_channel::{bounded, Sender, Receiver};
use flexi_logger::Logger; use flexi_logger::Logger;
use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, TextDocumentIdentifier}; use url::Url;
use libanalysis::{WorldState, World}; use libanalysis::{WorldState, World};
use ::{ use ::{
io::{Io, RawMsg, RawRequest}, io::{Io, RawMsg, RawRequest},
handlers::{handle_syntax_tree, handle_extend_selection, publish_diagnostics}, handlers::{handle_syntax_tree, handle_extend_selection, publish_diagnostics},
util::{FilePath, FnBox}
}; };
pub type Result<T> = ::std::result::Result<T, ::failure::Error>; pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
@ -198,21 +198,9 @@ fn main_loop(
dispatch::handle_notification::<req::DidOpenTextDocument, _>(&mut not, |params| { dispatch::handle_notification::<req::DidOpenTextDocument, _>(&mut not, |params| {
let path = params.text_document.file_path()?; let path = params.text_document.file_path()?;
world.change_overlay(path, Some(params.text_document.text)); world.change_overlay(path, Some(params.text_document.text));
let world = world.snapshot(); update_diagnostics_on_threadpool(
let sender = sender.clone(); pool, world.snapshot(), sender.clone(), params.text_document.uri,
let uri = params.text_document.uri; );
pool.execute(move || {
match publish_diagnostics(world, uri) {
Err(e) => {
error!("failed to compute diagnostics: {:?}", e)
}
Ok(params) => {
sender.send(Box::new(|io: &mut Io| {
dispatch::send_notification::<req::PublishDiagnostics>(io, params)
}))
}
}
});
Ok(()) Ok(())
})?; })?;
dispatch::handle_notification::<req::DidChangeTextDocument, _>(&mut not, |mut params| { dispatch::handle_notification::<req::DidChangeTextDocument, _>(&mut not, |mut params| {
@ -221,21 +209,9 @@ fn main_loop(
.ok_or_else(|| format_err!("empty changes"))? .ok_or_else(|| format_err!("empty changes"))?
.text; .text;
world.change_overlay(path, Some(text)); world.change_overlay(path, Some(text));
let world = world.snapshot(); update_diagnostics_on_threadpool(
let sender = sender.clone(); pool, world.snapshot(), sender.clone(), params.text_document.uri,
let uri = params.text_document.uri; );
pool.execute(move || {
match publish_diagnostics(world, uri) {
Err(e) => {
error!("failed to compute diagnostics: {:?}", e)
}
Ok(params) => {
sender.send(Box::new(|io: &mut Io| {
dispatch::send_notification::<req::PublishDiagnostics>(io, params)
}))
}
}
});
Ok(()) Ok(())
})?; })?;
dispatch::handle_notification::<req::DidCloseTextDocument, _>(&mut not, |params| { dispatch::handle_notification::<req::DidCloseTextDocument, _>(&mut not, |params| {
@ -278,41 +254,22 @@ fn handle_request_on_threadpool<R: req::ClientRequest>(
}) })
} }
trait FnBox<A, R>: Send { fn update_diagnostics_on_threadpool(
fn call_box(self: Box<Self>, a: A) -> R; pool: &ThreadPool,
} world: World,
sender: Sender<Thunk>,
impl<A, R, F: FnOnce(A) -> R + Send> FnBox<A, R> for F { uri: Url,
fn call_box(self: Box<F>, a: A) -> R { ) {
(*self)(a) pool.execute(move || {
} match publish_diagnostics(world, uri) {
} Err(e) => {
error!("failed to compute diagnostics: {:?}", e)
trait FilePath { }
fn file_path(&self) -> Result<PathBuf>; Ok(params) => {
} sender.send(Box::new(|io: &mut Io| {
dispatch::send_notification::<req::PublishDiagnostics>(io, params)
impl FilePath for TextDocumentItem { }))
fn file_path(&self) -> Result<PathBuf> { }
self.uri.file_path() }
} });
}
impl FilePath for VersionedTextDocumentIdentifier {
fn file_path(&self) -> Result<PathBuf> {
self.uri.file_path()
}
}
impl FilePath for TextDocumentIdentifier {
fn file_path(&self) -> Result<PathBuf> {
self.uri.file_path()
}
}
impl FilePath for ::url::Url {
fn file_path(&self) -> Result<PathBuf> {
self.to_file_path()
.map_err(|()| format_err!("invalid uri: {}", self))
}
} }

42
crates/server/src/util.rs Normal file
View file

@ -0,0 +1,42 @@
use std::path::PathBuf;
use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, TextDocumentIdentifier};
use ::{Result};
pub trait FnBox<A, R>: Send {
fn call_box(self: Box<Self>, a: A) -> R;
}
impl<A, R, F: FnOnce(A) -> R + Send> FnBox<A, R> for F {
fn call_box(self: Box<F>, a: A) -> R {
(*self)(a)
}
}
pub trait FilePath {
fn file_path(&self) -> Result<PathBuf>;
}
impl FilePath for TextDocumentItem {
fn file_path(&self) -> Result<PathBuf> {
self.uri.file_path()
}
}
impl FilePath for VersionedTextDocumentIdentifier {
fn file_path(&self) -> Result<PathBuf> {
self.uri.file_path()
}
}
impl FilePath for TextDocumentIdentifier {
fn file_path(&self) -> Result<PathBuf> {
self.uri.file_path()
}
}
impl FilePath for ::url::Url {
fn file_path(&self) -> Result<PathBuf> {
self.to_file_path()
.map_err(|()| format_err!("invalid uri: {}", self))
}
}