aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax
diff options
context:
space:
mode:
Diffstat (limited to 'crates/syntax')
-rw-r--r--crates/syntax/src/ast/edit_in_place.rs64
-rw-r--r--crates/syntax/src/ted.rs7
2 files changed, 71 insertions, 0 deletions
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs
index 529bd0eb1..27350e2b9 100644
--- a/crates/syntax/src/ast/edit_in_place.rs
+++ b/crates/syntax/src/ast/edit_in_place.rs
@@ -14,10 +14,21 @@ use crate::{
14use super::NameOwner; 14use super::NameOwner;
15 15
16pub trait GenericParamsOwnerEdit: ast::GenericParamsOwner + AstNodeEdit { 16pub trait GenericParamsOwnerEdit: ast::GenericParamsOwner + AstNodeEdit {
17 fn get_or_create_generic_param_list(&self) -> ast::GenericParamList;
17 fn get_or_create_where_clause(&self) -> ast::WhereClause; 18 fn get_or_create_where_clause(&self) -> ast::WhereClause;
18} 19}
19 20
20impl GenericParamsOwnerEdit for ast::Fn { 21impl GenericParamsOwnerEdit for ast::Fn {
22 fn get_or_create_generic_param_list(&self) -> ast::GenericParamList {
23 match self.generic_param_list() {
24 Some(it) => it,
25 None => {
26 let position = Position::after(self.name().unwrap().syntax);
27 create_generic_param_list(position)
28 }
29 }
30 }
31
21 fn get_or_create_where_clause(&self) -> WhereClause { 32 fn get_or_create_where_clause(&self) -> WhereClause {
22 if self.where_clause().is_none() { 33 if self.where_clause().is_none() {
23 let position = if let Some(ty) = self.ret_type() { 34 let position = if let Some(ty) = self.ret_type() {
@@ -34,6 +45,16 @@ impl GenericParamsOwnerEdit for ast::Fn {
34} 45}
35 46
36impl GenericParamsOwnerEdit for ast::Impl { 47impl GenericParamsOwnerEdit for ast::Impl {
48 fn get_or_create_generic_param_list(&self) -> ast::GenericParamList {
49 match self.generic_param_list() {
50 Some(it) => it,
51 None => {
52 let position = Position::after(self.impl_token().unwrap());
53 create_generic_param_list(position)
54 }
55 }
56 }
57
37 fn get_or_create_where_clause(&self) -> WhereClause { 58 fn get_or_create_where_clause(&self) -> WhereClause {
38 if self.where_clause().is_none() { 59 if self.where_clause().is_none() {
39 let position = if let Some(items) = self.assoc_item_list() { 60 let position = if let Some(items) = self.assoc_item_list() {
@@ -48,6 +69,10 @@ impl GenericParamsOwnerEdit for ast::Impl {
48} 69}
49 70
50impl GenericParamsOwnerEdit for ast::Trait { 71impl GenericParamsOwnerEdit for ast::Trait {
72 fn get_or_create_generic_param_list(&self) -> ast::GenericParamList {
73 todo!()
74 }
75
51 fn get_or_create_where_clause(&self) -> WhereClause { 76 fn get_or_create_where_clause(&self) -> WhereClause {
52 if self.where_clause().is_none() { 77 if self.where_clause().is_none() {
53 let position = if let Some(items) = self.assoc_item_list() { 78 let position = if let Some(items) = self.assoc_item_list() {
@@ -62,6 +87,10 @@ impl GenericParamsOwnerEdit for ast::Trait {
62} 87}
63 88
64impl GenericParamsOwnerEdit for ast::Struct { 89impl GenericParamsOwnerEdit for ast::Struct {
90 fn get_or_create_generic_param_list(&self) -> ast::GenericParamList {
91 todo!()
92 }
93
65 fn get_or_create_where_clause(&self) -> WhereClause { 94 fn get_or_create_where_clause(&self) -> WhereClause {
66 if self.where_clause().is_none() { 95 if self.where_clause().is_none() {
67 let tfl = self.field_list().and_then(|fl| match fl { 96 let tfl = self.field_list().and_then(|fl| match fl {
@@ -84,6 +113,10 @@ impl GenericParamsOwnerEdit for ast::Struct {
84} 113}
85 114
86impl GenericParamsOwnerEdit for ast::Enum { 115impl GenericParamsOwnerEdit for ast::Enum {
116 fn get_or_create_generic_param_list(&self) -> ast::GenericParamList {
117 todo!()
118 }
119
87 fn get_or_create_where_clause(&self) -> WhereClause { 120 fn get_or_create_where_clause(&self) -> WhereClause {
88 if self.where_clause().is_none() { 121 if self.where_clause().is_none() {
89 let position = if let Some(gpl) = self.generic_param_list() { 122 let position = if let Some(gpl) = self.generic_param_list() {
@@ -104,6 +137,37 @@ fn create_where_clause(position: Position) {
104 ted::insert(position, where_clause.syntax()); 137 ted::insert(position, where_clause.syntax());
105} 138}
106 139
140fn create_generic_param_list(position: Position) -> ast::GenericParamList {
141 let gpl = make::generic_param_list(empty()).clone_for_update();
142 ted::insert_raw(position, gpl.syntax());
143 gpl
144}
145
146impl ast::GenericParamList {
147 pub fn add_generic_param(&self, generic_param: ast::GenericParam) {
148 match self.generic_params().last() {
149 Some(last_param) => {
150 let mut elems = Vec::new();
151 if !last_param
152 .syntax()
153 .siblings_with_tokens(Direction::Next)
154 .any(|it| it.kind() == T![,])
155 {
156 elems.push(make::token(T![,]).into());
157 elems.push(make::tokens::single_space().into());
158 };
159 elems.push(generic_param.syntax().clone().into());
160 let after_last_param = Position::after(last_param.syntax());
161 ted::insert_all(after_last_param, elems);
162 }
163 None => {
164 let after_l_angle = Position::after(self.l_angle_token().unwrap());
165 ted::insert(after_l_angle, generic_param.syntax())
166 }
167 }
168 }
169}
170
107impl ast::WhereClause { 171impl ast::WhereClause {
108 pub fn add_predicate(&self, predicate: ast::WherePred) { 172 pub fn add_predicate(&self, predicate: ast::WherePred) {
109 if let Some(pred) = self.predicates().last() { 173 if let Some(pred) = self.predicates().last() {
diff --git a/crates/syntax/src/ted.rs b/crates/syntax/src/ted.rs
index 177d4ff67..450f2e447 100644
--- a/crates/syntax/src/ted.rs
+++ b/crates/syntax/src/ted.rs
@@ -165,6 +165,13 @@ fn ws_between(left: &SyntaxElement, right: &SyntaxElement) -> Option<SyntaxToken
165 if right.kind() == T![;] || right.kind() == T![,] { 165 if right.kind() == T![;] || right.kind() == T![,] {
166 return None; 166 return None;
167 } 167 }
168 if left.kind() == T![<] || right.kind() == T![>] {
169 return None;
170 }
171 if left.kind() == T![&] && right.kind() == SyntaxKind::LIFETIME {
172 return None;
173 }
174
168 if right.kind() == SyntaxKind::USE { 175 if right.kind() == SyntaxKind::USE {
169 let indent = IndentLevel::from_element(left); 176 let indent = IndentLevel::from_element(left);
170 return Some(make::tokens::whitespace(&format!("\n{}", indent))); 177 return Some(make::tokens::whitespace(&format!("\n{}", indent)));