mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
diagnostics
This commit is contained in:
parent
5896cd51de
commit
36d922c87d
5 changed files with 81 additions and 9 deletions
|
@ -14,5 +14,7 @@ crossbeam-channel = "0.2.4"
|
|||
threadpool = "1.7.1"
|
||||
flexi_logger = "0.9.0"
|
||||
log = "0.4.3"
|
||||
url = "1.1.0"
|
||||
|
||||
libeditor = { path = "../libeditor" }
|
||||
libanalysis = { path = "../libanalysis" }
|
||||
|
|
|
@ -136,6 +136,18 @@ pub fn handle_notification<N, F>(not: &mut Option<RawNotification>, f: F) -> Res
|
|||
}
|
||||
}
|
||||
|
||||
pub fn send_notification<N>(io: &mut Io, params: N::Params) -> Result<()>
|
||||
where
|
||||
N: Notification,
|
||||
N::Params: Serialize
|
||||
{
|
||||
io.send(RawMsg::Notification(RawNotification {
|
||||
method: N::METHOD.to_string(),
|
||||
params: serde_json::to_value(params)?,
|
||||
}));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
pub fn unknown_method(io: &mut Io, raw: RawRequest) -> Result<()> {
|
||||
error(io, raw.id, ErrorCode::MethodNotFound, "unknown method")
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use languageserver_types::{Range, Position};
|
||||
use url::Url;
|
||||
use languageserver_types::{Range, Position, Diagnostic, DiagnosticSeverity};
|
||||
use libanalysis::World;
|
||||
use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit};
|
||||
|
||||
use {req, Result, FilePath};
|
||||
|
||||
pub fn handle_syntax_tree(
|
||||
|
@ -29,6 +31,23 @@ pub fn handle_extend_selection(
|
|||
Ok(req::ExtendSelectionResult { selections })
|
||||
}
|
||||
|
||||
pub fn publish_diagnostics(world: World, uri: Url) -> Result<req::PublishDiagnosticsParams> {
|
||||
let path = uri.file_path()?;
|
||||
let file = world.file_syntax(&path)?;
|
||||
let line_index = world.file_line_index(&path)?;
|
||||
let diagnostics = libeditor::diagnostics(&file)
|
||||
.into_iter()
|
||||
.map(|d| Diagnostic {
|
||||
range: to_vs_range(&line_index, d.range),
|
||||
severity: Some(DiagnosticSeverity::Error),
|
||||
code: None,
|
||||
source: Some("libsyntax2".to_string()),
|
||||
message: d.msg,
|
||||
related_information: None,
|
||||
}).collect();
|
||||
Ok(req::PublishDiagnosticsParams { uri, diagnostics })
|
||||
}
|
||||
|
||||
|
||||
fn to_text_range(line_index: &LineIndex, range: Range) -> TextRange {
|
||||
TextRange::from_to(
|
||||
|
|
|
@ -11,6 +11,7 @@ extern crate crossbeam_channel;
|
|||
extern crate threadpool;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate url;
|
||||
extern crate flexi_logger;
|
||||
extern crate libeditor;
|
||||
extern crate libanalysis;
|
||||
|
@ -31,7 +32,7 @@ use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, Te
|
|||
|
||||
use ::{
|
||||
io::{Io, RawMsg},
|
||||
handlers::{handle_syntax_tree, handle_extend_selection},
|
||||
handlers::{handle_syntax_tree, handle_extend_selection, publish_diagnostics},
|
||||
};
|
||||
|
||||
pub type Result<T> = ::std::result::Result<T, ::failure::Error>;
|
||||
|
@ -209,6 +210,21 @@ fn main_loop(
|
|||
dispatch::handle_notification::<req::DidOpenTextDocument, _>(&mut not, |params| {
|
||||
let path = params.text_document.file_path()?;
|
||||
world.change_overlay(path, Some(params.text_document.text));
|
||||
let world = world.snapshot();
|
||||
let sender = sender.clone();
|
||||
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(())
|
||||
})?;
|
||||
dispatch::handle_notification::<req::DidChangeTextDocument, _>(&mut not, |mut params| {
|
||||
|
@ -217,11 +233,30 @@ fn main_loop(
|
|||
.ok_or_else(|| format_err!("empty changes"))?
|
||||
.text;
|
||||
world.change_overlay(path, Some(text));
|
||||
let world = world.snapshot();
|
||||
let sender = sender.clone();
|
||||
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(())
|
||||
})?;
|
||||
dispatch::handle_notification::<req::DidCloseTextDocument, _>(&mut not, |params| {
|
||||
let path = params.text_document.file_path()?;
|
||||
world.change_overlay(path, None);
|
||||
dispatch::send_notification::<req::PublishDiagnostics>(io, req::PublishDiagnosticsParams {
|
||||
uri: params.text_document.uri,
|
||||
diagnostics: Vec::new(),
|
||||
})?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
|
@ -252,21 +287,25 @@ trait FilePath {
|
|||
|
||||
impl FilePath for TextDocumentItem {
|
||||
fn file_path(&self) -> Result<PathBuf> {
|
||||
self.uri.to_file_path()
|
||||
.map_err(|()| format_err!("invalid uri: {}", self.uri))
|
||||
self.uri.file_path()
|
||||
}
|
||||
}
|
||||
|
||||
impl FilePath for VersionedTextDocumentIdentifier {
|
||||
fn file_path(&self) -> Result<PathBuf> {
|
||||
self.uri.to_file_path()
|
||||
.map_err(|()| format_err!("invalid uri: {}", self.uri))
|
||||
self.uri.file_path()
|
||||
}
|
||||
}
|
||||
|
||||
impl FilePath for TextDocumentIdentifier {
|
||||
fn file_path(&self) -> Result<PathBuf> {
|
||||
self.uri.to_file_path()
|
||||
.map_err(|()| format_err!("invalid uri: {}", self.uri))
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use languageserver_types::{TextDocumentIdentifier, Range};
|
|||
|
||||
pub use languageserver_types::{
|
||||
request::*, notification::*,
|
||||
InitializeResult,
|
||||
InitializeResult, PublishDiagnosticsParams
|
||||
};
|
||||
|
||||
pub enum SyntaxTree {}
|
||||
|
|
Loading…
Reference in a new issue