From 74f3cca85ab870614f314c6180e2fbb883ad4fe3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 13 Jun 2021 20:13:15 +0300 Subject: internal: refactor remove this semicolon diagnostics --- .../ide/src/diagnostics/remove_this_semicolon.rs | 64 ++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 crates/ide/src/diagnostics/remove_this_semicolon.rs (limited to 'crates/ide/src/diagnostics/remove_this_semicolon.rs') diff --git a/crates/ide/src/diagnostics/remove_this_semicolon.rs b/crates/ide/src/diagnostics/remove_this_semicolon.rs new file mode 100644 index 000000000..814cb0f8c --- /dev/null +++ b/crates/ide/src/diagnostics/remove_this_semicolon.rs @@ -0,0 +1,64 @@ +use hir::db::AstDatabase; +use ide_db::source_change::SourceChange; +use syntax::{ast, AstNode}; +use text_edit::TextEdit; + +use crate::{ + diagnostics::{fix, Diagnostic, DiagnosticsContext}, + Assist, +}; + +// Diagnostic: remove-this-semicolon +// +// This diagnostic is triggered when there's an erroneous `;` at the end of the block. +pub(super) fn remove_this_semicolon( + ctx: &DiagnosticsContext<'_>, + d: &hir::RemoveThisSemicolon, +) -> Diagnostic { + Diagnostic::new( + "remove-this-semicolon", + "remove this semicolon", + ctx.sema.diagnostics_display_range(d.expr.clone().map(|it| it.into())).range, + ) + .with_fixes(fixes(ctx, d)) +} + +fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::RemoveThisSemicolon) -> Option> { + let root = ctx.sema.db.parse_or_expand(d.expr.file_id)?; + + let semicolon = d + .expr + .value + .to_node(&root) + .syntax() + .parent() + .and_then(ast::ExprStmt::cast) + .and_then(|expr| expr.semicolon_token())? + .text_range(); + + let edit = TextEdit::delete(semicolon); + let source_change = + SourceChange::from_text_edit(d.expr.file_id.original_file(ctx.sema.db), edit); + + Some(vec![fix("remove_semicolon", "Remove this semicolon", source_change, semicolon)]) +} + +#[cfg(test)] +mod tests { + use crate::diagnostics::tests::{check_diagnostics, check_fix}; + + #[test] + fn missing_semicolon() { + check_diagnostics( + r#" +fn test() -> i32 { 123; } + //^^^ remove this semicolon +"#, + ); + } + + #[test] + fn remove_semicolon() { + check_fix(r#"fn f() -> i32 { 92$0; }"#, r#"fn f() -> i32 { 92 }"#); + } +} -- cgit v1.2.3