Warnings as hint or info

This commit is contained in:
Gabriel Valfridsson
2020-06-16 22:26:33 +02:00
parent 5d7974e5fb
commit 656e95211e
7 changed files with 402 additions and 13 deletions

View File

@@ -9,6 +9,7 @@
use std::{ffi::OsString, path::PathBuf};
use crate::diagnostics::DiagnosticsConfig;
use lsp_types::ClientCapabilities;
use ra_flycheck::FlycheckConfig;
use ra_ide::{AssistConfig, CompletionConfig, HoverConfig, InlayHintsConfig};
@@ -20,6 +21,7 @@ pub struct Config {
pub client_caps: ClientCapsConfig,
pub publish_diagnostics: bool,
pub diagnostics: DiagnosticsConfig,
pub lru_capacity: Option<usize>,
pub proc_macro_srv: Option<(PathBuf, Vec<OsString>)>,
pub files: FilesConfig,
@@ -136,6 +138,7 @@ impl Default for Config {
with_sysroot: true,
publish_diagnostics: true,
diagnostics: DiagnosticsConfig::default(),
lru_capacity: None,
proc_macro_srv: None,
files: FilesConfig { watcher: FilesWatcher::Notify, exclude: Vec::new() },
@@ -184,6 +187,8 @@ impl Config {
set(value, "/withSysroot", &mut self.with_sysroot);
set(value, "/diagnostics/enable", &mut self.publish_diagnostics);
set(value, "/diagnostics/warningsAsInfo", &mut self.diagnostics.warnings_as_info);
set(value, "/diagnostics/warningsAsHint", &mut self.diagnostics.warnings_as_hint);
set(value, "/lruCapacity", &mut self.lru_capacity);
self.files.watcher = match get(value, "/files/watcher") {
Some("client") => FilesWatcher::Client,

View File

@@ -10,6 +10,12 @@ use crate::lsp_ext;
pub type CheckFixes = Arc<HashMap<FileId, Vec<Fix>>>;
#[derive(Debug, Default, Clone)]
pub struct DiagnosticsConfig {
pub warnings_as_info: Vec<String>,
pub warnings_as_hint: Vec<String>,
}
#[derive(Debug, Default, Clone)]
pub struct DiagnosticCollection {
pub native: HashMap<FileId, Vec<Diagnostic>>,

View File

@@ -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(
Hint,
),
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",
id: None,
group: None,
kind: Some(
"quickfix",
),
command: None,
edit: Some(
SnippetWorkspaceEdit {
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,
},
),
},
],
},
]

View File

@@ -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(
Information,
),
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",
id: None,
group: None,
kind: Some(
"quickfix",
),
command: None,
edit: Some(
SnippetWorkspaceEdit {
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,
},
),
},
],
},
]

View File

