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.rs61
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;