mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 04:53:34 +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"
|
threadpool = "1.7.1"
|
||||||
flexi_logger = "0.9.0"
|
flexi_logger = "0.9.0"
|
||||||
log = "0.4.3"
|
log = "0.4.3"
|
||||||
|
url = "1.1.0"
|
||||||
|
|
||||||
libeditor = { path = "../libeditor" }
|
libeditor = { path = "../libeditor" }
|
||||||
libanalysis = { path = "../libanalysis" }
|
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<()> {
|
pub fn unknown_method(io: &mut Io, raw: RawRequest) -> Result<()> {
|
||||||
error(io, raw.id, ErrorCode::MethodNotFound, "unknown method")
|
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 libanalysis::World;
|
||||||
use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit};
|
use libeditor::{self, LineIndex, LineCol, TextRange, TextUnit};
|
||||||
|
|
||||||
use {req, Result, FilePath};
|
use {req, Result, FilePath};
|
||||||
|
|
||||||
pub fn handle_syntax_tree(
|
pub fn handle_syntax_tree(
|
||||||
|
@ -29,6 +31,23 @@ pub fn handle_extend_selection(
|
||||||
Ok(req::ExtendSelectionResult { selections })
|
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 {
|
fn to_text_range(line_index: &LineIndex, range: Range) -> TextRange {
|
||||||
TextRange::from_to(
|
TextRange::from_to(
|
||||||
|
|
|
@ -11,6 +11,7 @@ extern crate crossbeam_channel;
|
||||||
extern crate threadpool;
|
extern crate threadpool;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
extern crate url;
|
||||||
extern crate flexi_logger;
|
extern crate flexi_logger;
|
||||||
extern crate libeditor;
|
extern crate libeditor;
|
||||||
extern crate libanalysis;
|
extern crate libanalysis;
|
||||||
|
@ -31,7 +32,7 @@ use languageserver_types::{TextDocumentItem, VersionedTextDocumentIdentifier, Te
|
||||||
|
|
||||||
use ::{
|
use ::{
|
||||||
io::{Io, RawMsg},
|
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>;
|
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| {
|
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();
|
||||||
|
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(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
dispatch::handle_notification::<req::DidChangeTextDocument, _>(&mut not, |mut params| {
|
dispatch::handle_notification::<req::DidChangeTextDocument, _>(&mut not, |mut params| {
|
||||||
|
@ -217,11 +233,30 @@ 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();
|
||||||
|
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(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
dispatch::handle_notification::<req::DidCloseTextDocument, _>(&mut not, |params| {
|
dispatch::handle_notification::<req::DidCloseTextDocument, _>(&mut not, |params| {
|
||||||
let path = params.text_document.file_path()?;
|
let path = params.text_document.file_path()?;
|
||||||
world.change_overlay(path, None);
|
world.change_overlay(path, None);
|
||||||
|
dispatch::send_notification::<req::PublishDiagnostics>(io, req::PublishDiagnosticsParams {
|
||||||
|
uri: params.text_document.uri,
|
||||||
|
diagnostics: Vec::new(),
|
||||||
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -252,21 +287,25 @@ trait FilePath {
|
||||||
|
|
||||||
impl FilePath for TextDocumentItem {
|
impl FilePath for TextDocumentItem {
|
||||||
fn file_path(&self) -> Result<PathBuf> {
|
fn file_path(&self) -> Result<PathBuf> {
|
||||||
self.uri.to_file_path()
|
self.uri.file_path()
|
||||||
.map_err(|()| format_err!("invalid uri: {}", self.uri))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilePath for VersionedTextDocumentIdentifier {
|
impl FilePath for VersionedTextDocumentIdentifier {
|
||||||
fn file_path(&self) -> Result<PathBuf> {
|
fn file_path(&self) -> Result<PathBuf> {
|
||||||
self.uri.to_file_path()
|
self.uri.file_path()
|
||||||
.map_err(|()| format_err!("invalid uri: {}", self.uri))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FilePath for TextDocumentIdentifier {
|
impl FilePath for TextDocumentIdentifier {
|
||||||
fn file_path(&self) -> Result<PathBuf> {
|
fn file_path(&self) -> Result<PathBuf> {
|
||||||
self.uri.to_file_path()
|
self.uri.file_path()
|
||||||
.map_err(|()| format_err!("invalid uri: {}", self.uri))
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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::{
|
pub use languageserver_types::{
|
||||||
request::*, notification::*,
|
request::*, notification::*,
|
||||||
InitializeResult,
|
InitializeResult, PublishDiagnosticsParams
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum SyntaxTree {}
|
pub enum SyntaxTree {}
|
||||||
|
|
Loading…
Reference in a new issue