Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs')
| -rw-r--r-- | crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs | 61 |
1 files changed, 30 insertions, 31 deletions
diff --git a/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs b/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs index 3b8988db7a..635fab857d 100644 --- a/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs +++ b/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs @@ -1,8 +1,7 @@ use ide_db::source_change::SourceChangeBuilder; -use itertools::Itertools; use syntax::{ NodeOrToken, SyntaxToken, T, TextRange, algo, - ast::{self, AstNode, edit::AstNodeEdit, make, syntax_factory::SyntaxFactory}, + ast::{self, AstNode, edit::AstNodeEdit}, }; use crate::{AssistContext, AssistId, Assists}; @@ -151,7 +150,7 @@ pub(crate) fn wrap_unwrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>) - if let [attr] = &attrs[..] && let Some(ast::Meta::CfgAttrMeta(meta)) = attr.meta() { - unwrap_cfg_attr(acc, meta) + unwrap_cfg_attr(acc, ctx, meta) } else { wrap_cfg_attrs(acc, ctx, attrs) } @@ -192,8 +191,8 @@ fn wrap_derive( } } let handle_source_change = |edit: &mut SourceChangeBuilder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = edit.make_editor(attr.syntax()); + let editor = edit.make_editor(attr.syntax()); + let make = editor.make(); let new_derive = make.attr_outer( make.meta_token_tree(make.ident_path("derive"), make.token_tree(T!['('], new_derive)), ); @@ -221,8 +220,6 @@ fn wrap_derive( let tabstop = edit.make_placeholder_snippet(snippet_cap); editor.add_annotation(cfg_predicate.syntax(), tabstop); } - - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }; @@ -239,8 +236,8 @@ fn wrap_cfg_attrs(acc: &mut Assists, ctx: &AssistContext<'_>, attrs: Vec<ast::At let (first_attr, last_attr) = (attrs.first()?, attrs.last()?); let range = first_attr.syntax().text_range().cover(last_attr.syntax().text_range()); let handle_source_change = |edit: &mut SourceChangeBuilder| { - let make = SyntaxFactory::with_mappings(); - let mut editor = edit.make_editor(first_attr.syntax()); + let editor = edit.make_editor(first_attr.syntax()); + let make = editor.make(); let meta = make.cfg_attr_meta(make.cfg_flag("cfg"), attrs.iter().filter_map(|attr| attr.meta())); let cfg_attr = if first_attr.excl_token().is_some() { @@ -258,8 +255,6 @@ fn wrap_cfg_attrs(acc: &mut Assists, ctx: &AssistContext<'_>, attrs: Vec<ast::At let tabstop = edit.make_placeholder_snippet(snippet_cap); editor.add_annotation(cfg_flag.syntax(), tabstop); } - - editor.add_mappings(make.finish_with_mappings()); edit.add_file_edits(ctx.vfs_file_id(), editor); }; acc.add( @@ -271,37 +266,41 @@ fn wrap_cfg_attrs(acc: &mut Assists, ctx: &AssistContext<'_>, attrs: Vec<ast::At Some(()) } -fn unwrap_cfg_attr(acc: &mut Assists, meta: ast::CfgAttrMeta) -> Option<()> { +fn unwrap_cfg_attr( + acc: &mut Assists, + ctx: &AssistContext<'_>, + meta: ast::CfgAttrMeta, +) -> Option<()> { let top_attr = ast::Meta::from(meta.clone()).parent_attr()?; let range = top_attr.syntax().text_range(); - let inner_attrs = meta - .metas() - .map(|meta| { - if top_attr.excl_token().is_some() { - make::attr_inner(meta) - } else { - make::attr_outer(meta) - } - }) - .collect::<Vec<_>>(); - if inner_attrs.is_empty() { + let inner_metas: Vec<ast::Meta> = meta.metas().collect(); + if inner_metas.is_empty() { return None; } - let handle_source_change = |f: &mut SourceChangeBuilder| { - let inner_attrs = inner_attrs - .iter() - .map(|it| it.to_string()) - .join(&format!("\n{}", top_attr.indent_level())); - f.replace(range, inner_attrs); - }; + let is_inner = top_attr.excl_token().is_some(); + let indent = top_attr.indent_level(); acc.add( AssistId::refactor("wrap_unwrap_cfg_attr"), "Extract Inner Attributes from `cfg_attr`", range, - handle_source_change, + |builder: &mut SourceChangeBuilder| { + let editor = builder.make_editor(top_attr.syntax()); + let make = editor.make(); + let mut elements = vec![]; + for (i, meta) in inner_metas.into_iter().enumerate() { + if i > 0 { + elements.push(make.whitespace(&format!("\n{indent}")).into()); + } + let attr = if is_inner { make.attr_inner(meta) } else { make.attr_outer(meta) }; + elements.push(attr.syntax().clone().into()); + } + editor.replace_with_many(top_attr.syntax(), elements); + builder.add_file_edits(ctx.vfs_file_id(), editor); + }, ); Some(()) } + #[cfg(test)] mod tests { use crate::tests::check_assist; |