aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/ast/edit.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/ast/edit.rs')
-rw-r--r--crates/ra_syntax/src/ast/edit.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
new file mode 100644
index 000000000..c65899812
--- /dev/null
+++ b/crates/ra_syntax/src/ast/edit.rs
@@ -0,0 +1,52 @@
1//! This module contains functions for editing syntax trees. As the trees are
2//! immutable, all function here return a fresh copy of the tree, instead of
3//! doing an in-place modification.
4
5use arrayvec::ArrayVec;
6use std::ops::RangeInclusive;
7
8use crate::{
9 algo,
10 ast::{self, make, AstNode},
11 InsertPosition, SyntaxElement,
12};
13
14impl ast::FnDef {
15 #[must_use]
16 pub fn with_body(&self, body: ast::Block) -> ast::FnDef {
17 let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new();
18 let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() {
19 old_body.syntax().clone().into()
20 } else if let Some(semi) = self.semicolon_token() {
21 to_insert.push(make::tokens::single_space().into());
22 semi.into()
23 } else {
24 to_insert.push(make::tokens::single_space().into());
25 to_insert.push(body.syntax().clone().into());
26 return insert_children(self, InsertPosition::Last, to_insert.into_iter());
27 };
28 to_insert.push(body.syntax().clone().into());
29 let replace_range = RangeInclusive::new(old_body_or_semi.clone(), old_body_or_semi);
30 replace_children(self, replace_range, to_insert.into_iter())
31 }
32}
33
34#[must_use]
35fn insert_children<N: AstNode>(
36 parent: &N,
37 position: InsertPosition<SyntaxElement>,
38 mut to_insert: impl Iterator<Item = SyntaxElement>,
39) -> N {
40 let new_syntax = algo::insert_children(parent.syntax(), position, &mut to_insert);
41 N::cast(new_syntax).unwrap()
42}
43
44#[must_use]
45fn replace_children<N: AstNode>(
46 parent: &N,
47 to_replace: RangeInclusive<SyntaxElement>,
48 mut to_insert: impl Iterator<Item = SyntaxElement>,
49) -> N {
50 let new_syntax = algo::replace_children(parent.syntax(), to_replace, &mut to_insert);
51 N::cast(new_syntax).unwrap()
52}