Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/convert_let_else_to_match.rs')
-rw-r--r--crates/ide-assists/src/handlers/convert_let_else_to_match.rs181
1 files changed, 87 insertions, 94 deletions
diff --git a/crates/ide-assists/src/handlers/convert_let_else_to_match.rs b/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
index 994fb44279..75d7d0a836 100644
--- a/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
+++ b/crates/ide-assists/src/handlers/convert_let_else_to_match.rs
@@ -1,7 +1,6 @@
use syntax::T;
use syntax::ast::RangeItem;
use syntax::ast::edit::AstNodeEdit;
-use syntax::ast::syntax_factory::SyntaxFactory;
use syntax::ast::{self, AstNode, HasName, LetStmt, Pat};
use syntax::syntax_editor::SyntaxEditor;
@@ -26,15 +25,13 @@ use crate::{AssistContext, AssistId, Assists};
// }
// ```
pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
- let root = ctx.source_file().syntax().clone();
- let (mut editor, _) = SyntaxEditor::new(root);
+ let (mut editor, _) = SyntaxEditor::new(ctx.source_file().syntax().clone());
// Should focus on the `else` token to trigger
let let_stmt = ctx
.find_token_syntax_at_offset(T![else])
.and_then(|it| it.parent()?.parent())
.or_else(|| ctx.find_token_syntax_at_offset(T![let])?.parent())?;
let let_stmt = LetStmt::cast(let_stmt)?;
- let make = SyntaxFactory::with_mappings();
let else_block = let_stmt.let_else()?.block_expr()?;
let else_expr = if else_block.statements().next().is_none()
&& let Some(tail_expr) = else_block.tail_expr()
@@ -50,7 +47,7 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'
}
let pat = let_stmt.pat()?;
let mut idents = Vec::default();
- let pat_without_mut = remove_mut_and_collect_idents(&make, &mut editor, &pat, &mut idents)?;
+ let pat_without_mut = remove_mut_and_collect_idents(&mut editor, &pat, &mut idents)?;
let bindings = idents
.into_iter()
.filter_map(|ref pat| {
@@ -72,14 +69,14 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'
},
let_stmt.syntax().text_range(),
|builder| {
- // let mut editor = builder.make_editor(let_stmt.syntax());
-
let binding_paths = bindings
.iter()
- .map(|(name, _)| make.expr_path(make.ident_path(&name.to_string())))
+ .map(|(name, _)| {
+ editor.make().expr_path(editor.make().ident_path(&name.to_string()))
+ })
.collect::<Vec<_>>();
- let binding_arm = make.match_arm(
+ let binding_arm = editor.make().match_arm(
pat_without_mut,
None,
// There are three possible cases:
@@ -88,15 +85,16 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'
// - Single binding: `Some(it) => it`
// - Multiple bindings: `Foo::Bar { a, b, .. } => (a, b)`
match binding_paths.len() {
- 0 => make.expr_empty_block().into(),
+ 0 => editor.make().expr_empty_block().into(),
1 => binding_paths[0].clone(),
- _ => make.expr_tuple(binding_paths).into(),
+ _ => editor.make().expr_tuple(binding_paths).into(),
},
);
- let else_arm = make.match_arm(make.wildcard_pat().into(), None, else_expr);
+ let else_arm =
+ editor.make().match_arm(editor.make().wildcard_pat().into(), None, else_expr);
let arms = [binding_arm, else_arm].map(|arm| arm.indent(1.into()));
- let match_ = make.expr_match(init, make.match_arm_list(arms));
+ let match_ = editor.make().expr_match(init, editor.make().match_arm_list(arms));
let match_ = match_.indent(let_stmt.indent_level());
if bindings.is_empty() {
@@ -104,28 +102,25 @@ pub(crate) fn convert_let_else_to_match(acc: &mut Assists, ctx: &AssistContext<'
} else {
let ident_pats = bindings
.into_iter()
- .map(|(name, is_mut)| make.ident_pat(false, is_mut, name).into())
+ .map(|(name, is_mut)| editor.make().ident_pat(false, is_mut, name).into())
.collect::<Vec<Pat>>();
- let new_let_stmt = make.let_stmt(
+ let new_let_stmt = editor.make().let_stmt(
if ident_pats.len() == 1 {
ident_pats[0].clone()
} else {
- make.tuple_pat(ident_pats).into()
+ editor.make().tuple_pat(ident_pats).into()
},
None,
Some(match_.into()),
);
editor.replace(let_stmt.syntax(), new_let_stmt.syntax());
}
-
- editor.add_mappings(make.finish_with_mappings());
builder.add_file_edits(ctx.vfs_file_id(), editor);
},
)
}
fn remove_mut_and_collect_idents(
- make: &SyntaxFactory,
editor: &mut SyntaxEditor,
pat: &ast::Pat,
acc: &mut Vec<ast::IdentPat>,
@@ -133,103 +128,101 @@ fn remove_mut_and_collect_idents(
Some(match pat {
ast::Pat::IdentPat(p) => {
acc.push(p.clone());
- let non_mut_pat = make.ident_pat(
+ let non_mut_pat = editor.make().ident_pat(
p.ref_token().is_some(),
p.ref_token().is_some() && p.mut_token().is_some(),
p.name()?,
);
let non_mut_pat = if let Some(inner) = p.pat() {
- non_mut_pat.set_pat(
- remove_mut_and_collect_idents(make, editor, &inner, acc),
- editor,
- make,
- )
+ non_mut_pat.set_pat(remove_mut_and_collect_idents(editor, &inner, acc), editor)
} else {
non_mut_pat
};
non_mut_pat.into()
}
ast::Pat::BoxPat(p) => {
- make.box_pat(remove_mut_and_collect_idents(make, editor, &p.pat()?, acc)?).into()
+ let pat = remove_mut_and_collect_idents(editor, &p.pat()?, acc)?;
+ editor.make().box_pat(pat).into()
+ }
+ ast::Pat::OrPat(p) => {
+ let pats = p
+ .pats()
+ .map(|pat| remove_mut_and_collect_idents(editor, &pat, acc))
+ .collect::<Option<Vec<_>>>()?;
+ editor.make().or_pat(pats, p.leading_pipe().is_some()).into()
}
- ast::Pat::OrPat(p) => make
- .or_pat(
- p.pats()
- .map(|pat| remove_mut_and_collect_idents(make, editor, &pat, acc))
- .collect::<Option<Vec<_>>>()?,
- p.leading_pipe().is_some(),
- )
- .into(),
ast::Pat::ParenPat(p) => {
- make.paren_pat(remove_mut_and_collect_idents(make, editor, &p.pat()?, acc)?).into()
+ let pat = remove_mut_and_collect_idents(editor, &p.pat()?, acc)?;
+ editor.make().paren_pat(pat).into()
+ }
+ ast::Pat::RangePat(p) => {
+ let start = if let Some(start) = p.start() {
+ Some(remove_mut_and_collect_idents(editor, &start, acc)?)
+ } else {
+ None
+ };
+ let end = if let Some(end) = p.end() {
+ Some(remove_mut_and_collect_idents(editor, &end, acc)?)
+ } else {
+ None
+ };
+ editor.make().range_pat(start, end).into()
+ }
+ ast::Pat::RecordPat(p) => {
+ let fields = p
+ .record_pat_field_list()?
+ .fields()
+ .map(|field| {
+ remove_mut_and_collect_idents(editor, &field.pat()?, acc).map(|pat| {
+ if let Some(name_ref) = field.name_ref() {
+ editor.make().record_pat_field(name_ref, pat)
+ } else {
+ editor.make().record_pat_field_shorthand(pat)
+ }
+ })
+ })
+ .collect::<Option<Vec<_>>>()?;
+ editor
+ .make()
+ .record_pat_with_fields(
+ p.path()?,
+ editor
+ .make()
+ .record_pat_field_list(fields, p.record_pat_field_list()?.rest_pat()),
+ )
+ .into()
}
- ast::Pat::RangePat(p) => make
- .range_pat(
- if let Some(start) = p.start() {
- Some(remove_mut_and_collect_idents(make, editor, &start, acc)?)
- } else {
- None
- },
- if let Some(end) = p.end() {
- Some(remove_mut_and_collect_idents(make, editor, &end, acc)?)
- } else {
- None
- },
- )
- .into(),
- ast::Pat::RecordPat(p) => make
- .record_pat_with_fields(
- p.path()?,
- make.record_pat_field_list(
- p.record_pat_field_list()?
- .fields()
- .map(|field| {
- remove_mut_and_collect_idents(make, editor, &field.pat()?, acc).map(
- |pat| {
- if let Some(name_ref) = field.name_ref() {
- make.record_pat_field(name_ref, pat)
- } else {
- make.record_pat_field_shorthand(pat)
- }
- },
- )
- })
- .collect::<Option<Vec<_>>>()?,
- p.record_pat_field_list()?.rest_pat(),
- ),
- )
- .into(),
ast::Pat::RefPat(p) => {
let inner = p.pat()?;
if let ast::Pat::IdentPat(ident) = inner {
acc.push(ident);
p.clone().into()
} else {
- make.ref_pat(remove_mut_and_collect_idents(make, editor, &inner, acc)?).into()
+ let pat = remove_mut_and_collect_idents(editor, &inner, acc)?;
+ editor.make().ref_pat(pat).into()
}
}
- ast::Pat::SlicePat(p) => make
- .slice_pat(
- p.pats()
- .map(|pat| remove_mut_and_collect_idents(make, editor, &pat, acc))
- .collect::<Option<Vec<_>>>()?,
- )
- .into(),
- ast::Pat::TuplePat(p) => make
- .tuple_pat(
- p.fields()
- .map(|field| remove_mut_and_collect_idents(make, editor, &field, acc))
- .collect::<Option<Vec<_>>>()?,
- )
- .into(),
- ast::Pat::TupleStructPat(p) => make
- .tuple_struct_pat(
- p.path()?,
- p.fields()
- .map(|field| remove_mut_and_collect_idents(make, editor, &field, acc))
- .collect::<Option<Vec<_>>>()?,
- )
- .into(),
+ ast::Pat::SlicePat(p) => {
+ let pats = p
+ .pats()
+ .map(|pat| remove_mut_and_collect_idents(editor, &pat, acc))
+ .collect::<Option<Vec<_>>>()?;
+ editor.make().slice_pat(pats).into()
+ }
+ ast::Pat::TuplePat(p) => {
+ let pats = p
+ .fields()
+ .map(|field| remove_mut_and_collect_idents(editor, &field, acc))
+ .collect::<Option<Vec<_>>>()?;
+ editor.make().tuple_pat(pats).into()
+ }
+ ast::Pat::TupleStructPat(p) => {
+ let fields = p
+ .fields()
+ .map(|field| remove_mut_and_collect_idents(editor, &field, acc))
+ .collect::<Option<Vec<_>>>()?;
+ editor.make().tuple_struct_pat(p.path()?, fields).into()
+ }
ast::Pat::RestPat(_)
| ast::Pat::LiteralPat(_)
| ast::Pat::PathPat(_)