mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 22:54:58 +00:00
Move LSP bits from flycheck to rust-analyzer
There should be only one place that knows about LSP, and that place is right before we spit JSON on stdout.
This commit is contained in:
parent
12d82687cd
commit
220813dcb0
18 changed files with 1505 additions and 1506 deletions
|
@ -29,6 +29,7 @@ rustc-hash = "1.1.0"
|
|||
serde = { version = "1.0.106", features = ["derive"] }
|
||||
serde_json = "1.0.48"
|
||||
threadpool = "1.7.1"
|
||||
cargo_metadata = "0.10.0"
|
||||
|
||||
stdx = { path = "../stdx" }
|
||||
|
||||
|
@ -53,6 +54,7 @@ winapi = "0.3.8"
|
|||
|
||||
[dev-dependencies]
|
||||
tempfile = "3.1.0"
|
||||
insta = "0.16.0"
|
||||
test_utils = { path = "../test_utils" }
|
||||
|
||||
[features]
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//! Book keeping for keeping diagnostics easily in sync with the client.
|
||||
pub(crate) mod to_proto;
|
||||
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
---
|
||||
source: crates/rust-analyzer/src/diagnostics/to_proto.rs
|
||||
expression: diag
|
||||
---
|
||||
[
|
||||
MappedRustDiagnostic {
|
||||
location: Location {
|
||||
uri: "file:///test/compiler/mir/tagset.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 41,
|
||||
character: 23,
|
||||
},
|
||||
end: Position {
|
||||
line: 41,
|
||||
character: 28,
|
||||
},
|
||||
},
|
||||
},
|
||||
diagnostic: Diagnostic {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 41,
|
||||
character: 23,
|
||||
},
|
||||
end: Position {
|
||||
line: 41,
|
||||
character: 28,
|
||||
},
|
||||
},
|
||||
severity: Some(
|
||||
Warning,
|
||||
),
|
||||
code: Some(
|
||||
String(
|
||||
"trivially_copy_pass_by_ref",
|
||||
),
|
||||
),
|
||||
source: Some(
|
||||
"clippy",
|
||||
),
|
||||
message: "this argument is passed by reference, but would be more efficient if passed by value\n#[warn(clippy::trivially_copy_pass_by_ref)] implied by #[warn(clippy::all)]\nfor further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref",
|
||||
related_information: Some(
|
||||
[
|
||||
DiagnosticRelatedInformation {
|
||||
location: Location {
|
||||
uri: "file:///test/compiler/lib.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 0,
|
||||
character: 8,
|
||||
},
|
||||
end: Position {
|
||||
line: 0,
|
||||
character: 19,
|
||||
},
|
||||
},
|
||||
},
|
||||
message: "lint level defined here",
|
||||
},
|
||||
DiagnosticRelatedInformation {
|
||||
location: Location {
|
||||
uri: "file:///test/compiler/mir/tagset.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 41,
|
||||
character: 23,
|
||||
},
|
||||
end: Position {
|
||||
line: 41,
|
||||
character: 28,
|
||||
},
|
||||
},
|
||||
},
|
||||
message: "consider passing by value instead",
|
||||
},
|
||||
],
|
||||
),
|
||||
tags: None,
|
||||
},
|
||||
fixes: [],
|
||||
},
|
||||
]
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
source: crates/rust-analyzer/src/diagnostics/to_proto.rs
|
||||
expression: diag
|
||||
---
|
||||
[
|
||||
MappedRustDiagnostic {
|
||||
location: Location {
|
||||
uri: "file:///test/src/main.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 1,
|
||||
character: 4,
|
||||
},
|
||||
end: Position {
|
||||
line: 1,
|
||||
character: 26,
|
||||
},
|
||||
},
|
||||
},
|
||||
diagnostic: Diagnostic {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 1,
|
||||
character: 4,
|
||||
},
|
||||
end: Position {
|
||||
line: 1,
|
||||
character: 26,
|
||||
},
|
||||
},
|
||||
severity: Some(
|
||||
Error,
|
||||
),
|
||||
code: Some(
|
||||
String(
|
||||
"E0277",
|
||||
),
|
||||
),
|
||||
source: Some(
|
||||
"rustc",
|
||||
),
|
||||
message: "can\'t compare `{integer}` with `&str`\nthe trait `std::cmp::PartialEq<&str>` is not implemented for `{integer}`",
|
||||
related_information: None,
|
||||
tags: None,
|
||||
},
|
||||
fixes: [],
|
||||
},
|
||||
]
|
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
source: crates/rust-analyzer/src/diagnostics/to_proto.rs
|
||||
expression: diag
|
||||
---
|
||||
[
|
||||
MappedRustDiagnostic {
|
||||
location: Location {
|
||||
uri: "file:///test/crates/ra_hir_def/src/data.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 79,
|
||||
character: 15,
|
||||
},
|
||||
end: Position {
|
||||
line: 79,
|
||||
character: 41,
|
||||
},
|
||||
},
|
||||
},
|
||||
diagnostic: Diagnostic {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 79,
|
||||
character: 15,
|
||||
},
|
||||
end: Position {
|
||||
line: 79,
|
||||
character: 41,
|
||||
},
|
||||
},
|
||||
severity: Some(
|
||||
Error,
|
||||
),
|
||||
code: None,
|
||||
source: Some(
|
||||
"rustc",
|
||||
),
|
||||
message: "Please register your known path in the path module",
|
||||
related_information: Some(
|
||||
[
|
||||
DiagnosticRelatedInformation {
|
||||
location: Location {
|
||||
uri: "file:///test/crates/ra_hir_def/src/path.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 264,
|
||||
character: 8,
|
||||
},
|
||||
end: Position {
|
||||
line: 264,
|
||||
character: 76,
|
||||
},
|
||||
},
|
||||
},
|
||||
message: "Error originated from macro here",
|
||||
},
|
||||
],
|
||||
),
|
||||
tags: None,
|
||||
},
|
||||
fixes: [],
|
||||
},
|
||||
]
|
|
@ -0,0 +1,114 @@
|
|||
---
|
||||
source: crates/rust-analyzer/src/diagnostics/to_proto.rs
|
||||
expression: diag
|
||||
---
|
||||
[
|
||||
MappedRustDiagnostic {
|
||||
location: Location {
|
||||
uri: "file:///test/src/main.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 3,
|
||||
character: 4,
|
||||
},
|
||||
end: Position {
|
||||
line: 3,
|
||||
character: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
diagnostic: Diagnostic {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 3,
|
||||
character: 4,
|
||||
},
|
||||
end: Position {
|
||||
line: 3,
|
||||
character: 5,
|
||||
},
|
||||
},
|
||||
severity: Some(
|
||||
Warning,
|
||||
),
|
||||
code: Some(
|
||||
String(
|
||||
"let_and_return",
|
||||
),
|
||||
),
|
||||
source: Some(
|
||||
"clippy",
|
||||
),
|
||||
message: "returning the result of a let binding from a block\n`#[warn(clippy::let_and_return)]` on by default\nfor further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return",
|
||||
related_information: Some(
|
||||
[
|
||||
DiagnosticRelatedInformation {
|
||||
location: Location {
|
||||
uri: "file:///test/src/main.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 2,
|
||||
character: 4,
|
||||
},
|
||||
end: Position {
|
||||
line: 2,
|
||||
character: 30,
|
||||
},
|
||||
},
|
||||
},
|
||||
message: "unnecessary let binding",
|
||||
},
|
||||
],
|
||||
),
|
||||
tags: None,
|
||||
},
|
||||
fixes: [
|
||||
CodeAction {
|
||||
title: "return the expression directly",
|
||||
kind: Some(
|
||||
"quickfix",
|
||||
),
|
||||
diagnostics: None,
|
||||
edit: Some(
|
||||
WorkspaceEdit {
|
||||
changes: Some(
|
||||
{
|
||||
"file:///test/src/main.rs": [
|
||||
TextEdit {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 2,
|
||||
character: 4,
|
||||
},
|
||||
end: Position {
|
||||
line: 2,
|
||||
character: 30,
|
||||
},
|
||||
},
|
||||
new_text: "",
|
||||
},
|
||||
TextEdit {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 3,
|
||||
character: 4,
|
||||
},
|
||||
end: Position {
|
||||
line: 3,
|
||||
character: 5,
|
||||
},
|
||||
},
|
||||
new_text: "(0..10).collect()",
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
document_changes: None,
|
||||
},
|
||||
),
|
||||
command: None,
|
||||
is_preferred: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
source: crates/rust-analyzer/src/diagnostics/to_proto.rs
|
||||
expression: diag
|
||||
---
|
||||
[
|
||||
MappedRustDiagnostic {
|
||||
location: Location {
|
||||
uri: "file:///test/compiler/ty/list_iter.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 51,
|
||||
character: 4,
|
||||
},
|
||||
end: Position {
|
||||
line: 51,
|
||||
character: 47,
|
||||
},
|
||||
},
|
||||
},
|
||||
diagnostic: Diagnostic {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 51,
|
||||
character: 4,
|
||||
},
|
||||
end: Position {
|
||||
line: 51,
|
||||
character: 47,
|
||||
},
|
||||
},
|
||||
severity: Some(
|
||||
Error,
|
||||
),
|
||||
code: Some(
|
||||
String(
|
||||
"E0053",
|
||||
),
|
||||
),
|
||||
source: Some(
|
||||
"rustc",
|
||||
),
|
||||
message: "method `next` has an incompatible type for trait\nexpected type `fn(&mut ty::list_iter::ListIterator<\'list, M>) -> std::option::Option<&ty::Ref<M>>`\n found type `fn(&ty::list_iter::ListIterator<\'list, M>) -> std::option::Option<&\'list ty::Ref<M>>`",
|
||||
related_information: None,
|
||||
tags: None,
|
||||
},
|
||||
fixes: [],
|
||||
},
|
||||
]
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
source: crates/rust-analyzer/src/diagnostics/to_proto.rs
|
||||
expression: diag
|
||||
---
|
||||
[
|
||||
MappedRustDiagnostic {
|
||||
location: Location {
|
||||
uri: "file:///test/runtime/compiler_support.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 47,
|
||||
character: 64,
|
||||
},
|
||||
end: Position {
|
||||
line: 47,
|
||||
character: 69,
|
||||
},
|
||||
},
|
||||
},
|
||||
diagnostic: Diagnostic {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 47,
|
||||
character: 64,
|
||||
},
|
||||
end: Position {
|
||||
line: 47,
|
||||
character: 69,
|
||||
},
|
||||
},
|
||||
severity: Some(
|
||||
Error,
|
||||
),
|
||||
code: Some(
|
||||
String(
|
||||
"E0308",
|
||||
),
|
||||
),
|
||||
source: Some(
|
||||
"rustc",
|
||||
),
|
||||
message: "mismatched types\nexpected usize, found u32",
|
||||
related_information: None,
|
||||
tags: None,
|
||||
},
|
||||
fixes: [],
|
||||
},
|
||||
]
|
|
@ -0,0 +1,86 @@
|
|||
---
|
||||
source: crates/rust-analyzer/src/diagnostics/to_proto.rs
|
||||
expression: diag
|
||||
---
|
||||
[
|
||||
MappedRustDiagnostic {
|
||||
location: Location {
|
||||
uri: "file:///test/driver/subcommand/repl.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 290,
|
||||
character: 8,
|
||||
},
|
||||
end: Position {
|
||||
line: 290,
|
||||
character: 11,
|
||||
},
|
||||
},
|
||||
},
|
||||
diagnostic: Diagnostic {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 290,
|
||||
character: 8,
|
||||
},
|
||||
end: Position {
|
||||
line: 290,
|
||||
character: 11,
|
||||
},
|
||||
},
|
||||
severity: Some(
|
||||
Warning,
|
||||
),
|
||||
code: Some(
|
||||
String(
|
||||
"unused_variables",
|
||||
),
|
||||
),
|
||||
source: Some(
|
||||
"rustc",
|
||||
),
|
||||
message: "unused variable: `foo`\n#[warn(unused_variables)] on by default",
|
||||
related_information: None,
|
||||
tags: Some(
|
||||
[
|
||||
Unnecessary,
|
||||
],
|
||||
),
|
||||
},
|
||||
fixes: [
|
||||
CodeAction {
|
||||
title: "consider prefixing with an underscore",
|
||||
kind: Some(
|
||||
"quickfix",
|
||||
),
|
||||
diagnostics: None,
|
||||
edit: Some(
|
||||
WorkspaceEdit {
|
||||
changes: Some(
|
||||
{
|
||||
"file:///test/driver/subcommand/repl.rs": [
|
||||
TextEdit {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 290,
|
||||
character: 8,
|
||||
},
|
||||
end: Position {
|
||||
line: 290,
|
||||
character: 11,
|
||||
},
|
||||
},
|
||||
new_text: "_foo",
|
||||
},
|
||||
],
|
||||
},
|
||||
),
|
||||
document_changes: None,
|
||||
},
|
||||
),
|
||||
command: None,
|
||||
is_preferred: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
|
@ -0,0 +1,67 @@
|
|||
---
|
||||
source: crates/rust-analyzer/src/diagnostics/to_proto.rs
|
||||
expression: diag
|
||||
---
|
||||
[
|
||||
MappedRustDiagnostic {
|
||||
location: Location {
|
||||
uri: "file:///test/compiler/ty/select.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 103,
|
||||
character: 17,
|
||||
},
|
||||
end: Position {
|
||||
line: 103,
|
||||
character: 29,
|
||||
},
|
||||
},
|
||||
},
|
||||
diagnostic: Diagnostic {
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 103,
|
||||
character: 17,
|
||||
},
|
||||
end: Position {
|
||||
line: 103,
|
||||
character: 29,
|
||||
},
|
||||
},
|
||||
severity: Some(
|
||||
Error,
|
||||
),
|
||||
code: Some(
|
||||
String(
|
||||
"E0061",
|
||||
),
|
||||
),
|
||||
source: Some(
|
||||
"rustc",
|
||||
),
|
||||
message: "this function takes 2 parameters but 3 parameters were supplied\nexpected 2 parameters",
|
||||
related_information: Some(
|
||||
[
|
||||
DiagnosticRelatedInformation {
|
||||
location: Location {
|
||||
uri: "file:///test/compiler/ty/select.rs",
|
||||
range: Range {
|
||||
start: Position {
|
||||
line: 218,
|
||||
character: 4,
|
||||
},
|
||||
end: Position {
|
||||
line: 230,
|
||||
character: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
message: "defined here",
|
||||
},
|
||||
],
|
||||
),
|
||||
tags: None,
|
||||
},
|
||||
fixes: [],
|
||||
},
|
||||
]
|
1408
crates/rust-analyzer/src/diagnostics/to_proto.rs
Normal file
1408
crates/rust-analyzer/src/diagnostics/to_proto.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -25,7 +25,7 @@ use lsp_types::{
|
|||
WorkDoneProgressBegin, WorkDoneProgressCreateParams, WorkDoneProgressEnd,
|
||||
WorkDoneProgressReport,
|
||||
};
|
||||
use ra_flycheck::{url_from_path_with_drive_lowercasing, CheckTask};
|
||||
use ra_flycheck::{CheckTask, Status};
|
||||
use ra_ide::{Canceled, FileId, LibraryData, LineIndex, SourceRootId};
|
||||
use ra_prof::profile;
|
||||
use ra_project_model::{PackageRoot, ProjectWorkspace};
|
||||
|
@ -37,7 +37,7 @@ use threadpool::ThreadPool;
|
|||
|
||||
use crate::{
|
||||
config::{Config, FilesWatcher},
|
||||
diagnostics::DiagnosticTask,
|
||||
diagnostics::{to_proto::url_from_path_with_drive_lowercasing, DiagnosticTask},
|
||||
from_proto, lsp_ext,
|
||||
main_loop::{
|
||||
pending_requests::{PendingRequest, PendingRequests},
|
||||
|
@ -736,22 +736,61 @@ fn on_check_task(
|
|||
task_sender.send(Task::Diagnostic(DiagnosticTask::ClearCheck))?;
|
||||
}
|
||||
|
||||
CheckTask::AddDiagnostic { url, diagnostic, fixes } => {
|
||||
let path = url.to_file_path().map_err(|()| format!("invalid uri: {}", url))?;
|
||||
let file_id = match world_state.vfs.read().path2file(&path) {
|
||||
Some(file) => FileId(file.0),
|
||||
None => {
|
||||
log::error!("File with cargo diagnostic not found in VFS: {}", path.display());
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
CheckTask::AddDiagnostic { workspace_root, diagnostic } => {
|
||||
let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
|
||||
&diagnostic,
|
||||
&workspace_root,
|
||||
);
|
||||
for diag in diagnostics {
|
||||
let path = diag
|
||||
.location
|
||||
.uri
|
||||
.to_file_path()
|
||||
.map_err(|()| format!("invalid uri: {}", diag.location.uri))?;
|
||||
let file_id = match world_state.vfs.read().path2file(&path) {
|
||||
Some(file) => FileId(file.0),
|
||||
None => {
|
||||
log::error!(
|
||||
"File with cargo diagnostic not found in VFS: {}",
|
||||
path.display()
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
};
|
||||
|
||||
task_sender
|
||||
.send(Task::Diagnostic(DiagnosticTask::AddCheck(file_id, diagnostic, fixes)))?;
|
||||
task_sender.send(Task::Diagnostic(DiagnosticTask::AddCheck(
|
||||
file_id,
|
||||
diag.diagnostic,
|
||||
diag.fixes.into_iter().map(|it| it.into()).collect(),
|
||||
)))?;
|
||||
}
|
||||
}
|
||||
|
||||
CheckTask::Status(progress) => {
|
||||
CheckTask::Status(status) => {
|
||||
if world_state.config.client_caps.work_done_progress {
|
||||
let progress = match status {
|
||||
Status::Being => {
|
||||
lsp_types::WorkDoneProgress::Begin(lsp_types::WorkDoneProgressBegin {
|
||||
title: "Running `cargo check`".to_string(),
|
||||
cancellable: Some(false),
|
||||
message: None,
|
||||
percentage: None,
|
||||
})
|
||||
}
|
||||
Status::Progress(target) => {
|
||||
lsp_types::WorkDoneProgress::Report(lsp_types::WorkDoneProgressReport {
|
||||
cancellable: Some(false),
|
||||
message: Some(target),
|
||||
percentage: None,
|
||||
})
|
||||
}
|
||||
Status::End => {
|
||||
lsp_types::WorkDoneProgress::End(lsp_types::WorkDoneProgressEnd {
|
||||
message: None,
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
let params = lsp_types::ProgressParams {
|
||||
token: lsp_types::ProgressToken::String(
|
||||
"rustAnalyzer/cargoWatcher".to_string(),
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::{
|
|||
use crossbeam_channel::{unbounded, Receiver};
|
||||
use lsp_types::Url;
|
||||
use parking_lot::RwLock;
|
||||
use ra_flycheck::{url_from_path_with_drive_lowercasing, Flycheck, FlycheckConfig};
|
||||
use ra_flycheck::{Flycheck, FlycheckConfig};
|
||||
use ra_ide::{
|
||||
Analysis, AnalysisChange, AnalysisHost, CrateGraph, FileId, LibraryData, SourceRootId,
|
||||
};
|
||||
|
@ -22,7 +22,9 @@ use stdx::format_to;
|
|||
|
||||
use crate::{
|
||||
config::Config,
|
||||
diagnostics::{CheckFixes, DiagnosticCollection},
|
||||
diagnostics::{
|
||||
to_proto::url_from_path_with_drive_lowercasing, CheckFixes, DiagnosticCollection,
|
||||
},
|
||||
main_loop::pending_requests::{CompletedRequest, LatestRequests},
|
||||
vfs_glob::{Glob, RustPackageFilterBuilder},
|
||||
LspError, Result,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue