Skip to content

Commit e6e4417

Browse files
committed
Remove SyntaxRewriter::from_fn
1 parent 20f8219 commit e6e4417

File tree

3 files changed

+24
-31
lines changed

3 files changed

+24
-31
lines changed

crates/ide_assists/src/ast_transform.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,27 @@ use hir::{HirDisplay, PathResolution, SemanticsScope};
33
use ide_db::helpers::mod_path_to_ast;
44
use rustc_hash::FxHashMap;
55
use syntax::{
6-
algo::SyntaxRewriter,
76
ast::{self, AstNode},
8-
SyntaxNode,
7+
ted, SyntaxNode,
98
};
109

11-
pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N {
12-
SyntaxRewriter::from_fn(|element| match element {
13-
syntax::SyntaxElement::Node(n) => {
14-
let replacement = transformer.get_substitution(&n, transformer)?;
15-
Some(replacement.into())
10+
pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: &N) {
11+
let mut skip_to = None;
12+
for event in node.syntax().preorder() {
13+
match event {
14+
syntax::WalkEvent::Enter(node) if skip_to.is_none() => {
15+
skip_to = transformer.get_substitution(&node, transformer).zip(Some(node));
16+
}
17+
syntax::WalkEvent::Enter(_) => (),
18+
syntax::WalkEvent::Leave(node) => match &skip_to {
19+
Some((replacement, skip_target)) if *skip_target == node => {
20+
ted::replace(node, replacement.clone_for_update());
21+
skip_to.take();
22+
}
23+
_ => (),
24+
},
1625
}
17-
_ => None,
18-
})
19-
.rewrite_ast(&node)
26+
}
2027
}
2128

2229
/// `AstTransform` helps with applying bulk transformations to syntax nodes.
@@ -191,11 +198,9 @@ impl<'a> AstTransform<'a> for QualifyPaths<'a> {
191198
let found_path = from.find_use_path(self.source_scope.db.upcast(), def)?;
192199
let mut path = mod_path_to_ast(&found_path);
193200

194-
let type_args = p
195-
.segment()
196-
.and_then(|s| s.generic_arg_list())
197-
.map(|arg_list| apply(recur, arg_list));
201+
let type_args = p.segment().and_then(|s| s.generic_arg_list());
198202
if let Some(type_args) = type_args {
203+
apply(recur, &type_args);
199204
let last_segment = path.segment().unwrap();
200205
path = path.with_segment(last_segment.with_generic_args(type_args))
201206
}

crates/ide_assists/src/utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ pub fn add_trait_assoc_items_to_impl(
140140

141141
let items = items
142142
.into_iter()
143-
.map(|it| ast_transform::apply(&*ast_transform, it))
143+
.map(|it| it.clone_for_update())
144+
.inspect(|it| ast_transform::apply(&*ast_transform, it))
144145
.map(|it| match it {
145146
ast::AssocItem::Fn(def) => ast::AssocItem::Fn(add_body(def)),
146147
ast::AssocItem::TypeAlias(def) => ast::AssocItem::TypeAlias(def.remove_bounds()),

crates/syntax/src/algo.rs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,10 @@ enum InsertPos {
342342

343343
#[derive(Default)]
344344
pub struct SyntaxRewriter<'a> {
345-
f: Option<Box<dyn Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a>>,
346345
//FIXME: add debug_assertions that all elements are in fact from the same file.
347346
replacements: FxHashMap<SyntaxElement, Replacement>,
348347
insertions: IndexMap<InsertPos, Vec<SyntaxElement>>,
348+
_pd: std::marker::PhantomData<&'a ()>,
349349
}
350350

351351
impl fmt::Debug for SyntaxRewriter<'_> {
@@ -357,14 +357,7 @@ impl fmt::Debug for SyntaxRewriter<'_> {
357357
}
358358
}
359359

360-
impl<'a> SyntaxRewriter<'a> {
361-
pub fn from_fn(f: impl Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a) -> SyntaxRewriter<'a> {
362-
SyntaxRewriter {
363-
f: Some(Box::new(f)),
364-
replacements: FxHashMap::default(),
365-
insertions: IndexMap::default(),
366-
}
367-
}
360+
impl SyntaxRewriter<'_> {
368361
pub fn delete<T: Clone + Into<SyntaxElement>>(&mut self, what: &T) {
369362
let what = what.clone().into();
370363
let replacement = Replacement::Delete;
@@ -470,7 +463,7 @@ impl<'a> SyntaxRewriter<'a> {
470463
pub fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode {
471464
let _p = profile::span("rewrite");
472465

473-
if self.f.is_none() && self.replacements.is_empty() && self.insertions.is_empty() {
466+
if self.replacements.is_empty() && self.insertions.is_empty() {
474467
return node.clone();
475468
}
476469
let green = self.rewrite_children(node);
@@ -495,7 +488,6 @@ impl<'a> SyntaxRewriter<'a> {
495488
}
496489
}
497490

498-
assert!(self.f.is_none());
499491
self.replacements
500492
.keys()
501493
.filter_map(element_to_node_or_parent)
@@ -510,10 +502,6 @@ impl<'a> SyntaxRewriter<'a> {
510502
}
511503

512504
fn replacement(&self, element: &SyntaxElement) -> Option<Replacement> {
513-
if let Some(f) = &self.f {
514-
assert!(self.replacements.is_empty());
515-
return f(element).map(Replacement::Single);
516-
}
517505
self.replacements.get(element).cloned()
518506
}
519507

@@ -574,7 +562,6 @@ fn element_to_green(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, row
574562

575563
impl ops::AddAssign for SyntaxRewriter<'_> {
576564
fn add_assign(&mut self, rhs: SyntaxRewriter) {
577-
assert!(rhs.f.is_none());
578565
self.replacements.extend(rhs.replacements);
579566
for (pos, insertions) in rhs.insertions.into_iter() {
580567
match self.insertions.entry(pos) {

0 commit comments

Comments
 (0)