From 58712088ac2114e41d754ec6bcb5cd6bc3625256 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 14 Jun 2021 21:23:59 +0300 Subject: minor: make diagnostics more similar --- .../ide_diagnostics/src/handlers/useless_braces.rs | 148 +++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 crates/ide_diagnostics/src/handlers/useless_braces.rs (limited to 'crates/ide_diagnostics/src/handlers/useless_braces.rs') diff --git a/crates/ide_diagnostics/src/handlers/useless_braces.rs b/crates/ide_diagnostics/src/handlers/useless_braces.rs new file mode 100644 index 000000000..8b9330e04 --- /dev/null +++ b/crates/ide_diagnostics/src/handlers/useless_braces.rs @@ -0,0 +1,148 @@ +use ide_db::{base_db::FileId, source_change::SourceChange}; +use itertools::Itertools; +use syntax::{ast, AstNode, SyntaxNode, TextRange}; +use text_edit::TextEdit; + +use crate::{fix, Diagnostic, Severity}; + +// Diagnostic: unnecessary-braces +// +// Diagnostic for unnecessary braces in `use` items. +pub(crate) fn useless_braces( + acc: &mut Vec, + file_id: FileId, + node: &SyntaxNode, +) -> Option<()> { + let use_tree_list = ast::UseTreeList::cast(node.clone())?; + if let Some((single_use_tree,)) = use_tree_list.use_trees().collect_tuple() { + // If there is a comment inside the bracketed `use`, + // assume it is a commented out module path and don't show diagnostic. + if use_tree_list.has_inner_comment() { + return Some(()); + } + + let use_range = use_tree_list.syntax().text_range(); + let edit = remove_braces(&single_use_tree).unwrap_or_else(|| { + let to_replace = single_use_tree.syntax().text().to_string(); + let mut edit_builder = TextEdit::builder(); + edit_builder.delete(use_range); + edit_builder.insert(use_range.start(), to_replace); + edit_builder.finish() + }); + + acc.push( + Diagnostic::new( + "unnecessary-braces", + "Unnecessary braces in use statement".to_string(), + use_range, + ) + .severity(Severity::WeakWarning) + .with_fixes(Some(vec![fix( + "remove_braces", + "Remove unnecessary braces", + SourceChange::from_text_edit(file_id, edit), + use_range, + )])), + ); + } + + Some(()) +} + +fn remove_braces(single_use_tree: &ast::UseTree) -> Option { + let use_tree_list_node = single_use_tree.syntax().parent()?; + if single_use_tree.path()?.segment()?.self_token().is_some() { + let start = use_tree_list_node.prev_sibling_or_token()?.text_range().start(); + let end = use_tree_list_node.text_range().end(); + return Some(TextEdit::delete(TextRange::new(start, end))); + } + None +} + +#[cfg(test)] +mod tests { + use crate::tests::{check_diagnostics, check_fix}; + + #[test] + fn test_check_unnecessary_braces_in_use_statement() { + check_diagnostics( + r#" +use a; +use a::{c, d::e}; + +mod a { + mod c {} + mod d { + mod e {} + } +} +"#, + ); + check_diagnostics( + r#" +use a; +use a::{ + c, + // d::e +}; + +mod a { + mod c {} + mod d { + mod e {} + } +} +"#, + ); + check_fix( + r#" +mod b {} +use {$0b}; +"#, + r#" +mod b {} +use b; +"#, + ); + check_fix( + r#" +mod b {} +use {b$0}; +"#, + r#" +mod b {} +use b; +"#, + ); + check_fix( + r#" +mod a { mod c {} } +use a::{c$0}; +"#, + r#" +mod a { mod c {} } +use a::c; +"#, + ); + check_fix( + r#" +mod a {} +use a::{self$0}; +"#, + r#" +mod a {} +use a; +"#, + ); + check_fix( + r#" +mod a { mod c {} mod d { mod e {} } } +use a::{c, d::{e$0}}; +"#, + r#" +mod a { mod c {} mod d { mod e {} } } +use a::{c, d::e}; +"#, + ); + } +} -- cgit v1.2.3