aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax/src/ast/edit_in_place.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/syntax/src/ast/edit_in_place.rs')
-rw-r--r--crates/syntax/src/ast/edit_in_place.rs129
1 files changed, 129 insertions, 0 deletions
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs
new file mode 100644
index 000000000..449b058fb
--- /dev/null
+++ b/crates/syntax/src/ast/edit_in_place.rs
@@ -0,0 +1,129 @@
1//! Structural editing for ast.
2
3use std::iter::empty;
4
5use ast::{edit::AstNodeEdit, make, GenericParamsOwner, WhereClause};
6use parser::T;
7
8use crate::{
9 ast,
10 ted::{self, Position},
11 AstNode, Direction, SyntaxElement,
12};
13
14use super::NameOwner;
15
16pub trait GenericParamsOwnerEdit: ast::GenericParamsOwner + AstNodeEdit {
17 fn get_or_create_where_clause(&self) -> ast::WhereClause;
18}
19
20impl GenericParamsOwnerEdit for ast::Fn {
21 fn get_or_create_where_clause(&self) -> WhereClause {
22 if self.where_clause().is_none() {
23 let position = if let Some(ty) = self.ret_type() {
24 Position::after(ty.syntax().clone())
25 } else if let Some(param_list) = self.param_list() {
26 Position::after(param_list.syntax().clone())
27 } else {
28 Position::last_child_of(self.syntax().clone())
29 };
30 create_where_clause(position)
31 }
32 self.where_clause().unwrap()
33 }
34}
35
36impl GenericParamsOwnerEdit for ast::Impl {
37 fn get_or_create_where_clause(&self) -> WhereClause {
38 if self.where_clause().is_none() {
39 let position = if let Some(items) = self.assoc_item_list() {
40 Position::before(items.syntax().clone())
41 } else {
42 Position::last_child_of(self.syntax().clone())
43 };
44 create_where_clause(position)
45 }
46 self.where_clause().unwrap()
47 }
48}
49
50impl GenericParamsOwnerEdit for ast::Trait {
51 fn get_or_create_where_clause(&self) -> WhereClause {
52 if self.where_clause().is_none() {
53 let position = if let Some(items) = self.assoc_item_list() {
54 Position::before(items.syntax().clone())
55 } else {
56 Position::last_child_of(self.syntax().clone())
57 };
58 create_where_clause(position)
59 }
60 self.where_clause().unwrap()
61 }
62}
63
64impl GenericParamsOwnerEdit for ast::Struct {
65 fn get_or_create_where_clause(&self) -> WhereClause {
66 if self.where_clause().is_none() {
67 let tfl = self.field_list().and_then(|fl| match fl {
68 ast::FieldList::RecordFieldList(_) => None,
69 ast::FieldList::TupleFieldList(it) => Some(it),
70 });
71 let position = if let Some(tfl) = tfl {
72 Position::after(tfl.syntax().clone())
73 } else if let Some(gpl) = self.generic_param_list() {
74 Position::after(gpl.syntax().clone())
75 } else if let Some(name) = self.name() {
76 Position::after(name.syntax().clone())
77 } else {
78 Position::last_child_of(self.syntax().clone())
79 };
80 create_where_clause(position)
81 }
82 self.where_clause().unwrap()
83 }
84}
85
86impl GenericParamsOwnerEdit for ast::Enum {
87 fn get_or_create_where_clause(&self) -> WhereClause {
88 if self.where_clause().is_none() {
89 let position = if let Some(gpl) = self.generic_param_list() {
90 Position::after(gpl.syntax().clone())
91 } else if let Some(name) = self.name() {
92 Position::after(name.syntax().clone())
93 } else {
94 Position::last_child_of(self.syntax().clone())
95 };
96 create_where_clause(position)
97 }
98 self.where_clause().unwrap()
99 }
100}
101
102fn create_where_clause(position: Position) {
103 let where_clause: SyntaxElement =
104 make::where_clause(empty()).clone_for_update().syntax().clone().into();
105 ted::insert(position, where_clause);
106}
107
108impl ast::WhereClause {
109 pub fn add_predicate(&self, predicate: ast::WherePred) {
110 if let Some(pred) = self.predicates().last() {
111 if !pred.syntax().siblings_with_tokens(Direction::Next).any(|it| it.kind() == T![,]) {
112 ted::append_child_raw(self.syntax().clone(), make::token(T![,]));
113 }
114 }
115 ted::append_child(self.syntax().clone(), predicate.syntax().clone())
116 }
117}
118
119impl ast::TypeBoundList {
120 pub fn remove(&self) {
121 if let Some(colon) =
122 self.syntax().siblings_with_tokens(Direction::Prev).find(|it| it.kind() == T![:])
123 {
124 ted::remove_all(colon..=self.syntax().clone().into())
125 } else {
126 ted::remove(self.syntax().clone())
127 }
128 }
129}