@@ -9,14 +9,24 @@ use lsp_types::{
use ra_flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan, DiagnosticSpanMacroExpansion};
use stdx::format_to;
use super::DiagnosticsConfig;
use crate::{lsp_ext, to_proto::url_from_abs_path};
/// Converts a Rust level string to a LSP severity
fn map_level_to_severity(val: DiagnosticLevel) -> Option<DiagnosticSeverity> {
let res = match val {
/// Determines the LSP severity from a diagnostic
fn map_diagnostic_to_severity(
config: &DiagnosticsConfig,
val: &ra_flycheck::Diagnostic,
) -> Option<DiagnosticSeverity> {
let res = match val.level {
DiagnosticLevel::Ice => DiagnosticSeverity::Error,
DiagnosticLevel::Error => DiagnosticSeverity::Error,
DiagnosticLevel::Warning => DiagnosticSeverity::Warning,
DiagnosticLevel::Warning => match &val.code {
Some(code) if config.warnings_as_hint.contains(&code.code) => DiagnosticSeverity::Hint,
Some(code) if config.warnings_as_info.contains(&code.code) => {
DiagnosticSeverity::Information
}
_ => DiagnosticSeverity::Warning,
},
DiagnosticLevel::Note => DiagnosticSeverity::Information,
DiagnosticLevel::Help => DiagnosticSeverity::Hint,
DiagnosticLevel::Unknown => return None,
@@ -172,6 +182,7 @@ pub(crate) struct MappedRustDiagnostic {
///
/// If the diagnostic has no primary span this will return `None`
pub(crate) fn map_rust_diagnostic_to_lsp(
config: &DiagnosticsConfig,
rd: &ra_flycheck::Diagnostic,
workspace_root: &Path,
) -> Vec<MappedRustDiagnostic> {
@@ -180,7 +191,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp(
return Vec::new();
}
let severity = map_level_to_severity(rd.level);
let severity = map_diagnostic_to_severity(config, rd);
let mut source = String::from("rustc");
let mut code = rd.code.as_ref().map(|c| c.code.clone());
@@ -328,7 +339,7 @@ mod tests {
);
let workspace_root = Path::new("/test/");
let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root);
let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root);
insta::assert_debug_snapshot!(diag);
}
@@ -410,7 +421,183 @@ mod tests {
);
let workspace_root = Path::new("/test/");
let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root);
let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root);
insta::assert_debug_snapshot!(diag);
}
#[test]
#[cfg(not(windows))]
fn snap_rustc_unused_variable_as_info() {
let diag = parse_diagnostic(
r##"{
"message": "unused variable: `foo`",
"code": {
"code": "unused_variables",
"explanation": null
},
"level": "warning",
"spans": [
{
"file_name": "driver/subcommand/repl.rs",
"byte_start": 9228,
"byte_end": 9231,
"line_start": 291,
"line_end": 291,
"column_start": 9,
"column_end": 12,
"is_primary": true,
"text": [
{
"text": " let foo = 42;",
"highlight_start": 9,
"highlight_end": 12
}
],
"label": null,
"suggested_replacement": null,
"suggestion_applicability": null,
"expansion": null
}
],
"children": [
{
"message": "#[warn(unused_variables)] on by default",
"code": null,
"level": "note",
"spans": [],
"children": [],
"rendered": null
},
{
"message": "consider prefixing with an underscore",
"code": null,
"level": "help",
"spans": [
{
"file_name": "driver/subcommand/repl.rs",
"byte_start": 9228,
"byte_end": 9231,
"line_start": 291,
"line_end": 291,
"column_start": 9,
"column_end": 12,
"is_primary": true,
"text": [
{
"text": " let foo = 42;",
"highlight_start": 9,
"highlight_end": 12
}
],
"label": null,
"suggested_replacement": "_foo",
"suggestion_applicability": "MachineApplicable",
"expansion": null
}
],
"children": [],
"rendered": null
}
],
"rendered": "warning: unused variable: `foo`\n --> driver/subcommand/repl.rs:291:9\n |\n291 | let foo = 42;\n | ^^^ help: consider prefixing with an underscore: `_foo`\n |\n = note: #[warn(unused_variables)] on by default\n\n"
}"##,
);
let config = DiagnosticsConfig {
warnings_as_info: vec!["unused_variables".to_string()],
..DiagnosticsConfig::default()
};
let workspace_root = Path::new("/test/");
let diag = map_rust_diagnostic_to_lsp(&config, &diag, workspace_root);
insta::assert_debug_snapshot!(diag);
}
#[test]
#[cfg(not(windows))]
fn snap_rustc_unused_variable_as_hint() {
let diag = parse_diagnostic(
r##"{
"message": "unused variable: `foo`",
"code": {
"code": "unused_variables",
"explanation": null
},
"level": "warning",
"spans": [
{
"file_name": "driver/subcommand/repl.rs",
"byte_start": 9228,
"byte_end": 9231,
"line_start": 291,
"line_end": 291,
"column_start": 9,
"column_end": 12,
"is_primary": true,
"text": [
{
"text": " let foo = 42;",
"highlight_start": 9,
"highlight_end": 12
}
],
"label": null,
"suggested_replacement": null,
"suggestion_applicability": null,
"expansion": null
}
],
"children": [
{
"message": "#[warn(unused_variables)] on by default",
"code": null,
"level": "note",
"spans": [],
"children": [],
"rendered": null
},
{
"message": "consider prefixing with an underscore",
"code": null,
"level": "help",
"spans": [
{
"file_name": "driver/subcommand/repl.rs",
"byte_start": 9228,
"byte_end": 9231,
"line_start": 291,
"line_end": 291,
"column_start": 9,
"column_end": 12,
"is_primary": true,
"text": [
{
"text": " let foo = 42;",
"highlight_start": 9,
"highlight_end": 12
}
],
"label": null,
"suggested_replacement": "_foo",
"suggestion_applicability": "MachineApplicable",
"expansion": null
}
],
"children": [],
"rendered": null
}
],
"rendered": "warning: unused variable: `foo`\n --> driver/subcommand/repl.rs:291:9\n |\n291 | let foo = 42;\n | ^^^ help: consider prefixing with an underscore: `_foo`\n |\n = note: #[warn(unused_variables)] on by default\n\n"
}"##,
);
let config = DiagnosticsConfig {
warnings_as_hint: vec!["unused_variables".to_string()],
..DiagnosticsConfig::default()
};
let workspace_root = Path::new("/test/");
let diag = map_rust_diagnostic_to_lsp(&config, &diag, workspace_root);
insta::assert_debug_snapshot!(diag);
}
@@ -534,7 +721,7 @@ mod tests {
);
let workspace_root = Path::new("/test/");
let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root);
let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root);
insta::assert_debug_snapshot!(diag);
}
@@ -654,7 +841,7 @@ mod tests {
);
let workspace_root = Path::new("/test/");
let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root);
let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root);
insta::assert_debug_snapshot!(diag);
}
@@ -697,7 +884,7 @@ mod tests {
);
let workspace_root = Path::new("/test/");
let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root);
let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root);
insta::assert_debug_snapshot!(diag);
}
@@ -968,7 +1155,7 @@ mod tests {
);
let workspace_root = Path::new("/test/");
let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root);
let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root);
insta::assert_debug_snapshot!(diag);
}
@@ -1197,7 +1384,7 @@ mod tests {
);
let workspace_root = Path::new("/test/");
let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root);
let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root);
insta::assert_debug_snapshot!(diag);
}
@@ -1330,7 +1517,7 @@ mod tests {
);
let workspace_root = Path::new("/test/");
let diag = map_rust_diagnostic_to_lsp(&diag, workspace_root);
let diag = map_rust_diagnostic_to_lsp(&DiagnosticsConfig::default(), &diag, workspace_root);
insta::assert_debug_snapshot!(diag);
}
}

View File

@@ -734,6 +734,7 @@ fn on_check_task(
CheckTask::AddDiagnostic { workspace_root, diagnostic } => {
let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
&global_state.config.diagnostics,
&diagnostic,
&workspace_root,
);