mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-10 12:18:49 +00:00
65 lines
1.7 KiB
Rust
65 lines
1.7 KiB
Rust
|
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<Vec<Assist>> {
|
||
|
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 }"#);
|
||
|
}
|
||
|
}
|