Simplify diagnostic construction, add unused field

This commit is contained in:
Jonas Schievink 2020-10-20 17:48:43 +02:00
parent f925735e64
commit a54e481646
3 changed files with 55 additions and 64 deletions

View file

@ -31,6 +31,21 @@ pub struct Diagnostic {
pub range: TextRange, pub range: TextRange,
pub severity: Severity, pub severity: Severity,
pub fix: Option<Fix>, pub fix: Option<Fix>,
pub unused: bool,
}
impl Diagnostic {
fn error(range: TextRange, message: String) -> Self {
Self { message, range, severity: Severity::Error, fix: None, unused: false }
}
fn hint(range: TextRange, message: String) -> Self {
Self { message, range, severity: Severity::WeakWarning, fix: None, unused: false }
}
fn with_fix(self, fix: Option<Fix>) -> Self {
Self { fix, ..self }
}
} }
#[derive(Debug)] #[derive(Debug)]
@ -71,13 +86,13 @@ pub(crate) fn diagnostics(
let mut res = Vec::new(); let mut res = Vec::new();
// [#34344] Only take first 128 errors to prevent slowing down editor/ide, the number 128 is chosen arbitrarily. // [#34344] Only take first 128 errors to prevent slowing down editor/ide, the number 128 is chosen arbitrarily.
res.extend(parse.errors().iter().take(128).map(|err| Diagnostic { res.extend(
// name: None, parse
range: err.range(), .errors()
message: format!("Syntax Error: {}", err), .iter()
severity: Severity::Error, .take(128)
fix: None, .map(|err| Diagnostic::error(err.range(), format!("Syntax Error: {}", err))),
})); );
for node in parse.tree().syntax().descendants() { for node in parse.tree().syntax().descendants() {
check_unnecessary_braces_in_use_statement(&mut res, file_id, &node); check_unnecessary_braces_in_use_statement(&mut res, file_id, &node);
@ -108,13 +123,8 @@ pub(crate) fn diagnostics(
let mut sink = sink_builder let mut sink = sink_builder
// Diagnostics not handled above get no fix and default treatment. // Diagnostics not handled above get no fix and default treatment.
.build(|d| { .build(|d| {
res.borrow_mut().push(Diagnostic { res.borrow_mut()
// name: Some(d.name().into()), .push(Diagnostic::error(sema.diagnostics_display_range(d).range, d.message()));
message: d.message(),
range: sema.diagnostics_display_range(d).range,
severity: Severity::Error,
fix: None,
})
}); });
if let Some(m) = sema.to_module_def(file_id) { if let Some(m) = sema.to_module_def(file_id) {
@ -125,22 +135,11 @@ pub(crate) fn diagnostics(
} }
fn diagnostic_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { fn diagnostic_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic {
Diagnostic { Diagnostic::error(sema.diagnostics_display_range(d).range, d.message()).with_fix(d.fix(&sema))
// name: Some(d.name().into()),
range: sema.diagnostics_display_range(d).range,
message: d.message(),
severity: Severity::Error,
fix: d.fix(&sema),
}
} }
fn warning_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic { fn warning_with_fix<D: DiagnosticWithFix>(d: &D, sema: &Semantics<RootDatabase>) -> Diagnostic {
Diagnostic { Diagnostic::hint(sema.diagnostics_display_range(d).range, d.message()).with_fix(d.fix(&sema))
range: sema.diagnostics_display_range(d).range,
message: d.message(),
severity: Severity::WeakWarning,
fix: d.fix(&sema),
}
} }
fn check_unnecessary_braces_in_use_statement( fn check_unnecessary_braces_in_use_statement(
@ -161,17 +160,14 @@ fn check_unnecessary_braces_in_use_statement(
edit_builder.finish() edit_builder.finish()
}); });
acc.push(Diagnostic { acc.push(
// name: None, Diagnostic::hint(use_range, "Unnecessary braces in use statement".to_string())
range: use_range, .with_fix(Some(Fix::new(
message: "Unnecessary braces in use statement".to_string(),
severity: Severity::WeakWarning,
fix: Some(Fix::new(
"Remove unnecessary braces", "Remove unnecessary braces",
SourceFileEdit { file_id, edit }.into(), SourceFileEdit { file_id, edit }.into(),
use_range, use_range,
)), ))),
}); );
} }
Some(()) Some(())
@ -578,6 +574,7 @@ fn test_fn() {
fix_trigger_range: 0..8, fix_trigger_range: 0..8,
}, },
), ),
unused: false,
}, },
] ]
"#]], "#]],

