Skip to content

Commit 0e4f189

Browse files
committed
internal: Migrate inline_local_variable to SyntaxEditor
1 parent d11c5b8 commit 0e4f189

File tree

2 files changed

+55
-32
lines changed

2 files changed

+55
-32
lines changed

Diff for: src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs

+34-32
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use ide_db::{
55
EditionedFileId, RootDatabase,
66
};
77
use syntax::{
8-
ast::{self, AstNode, AstToken, HasName},
8+
ast::{self, syntax_factory::SyntaxFactory, AstNode, AstToken, HasName},
99
SyntaxElement, TextRange,
1010
};
1111

@@ -43,22 +43,6 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>)
4343
}?;
4444
let initializer_expr = let_stmt.initializer()?;
4545

46-
let delete_range = delete_let.then(|| {
47-
if let Some(whitespace) = let_stmt
48-
.syntax()
49-
.next_sibling_or_token()
50-
.and_then(SyntaxElement::into_token)
51-
.and_then(ast::Whitespace::cast)
52-
{
53-
TextRange::new(
54-
let_stmt.syntax().text_range().start(),
55-
whitespace.syntax().text_range().end(),
56-
)
57-
} else {
58-
let_stmt.syntax().text_range()
59-
}
60-
});
61-
6246
let wrap_in_parens = references
6347
.into_iter()
6448
.filter_map(|FileReference { range, name, .. }| match name {
@@ -76,37 +60,55 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>)
7660
let usage_parent_option = usage_node.and_then(|it| it.parent());
7761
let usage_parent = match usage_parent_option {
7862
Some(u) => u,
79-
None => return Some((range, name_ref, false)),
63+
None => return Some((name_ref, false)),
8064
};
81-
Some((range, name_ref, initializer_expr.needs_parens_in(&usage_parent)))
65+
Some((name_ref, initializer_expr.needs_parens_in(&usage_parent)))
8266
})
8367
.collect::<Option<Vec<_>>>()?;
8468

85-
let init_str = initializer_expr.syntax().text().to_string();
86-
let init_in_paren = format!("({init_str})");
87-
8869
let target = match target {
89-
ast::NameOrNameRef::Name(it) => it.syntax().text_range(),
90-
ast::NameOrNameRef::NameRef(it) => it.syntax().text_range(),
70+
ast::NameOrNameRef::Name(it) => it.syntax().clone(),
71+
ast::NameOrNameRef::NameRef(it) => it.syntax().clone(),
9172
};
9273

9374
acc.add(
9475
AssistId("inline_local_variable", AssistKind::RefactorInline),
9576
"Inline variable",
96-
target,
77+
target.text_range(),
9778
move |builder| {
98-
if let Some(range) = delete_range {
99-
builder.delete(range);
79+
let mut editor = builder.make_editor(&target);
80+
if delete_let {
81+
editor.delete(let_stmt.syntax());
82+
if let Some(whitespace) = let_stmt
83+
.syntax()
84+
.next_sibling_or_token()
85+
.and_then(SyntaxElement::into_token)
86+
.and_then(ast::Whitespace::cast)
87+
{
88+
editor.delete(whitespace.syntax());
89+
}
10090
}
101-
for (range, name, should_wrap) in wrap_in_parens {
102-
let replacement = if should_wrap { &init_in_paren } else { &init_str };
103-
if ast::RecordExprField::for_field_name(&name).is_some() {
91+
92+
let make = SyntaxFactory::new();
93+
94+
for (name, should_wrap) in wrap_in_parens {
95+
let replacement = if should_wrap {
96+
make.expr_paren(initializer_expr.clone()).into()
97+
} else {
98+
initializer_expr.clone()
99+
};
100+
101+
if let Some(record_field) = ast::RecordExprField::for_field_name(&name) {
104102
cov_mark::hit!(inline_field_shorthand);
105-
builder.insert(range.end(), format!(": {replacement}"));
103+
let replacement = make.record_expr_field(name, Some(replacement));
104+
editor.replace(record_field.syntax(), replacement.syntax());
106105
} else {
107-
builder.replace(range, replacement.clone())
106+
editor.replace(name.syntax(), replacement.syntax());
108107
}
109108
}
109+
110+
editor.add_mappings(make.finish_with_mappings());
111+
builder.add_file_edits(ctx.file_id(), editor);
110112
},
111113
)
112114
}

Diff for: src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs

+21
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,27 @@ impl SyntaxFactory {
783783
ast
784784
}
785785

786+
pub fn record_expr_field(
787+
&self,
788+
name: ast::NameRef,
789+
expr: Option<ast::Expr>,
790+
) -> ast::RecordExprField {
791+
let ast = make::record_expr_field(name.clone(), expr.clone()).clone_for_update();
792+
793+
if let Some(mut mapping) = self.mappings() {
794+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
795+
796+
builder.map_node(name.syntax().clone(), ast.name_ref().unwrap().syntax().clone());
797+
if let Some(expr) = expr {
798+
builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone());
799+
}
800+
801+
builder.finish(&mut mapping);
802+
}
803+
804+
ast
805+
}
806+
786807
pub fn record_field_list(
787808
&self,
788809
fields: impl IntoIterator<Item = ast::RecordField>,

0 commit comments

Comments
 (0)