1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
use std::{iter, ops::RangeInclusive};
use ra_syntax::{
algo,
ast::{self, TypeBoundsOwner},
AstNode, SyntaxElement,
};
use ra_text_edit::TextEditBuilder;
use rustc_hash::FxHashMap;
pub struct AstEditor<N: AstNode> {
original_ast: N,
ast: N,
}
impl<N: AstNode> AstEditor<N> {
pub fn new(node: N) -> AstEditor<N>
where
N: Clone,
{
AstEditor { original_ast: node.clone(), ast: node }
}
pub fn into_text_edit(self, builder: &mut TextEditBuilder) {
algo::diff(&self.original_ast.syntax(), self.ast().syntax()).into_text_edit(builder)
}
pub fn ast(&self) -> &N {
&self.ast
}
pub fn replace_descendants<T: AstNode>(
&mut self,
replacement_map: impl Iterator<Item = (T, T)>,
) -> &mut Self {
let map = replacement_map
.map(|(from, to)| (from.syntax().clone().into(), to.syntax().clone().into()))
.collect::<FxHashMap<_, _>>();
let new_syntax = algo::replace_descendants(self.ast.syntax(), &map);
self.ast = N::cast(new_syntax).unwrap();
self
}
#[must_use]
fn replace_children(
&self,
to_delete: RangeInclusive<SyntaxElement>,
mut to_insert: impl Iterator<Item = SyntaxElement>,
) -> N {
let new_syntax = algo::replace_children(self.ast().syntax(), to_delete, &mut to_insert);
N::cast(new_syntax).unwrap()
}
}
|