View file

@ -6,7 +6,7 @@ use ide_db::source_change::SourceFileEdit;
use syntax::{ast, match_ast, AstNode, SyntaxNode}; use syntax::{ast, match_ast, AstNode, SyntaxNode};
use text_edit::TextEdit; use text_edit::TextEdit;
use crate::{Diagnostic, Fix, Severity}; use crate::{Diagnostic, Fix};
pub(super) fn check(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &SyntaxNode) { pub(super) fn check(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &SyntaxNode) {
match_ast! { match_ast! {
@ -46,17 +46,15 @@ fn check_expr_field_shorthand(
let edit = edit_builder.finish(); let edit = edit_builder.finish();
let field_range = record_field.syntax().text_range(); let field_range = record_field.syntax().text_range();
acc.push(Diagnostic { acc.push(
// name: None, Diagnostic::hint(field_range, "Shorthand struct initialization".to_string()).with_fix(
range: field_range, Some(Fix::new(
message: "Shorthand struct initialization".to_string(),
severity: Severity::WeakWarning,
fix: Some(Fix::new(
"Use struct shorthand initialization", "Use struct shorthand initialization",
SourceFileEdit { file_id, edit }.into(), SourceFileEdit { file_id, edit }.into(),
field_range, field_range,
)), )),
}); ),
);
} }
} }
@ -88,17 +86,13 @@ fn check_pat_field_shorthand(
let edit = edit_builder.finish(); let edit = edit_builder.finish();
let field_range = record_pat_field.syntax().text_range(); let field_range = record_pat_field.syntax().text_range();
acc.push(Diagnostic { acc.push(Diagnostic::hint(field_range, "Shorthand struct pattern".to_string()).with_fix(
// name: None, Some(Fix::new(
range: field_range,
message: "Shorthand struct pattern".to_string(),
severity: Severity::WeakWarning,
fix: Some(Fix::new(
"Use struct field shorthand", "Use struct field shorthand",
SourceFileEdit { file_id, edit }.into(), SourceFileEdit { file_id, edit }.into(),
field_range, field_range,
)), )),
}); ));
} }
} }

View file

@ -16,12 +16,12 @@ use lsp_server::ErrorCode;
use lsp_types::{ use lsp_types::{
CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem, CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams, CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams,
CodeActionKind, CodeLens, Command, CompletionItem, Diagnostic, DocumentFormattingParams, CodeActionKind, CodeLens, Command, CompletionItem, Diagnostic, DiagnosticTag,
DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams, HoverContents, Location, DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams,
Position, PrepareRenameResponse, Range, RenameParams, SemanticTokensDeltaParams, HoverContents, Location, Position, PrepareRenameResponse, Range, RenameParams,
SemanticTokensFullDeltaResult, SemanticTokensParams, SemanticTokensRangeParams, SemanticTokensDeltaParams, SemanticTokensFullDeltaResult, SemanticTokensParams,
SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation, SymbolTag, SemanticTokensRangeParams, SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation,
TextDocumentIdentifier, Url, WorkspaceEdit, SymbolTag, TextDocumentIdentifier, Url, WorkspaceEdit,
}; };
use project_model::TargetKind; use project_model::TargetKind;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -1124,7 +1124,7 @@ pub(crate) fn publish_diagnostics(
source: Some("rust-analyzer".to_string()), source: Some("rust-analyzer".to_string()),
message: d.message, message: d.message,
related_information: None, related_information: None,
tags: None, tags: if d.unused { Some(vec![DiagnosticTag::Unnecessary]) } else { None },
}) })
.collect(); .collect();
Ok(diagnostics) Ok(diagnostics)