Skip to content

Commit 11d45c8

Browse files
authored
Merge pull request #20137 from Hmikihiro/migrate-wrap_unwrap_cfg_attr-assist-to-syntaxeditor
Migrate `wrap_unwrap_cfg_attr` Assist to use `SyntaxEditor`
2 parents aa16885 + 0b7ad9c commit 11d45c8

File tree

2 files changed

+85
-42
lines changed

2 files changed

+85
-42
lines changed

crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use ide_db::source_change::SourceChangeBuilder;
22
use itertools::Itertools;
33
use syntax::{
44
NodeOrToken, SyntaxToken, T, TextRange, algo,
5-
ast::{self, AstNode, make},
6-
ted::{self, Position},
5+
ast::{self, AstNode, make, syntax_factory::SyntaxFactory},
76
};
87

98
use crate::{AssistContext, AssistId, Assists};
@@ -173,40 +172,45 @@ fn wrap_derive(
173172
}
174173
}
175174
let handle_source_change = |edit: &mut SourceChangeBuilder| {
176-
let new_derive = make::attr_outer(make::meta_token_tree(
177-
make::ext::ident_path("derive"),
178-
make::token_tree(T!['('], new_derive),
179-
))
180-
.clone_for_update();
181-
let meta = make::meta_token_tree(
182-
make::ext::ident_path("cfg_attr"),
183-
make::token_tree(
175+
let make = SyntaxFactory::with_mappings();
176+
let mut editor = edit.make_editor(attr.syntax());
177+
let new_derive = make.attr_outer(
178+
make.meta_token_tree(make.ident_path("derive"), make.token_tree(T!['('], new_derive)),
179+
);
180+
let meta = make.meta_token_tree(
181+
make.ident_path("cfg_attr"),
182+
make.token_tree(
184183
T!['('],
185184
vec![
186-
NodeOrToken::Token(make::token(T![,])),
187-
NodeOrToken::Token(make::tokens::whitespace(" ")),
188-
NodeOrToken::Token(make::tokens::ident("derive")),
189-
NodeOrToken::Node(make::token_tree(T!['('], cfg_derive_tokens)),
185+
NodeOrToken::Token(make.token(T![,])),
186+
NodeOrToken::Token(make.whitespace(" ")),
187+
NodeOrToken::Token(make.ident("derive")),
188+
NodeOrToken::Node(make.token_tree(T!['('], cfg_derive_tokens)),
190189
],
191190
),
192191
);
193-
// Remove the derive attribute
194-
let edit_attr = edit.make_syntax_mut(attr.syntax().clone());
195-
196-
ted::replace(edit_attr, new_derive.syntax().clone());
197-
let cfg_attr = make::attr_outer(meta).clone_for_update();
198192

199-
ted::insert_all_raw(
200-
Position::after(new_derive.syntax().clone()),
201-
vec![make::tokens::whitespace("\n").into(), cfg_attr.syntax().clone().into()],
193+
let cfg_attr = make.attr_outer(meta);
194+
editor.replace_with_many(
195+
attr.syntax(),
196+
vec![
197+
new_derive.syntax().clone().into(),
198+
make.whitespace("\n").into(),
199+
cfg_attr.syntax().clone().into(),
200+
],
202201
);
202+
203203
if let Some(snippet_cap) = ctx.config.snippet_cap {
204204
if let Some(first_meta) =
205205
cfg_attr.meta().and_then(|meta| meta.token_tree()).and_then(|tt| tt.l_paren_token())
206206
{
207-
edit.add_tabstop_after_token(snippet_cap, first_meta)
207+
let tabstop = edit.make_tabstop_after(snippet_cap);
208+
editor.add_annotation(first_meta, tabstop);
208209
}
209210
}
211+
212+
editor.add_mappings(make.finish_with_mappings());
213+
edit.add_file_edits(ctx.vfs_file_id(), editor);
210214
};
211215

212216
acc.add(
@@ -221,20 +225,20 @@ fn wrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>, attr: ast::Attr) ->
221225
let range = attr.syntax().text_range();
222226
let path = attr.path()?;
223227
let handle_source_change = |edit: &mut SourceChangeBuilder| {
224-
let mut raw_tokens = vec![
225-
NodeOrToken::Token(make::token(T![,])),
226-
NodeOrToken::Token(make::tokens::whitespace(" ")),
227-
];
228+
let make = SyntaxFactory::with_mappings();
229+
let mut editor = edit.make_editor(attr.syntax());
230+
let mut raw_tokens =
231+
vec![NodeOrToken::Token(make.token(T![,])), NodeOrToken::Token(make.whitespace(" "))];
228232
path.syntax().descendants_with_tokens().for_each(|it| {
229233
if let NodeOrToken::Token(token) = it {
230234
raw_tokens.push(NodeOrToken::Token(token));
231235
}
232236
});
233237
if let Some(meta) = attr.meta() {
234238
if let (Some(eq), Some(expr)) = (meta.eq_token(), meta.expr()) {
235-
raw_tokens.push(NodeOrToken::Token(make::tokens::whitespace(" ")));
239+
raw_tokens.push(NodeOrToken::Token(make.whitespace(" ")));
236240
raw_tokens.push(NodeOrToken::Token(eq));
237-
raw_tokens.push(NodeOrToken::Token(make::tokens::whitespace(" ")));
241+
raw_tokens.push(NodeOrToken::Token(make.whitespace(" ")));
238242

239243
expr.syntax().descendants_with_tokens().for_each(|it| {
240244
if let NodeOrToken::Token(token) = it {
@@ -245,26 +249,24 @@ fn wrap_cfg_attr(acc: &mut Assists, ctx: &AssistContext<'_>, attr: ast::Attr) ->
245249
raw_tokens.extend(tt.token_trees_and_tokens());
246250
}
247251
}
248-
let meta = make::meta_token_tree(
249-
make::ext::ident_path("cfg_attr"),
250-
make::token_tree(T!['('], raw_tokens),
251-
);
252-
let cfg_attr = if attr.excl_token().is_some() {
253-
make::attr_inner(meta)
254-
} else {
255-
make::attr_outer(meta)
256-
}
257-
.clone_for_update();
258-
let attr_syntax = edit.make_syntax_mut(attr.syntax().clone());
259-
ted::replace(attr_syntax, cfg_attr.syntax());
252+
let meta =
253+
make.meta_token_tree(make.ident_path("cfg_attr"), make.token_tree(T!['('], raw_tokens));
254+
let cfg_attr =
255+
if attr.excl_token().is_some() { make.attr_inner(meta) } else { make.attr_outer(meta) };
256+
257+
editor.replace(attr.syntax(), cfg_attr.syntax());
260258

261259
if let Some(snippet_cap) = ctx.config.snippet_cap {
262260
if let Some(first_meta) =
263261
cfg_attr.meta().and_then(|meta| meta.token_tree()).and_then(|tt| tt.l_paren_token())
264262
{
265-
edit.add_tabstop_after_token(snippet_cap, first_meta)
263+
let tabstop = edit.make_tabstop_after(snippet_cap);
264+
editor.add_annotation(first_meta, tabstop);
266265
}
267266
}
267+
268+
editor.add_mappings(make.finish_with_mappings());
269+
edit.add_file_edits(ctx.vfs_file_id(), editor);
268270
};
269271
acc.add(
270272
AssistId::refactor("wrap_unwrap_cfg_attr"),

crates/syntax/src/ast/syntax_factory/constructors.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,43 @@ impl SyntaxFactory {
12121212
ast
12131213
}
12141214

1215+
pub fn attr_outer(&self, meta: ast::Meta) -> ast::Attr {
1216+
let ast = make::attr_outer(meta.clone()).clone_for_update();
1217+
1218+
if let Some(mut mapping) = self.mappings() {
1219+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
1220+
builder.map_node(meta.syntax().clone(), ast.meta().unwrap().syntax().clone());
1221+
builder.finish(&mut mapping);
1222+
}
1223+
1224+
ast
1225+
}
1226+
1227+
pub fn attr_inner(&self, meta: ast::Meta) -> ast::Attr {
1228+
let ast = make::attr_inner(meta.clone()).clone_for_update();
1229+
1230+
if let Some(mut mapping) = self.mappings() {
1231+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
1232+
builder.map_node(meta.syntax().clone(), ast.meta().unwrap().syntax().clone());
1233+
builder.finish(&mut mapping);
1234+
}
1235+
1236+
ast
1237+
}
1238+
1239+
pub fn meta_token_tree(&self, path: ast::Path, tt: ast::TokenTree) -> ast::Meta {
1240+
let ast = make::meta_token_tree(path.clone(), tt.clone()).clone_for_update();
1241+
1242+
if let Some(mut mapping) = self.mappings() {
1243+
let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
1244+
builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone());
1245+
builder.map_node(tt.syntax().clone(), ast.token_tree().unwrap().syntax().clone());
1246+
builder.finish(&mut mapping);
1247+
}
1248+
1249+
ast
1250+
}
1251+
12151252
pub fn token_tree(
12161253
&self,
12171254
delimiter: SyntaxKind,
@@ -1242,6 +1279,10 @@ impl SyntaxFactory {
12421279
pub fn whitespace(&self, text: &str) -> SyntaxToken {
12431280
make::tokens::whitespace(text)
12441281
}
1282+
1283+
pub fn ident(&self, text: &str) -> SyntaxToken {
1284+
make::tokens::ident(text)
1285+
}
12451286
}
12461287

12471288
// `ext` constructors

0 commit comments

Comments
 (0)