about summary refs log tree commit diff
path: root/src/tools/rust-analyzer
diff options
context:
space:
mode:
authorPrajwal S N <prajwalnadig21@gmail.com>2025-04-11 21:24:48 +0530
committerPrajwal S N <prajwalnadig21@gmail.com>2025-04-11 21:25:53 +0530
commita3bc2b12fcee16d45c818b632a54719420737f71 (patch)
tree6028a04611aee52cd0b22a1791d72412eb1dc9cd /src/tools/rust-analyzer
parent7425cc1d1825a29ef05975971d14d13e0662c7f0 (diff)
downloadrust-a3bc2b12fcee16d45c818b632a54719420737f71.tar.gz
rust-a3bc2b12fcee16d45c818b632a54719420737f71.zip
refactor: migrate `expand_rest_pattern` to editor
Signed-off-by: Prajwal S N <prajwalnadig21@gmail.com>
Diffstat (limited to 'src/tools/rust-analyzer')
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs119
1 files changed, 66 insertions, 53 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs
index ceb13b2f212..1b5fc63e525 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/expand_rest_pattern.rs
@@ -2,28 +2,12 @@ use hir::{PathResolution, StructKind};
 use ide_db::syntax_helpers::suggest_name::NameGenerator;
 use syntax::{
     AstNode, ToSmolStr,
-    ast::{self, make},
+    ast::{self, syntax_factory::SyntaxFactory},
     match_ast,
 };
 
 use crate::{AssistContext, AssistId, Assists};
 
-pub(crate) fn expand_rest_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    let rest_pat = ctx.find_node_at_offset::<ast::RestPat>()?;
-    let parent = rest_pat.syntax().parent()?;
-    match_ast! {
-        match parent {
-            ast::RecordPatFieldList(it) => expand_record_rest_pattern(acc, ctx, it.syntax().parent().and_then(ast::RecordPat::cast)?, rest_pat),
-            ast::TupleStructPat(it) => expand_tuple_struct_rest_pattern(acc, ctx, it, rest_pat),
-            // FIXME
-            // ast::TuplePat(it) => (),
-            // FIXME
-            // ast::SlicePat(it) => (),
-            _ => return None,
-        }
-    }
-}
-
 // Assist: expand_record_rest_pattern
 //
 // Fills fields by replacing rest pattern in record patterns.
@@ -50,7 +34,6 @@ fn expand_record_rest_pattern(
     rest_pat: ast::RestPat,
 ) -> Option<()> {
     let missing_fields = ctx.sema.record_pattern_missing_fields(&record_pat);
-
     if missing_fields.is_empty() {
         cov_mark::hit!(no_missing_fields);
         return None;
@@ -62,24 +45,30 @@ fn expand_record_rest_pattern(
         return None;
     }
 
-    let new_field_list =
-        make::record_pat_field_list(old_field_list.fields(), None).clone_for_update();
-    for (f, _) in missing_fields.iter() {
-        let edition = ctx.sema.scope(record_pat.syntax())?.krate().edition(ctx.db());
-        let field = make::record_pat_field_shorthand(make::name_ref(
-            &f.name(ctx.sema.db).display_no_db(edition).to_smolstr(),
-        ));
-        new_field_list.add_field(field.clone_for_update());
-    }
-
-    let target_range = rest_pat.syntax().text_range();
+    let edition = ctx.sema.scope(record_pat.syntax())?.krate().edition(ctx.db());
     acc.add(
         AssistId::refactor_rewrite("expand_record_rest_pattern"),
         "Fill struct fields",
-        target_range,
-        move |builder| builder.replace_ast(old_field_list, new_field_list),
+        rest_pat.syntax().text_range(),
+        |builder| {
+            let make = SyntaxFactory::with_mappings();
+            let mut editor = builder.make_editor(rest_pat.syntax());
+            let new_field_list = make.record_pat_field_list(old_field_list.fields(), None);
+            for (f, _) in missing_fields.iter() {
+                let field = make.record_pat_field_shorthand(
+                    make.name_ref(&f.name(ctx.sema.db).display_no_db(edition).to_smolstr()),
+                );
+                new_field_list.add_field(field);
+            }
+
+            editor.replace(old_field_list.syntax(), new_field_list.syntax());
+
+            editor.add_mappings(make.finish_with_mappings());
+            builder.add_file_edits(ctx.file_id(), editor);
+        },
     )
 }
+
 // Assist: expand_tuple_struct_rest_pattern
 //
 // Fills fields by replacing rest pattern in tuple struct patterns.
@@ -134,34 +123,58 @@ fn expand_tuple_struct_rest_pattern(
         return None;
     }
 
-    let mut name_gen = NameGenerator::new_from_scope_locals(ctx.sema.scope(pat.syntax()));
-    let new_pat = make::tuple_struct_pat(
-        path,
-        pat.fields()
-            .take(prefix_count)
-            .chain(fields[prefix_count..fields.len() - suffix_count].iter().map(|f| {
-                make::ident_pat(
-                    false,
-                    false,
-                    match name_gen.for_type(&f.ty(ctx.sema.db), ctx.sema.db, ctx.edition()) {
-                        Some(name) => make::name(&name),
-                        None => make::name(&format!("_{}", f.index())),
-                    },
-                )
-                .into()
-            }))
-            .chain(pat.fields().skip(prefix_count + 1)),
-    );
-
-    let target_range = rest_pat.syntax().text_range();
     acc.add(
         AssistId::refactor_rewrite("expand_tuple_struct_rest_pattern"),
         "Fill tuple struct fields",
-        target_range,
-        move |builder| builder.replace_ast(pat, new_pat),
+        rest_pat.syntax().text_range(),
+        |builder| {
+            let make = SyntaxFactory::with_mappings();
+            let mut editor = builder.make_editor(rest_pat.syntax());
+
+            let mut name_gen = NameGenerator::new_from_scope_locals(ctx.sema.scope(pat.syntax()));
+            let new_pat = make.tuple_struct_pat(
+                path,
+                pat.fields()
+                    .take(prefix_count)
+                    .chain(fields[prefix_count..fields.len() - suffix_count].iter().map(|f| {
+                        make.ident_pat(
+                            false,
+                            false,
+                            match name_gen.for_type(&f.ty(ctx.sema.db), ctx.sema.db, ctx.edition())
+                            {
+                                Some(name) => make.name(&name),
+                                None => make.name(&format!("_{}", f.index())),
+                            },
+                        )
+                        .into()
+                    }))
+                    .chain(pat.fields().skip(prefix_count + 1)),
+            );
+
+            editor.replace(pat.syntax(), new_pat.syntax());
+
+            editor.add_mappings(make.finish_with_mappings());
+            builder.add_file_edits(ctx.file_id(), editor);
+        },
     )
 }
 
+pub(crate) fn expand_rest_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+    let rest_pat = ctx.find_node_at_offset::<ast::RestPat>()?;
+    let parent = rest_pat.syntax().parent()?;
+    match_ast! {
+        match parent {
+            ast::RecordPatFieldList(it) => expand_record_rest_pattern(acc, ctx, it.syntax().parent().and_then(ast::RecordPat::cast)?, rest_pat),
+            ast::TupleStructPat(it) => expand_tuple_struct_rest_pattern(acc, ctx, it, rest_pat),
+            // FIXME
+            // ast::TuplePat(it) => (),
+            // FIXME
+            // ast::SlicePat(it) => (),
+            _ => return None,
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;