Skip to content

Commit 1fdc9d8

Browse files
committed
internal: remove one more syntax rewriter
1 parent 4e3f018 commit 1fdc9d8

File tree

3 files changed

+38
-65
lines changed

3 files changed

+38
-65
lines changed

crates/ide_assists/src/assist_context.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use ide_db::{
1313
RootDatabase,
1414
};
1515
use syntax::{
16-
algo::{self, find_node_at_offset, find_node_at_range, SyntaxRewriter},
16+
algo::{self, find_node_at_offset, find_node_at_range},
1717
AstNode, AstToken, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr,
1818
SyntaxToken, TextRange, TextSize, TokenAtOffset,
1919
};
@@ -290,12 +290,6 @@ impl AssistBuilder {
290290
pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
291291
algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit)
292292
}
293-
pub(crate) fn rewrite(&mut self, rewriter: SyntaxRewriter) {
294-
if let Some(node) = rewriter.rewrite_root() {
295-
let new = rewriter.rewrite(&node);
296-
algo::diff(&node, &new).into_text_edit(&mut self.edit);
297-
}
298-
}
299293
pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) {
300294
let file_system_edit =
301295
FileSystemEdit::CreateFile { dst: dst, initial_contents: content.into() };

crates/ide_assists/src/handlers/expand_glob_import.rs

Lines changed: 33 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ use ide_db::{
44
defs::{Definition, NameRefClass},
55
search::SearchScope,
66
};
7+
use stdx::never;
78
use syntax::{
8-
algo::SyntaxRewriter,
99
ast::{self, make},
10-
AstNode, Direction, SyntaxNode, SyntaxToken, T,
10+
ted, AstNode, Direction, SyntaxNode, SyntaxToken, T,
1111
};
1212

1313
use crate::{
@@ -42,6 +42,7 @@ use crate::{
4242
// ```
4343
pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
4444
let star = ctx.find_token_syntax_at_offset(T![*])?;
45+
let use_tree = star.parent().and_then(ast::UseTree::cast)?;
4546
let (parent, mod_path) = find_parent_and_path(&star)?;
4647
let target_module = match ctx.sema.resolve_path(&mod_path)? {
4748
PathResolution::Def(ModuleDef::Module(it)) => it,
@@ -53,17 +54,39 @@ pub(crate) fn expand_glob_import(acc: &mut Assists, ctx: &AssistContext) -> Opti
5354

5455
let refs_in_target = find_refs_in_mod(ctx, target_module, Some(current_module))?;
5556
let imported_defs = find_imported_defs(ctx, star)?;
56-
let names_to_import = find_names_to_import(ctx, refs_in_target, imported_defs);
5757

5858
let target = parent.clone().either(|n| n.syntax().clone(), |n| n.syntax().clone());
5959
acc.add(
6060
AssistId("expand_glob_import", AssistKind::RefactorRewrite),
6161
"Expand glob import",
6262
target.text_range(),
6363
|builder| {
64-
let mut rewriter = SyntaxRewriter::default();
65-
replace_ast(&mut rewriter, parent, mod_path, names_to_import);
66-
builder.rewrite(rewriter);
64+
let use_tree = builder.make_ast_mut(use_tree);
65+
66+
let names_to_import = find_names_to_import(ctx, refs_in_target, imported_defs);
67+
let expanded = make::use_tree_list(names_to_import.iter().map(|n| {
68+
let path =
69+
make::path_unqualified(make::path_segment(make::name_ref(&n.to_string())));
70+
make::use_tree(path, None, None, false)
71+
}))
72+
.clone_for_update();
73+
74+
match use_tree.star_token() {
75+
Some(star) => {
76+
let needs_braces = use_tree.path().is_some() && names_to_import.len() > 1;
77+
if needs_braces {
78+
ted::replace(star, expanded.syntax())
79+
} else {
80+
let without_braces = expanded
81+
.syntax()
82+
.children_with_tokens()
83+
.filter(|child| !matches!(child.kind(), T!['{'] | T!['}']))
84+
.collect();
85+
ted::replace_with_many(star, without_braces)
86+
}
87+
}
88+
None => never!(),
89+
}
6790
},
6891
)
6992
}
@@ -232,53 +255,6 @@ fn find_names_to_import(
232255
used_refs.0.iter().map(|r| r.visible_name.clone()).collect()
233256
}
234257

235-
fn replace_ast(
236-
rewriter: &mut SyntaxRewriter,
237-
parent: Either<ast::UseTree, ast::UseTreeList>,
238-
path: ast::Path,
239-
names_to_import: Vec<Name>,
240-
) {
241-
let existing_use_trees = match parent.clone() {
242-
Either::Left(_) => vec![],
243-
Either::Right(u) => u
244-
.use_trees()
245-
.filter(|n|
246-
// filter out star
247-
n.star_token().is_none())
248-
.collect(),
249-
};
250-
251-
let new_use_trees: Vec<ast::UseTree> = names_to_import
252-
.iter()
253-
.map(|n| {
254-
let path = make::path_unqualified(make::path_segment(make::name_ref(&n.to_string())));
255-
make::use_tree(path, None, None, false)
256-
})
257-
.collect();
258-
259-
let use_trees = [&existing_use_trees[..], &new_use_trees[..]].concat();
260-
261-
match use_trees.as_slice() {
262-
[name] => {
263-
if let Some(end_path) = name.path() {
264-
rewriter.replace_ast(
265-
&parent.left_or_else(|tl| tl.parent_use_tree()),
266-
&make::use_tree(make::path_concat(path, end_path), None, None, false),
267-
);
268-
}
269-
}
270-
names => match &parent {
271-
Either::Left(parent) => rewriter.replace_ast(
272-
parent,
273-
&make::use_tree(path, Some(make::use_tree_list(names.to_owned())), None, false),
274-
),
275-
Either::Right(parent) => {
276-
rewriter.replace_ast(parent, &make::use_tree_list(names.to_owned()))
277-
}
278-
},
279-
};
280-
}
281-
282258
#[cfg(test)]
283259
mod tests {
284260
use crate::tests::{check_assist, check_assist_not_applicable};
@@ -350,7 +326,7 @@ mod foo {
350326
pub fn f() {}
351327
}
352328
353-
use foo::{f, Baz, Bar};
329+
use foo::{Baz, Bar, f};
354330
355331
fn qux(bar: Bar, baz: Baz) {
356332
f();
@@ -389,7 +365,7 @@ mod foo {
389365
}
390366
391367
use foo::Bar;
392-
use foo::{f, Baz};
368+
use foo::{Baz, f};
393369
394370
fn qux(bar: Bar, baz: Baz) {
395371
f();
@@ -439,7 +415,7 @@ mod foo {
439415
}
440416
}
441417
442-
use foo::{bar::{f, Baz, Bar}, baz::*};
418+
use foo::{bar::{Baz, Bar, f}, baz::*};
443419
444420
fn qux(bar: Bar, baz: Baz) {
445421
f();
@@ -891,7 +867,7 @@ mod foo {
891867
pub struct Bar;
892868
}
893869
894-
use foo::Bar;
870+
use foo::{Bar};
895871
896872
struct Baz {
897873
bar: Bar

crates/syntax/src/ted.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,11 @@ pub fn remove_all_iter(range: impl IntoIterator<Item = SyntaxElement>) {
125125
}
126126

127127
pub fn replace(old: impl Element, new: impl Element) {
128+
replace_with_many(old, vec![new.syntax_element()])
129+
}
130+
pub fn replace_with_many(old: impl Element, new: Vec<SyntaxElement>) {
128131
let old = old.syntax_element();
129-
replace_all(old.clone()..=old, vec![new.syntax_element()])
132+
replace_all(old.clone()..=old, new)
130133
}
131134
pub fn replace_all(range: RangeInclusive<SyntaxElement>, new: Vec<SyntaxElement>) {
132135
let start = range.start().index();

0 commit comments

Comments
 (0)