aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-05-14 18:01:05 +0100
committerGitHub <[email protected]>2021-05-14 18:01:05 +0100
commit6c0f20d79f8e5da57bd907aa1c3324fb92344b9a (patch)
tree0abf081283df9de4bb1318396b007d8fc9f93adf
parenta32589f773be2c19e6b6307b5302d07ec3ab6db6 (diff)
parent883dd1568f3f1824b88a136e69248c7e7d476e7e (diff)
Merge #8838
8838: internal: use more mutable APIs r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r--crates/ide_assists/src/utils.rs34
-rw-r--r--crates/syntax/src/ast/edit.rs36
-rw-r--r--crates/syntax/src/ast/edit_in_place.rs16
3 files changed, 33 insertions, 53 deletions
diff --git a/crates/ide_assists/src/utils.rs b/crates/ide_assists/src/utils.rs
index 7d562d1d4..fc7caee04 100644
--- a/crates/ide_assists/src/utils.rs
+++ b/crates/ide_assists/src/utils.rs
@@ -17,7 +17,7 @@ use syntax::{
17 ast::AttrsOwner, 17 ast::AttrsOwner,
18 ast::NameOwner, 18 ast::NameOwner,
19 ast::{self, edit, make, ArgListOwner, GenericParamsOwner}, 19 ast::{self, edit, make, ArgListOwner, GenericParamsOwner},
20 AstNode, Direction, SmolStr, 20 ted, AstNode, Direction, SmolStr,
21 SyntaxKind::*, 21 SyntaxKind::*,
22 SyntaxNode, TextSize, T, 22 SyntaxNode, TextSize, T,
23}; 23};
@@ -139,34 +139,32 @@ pub fn add_trait_assoc_items_to_impl(
139 .into_iter() 139 .into_iter()
140 .map(|it| it.clone_for_update()) 140 .map(|it| it.clone_for_update())
141 .inspect(|it| ast_transform::apply(&*ast_transform, it)) 141 .inspect(|it| ast_transform::apply(&*ast_transform, it))
142 .map(|it| match it {
143 ast::AssocItem::Fn(def) => ast::AssocItem::Fn(add_body(def)),
144 ast::AssocItem::TypeAlias(def) => ast::AssocItem::TypeAlias(def.remove_bounds()),
145 _ => it,
146 })
147 .map(|it| edit::remove_attrs_and_docs(&it).clone_subtree().clone_for_update()); 142 .map(|it| edit::remove_attrs_and_docs(&it).clone_subtree().clone_for_update());
148 143
149 let res = impl_.clone_for_update(); 144 let res = impl_.clone_for_update();
145
150 let assoc_item_list = res.get_or_create_assoc_item_list(); 146 let assoc_item_list = res.get_or_create_assoc_item_list();
151 let mut first_item = None; 147 let mut first_item = None;
152 for item in items { 148 for item in items {
153 if first_item.is_none() { 149 first_item.get_or_insert_with(|| item.clone());
154 first_item = Some(item.clone()) 150 match &item {
155 } 151 ast::AssocItem::Fn(fn_) if fn_.body().is_none() => {
156 assoc_item_list.add_item(item)
157 }
158 return (res, first_item.unwrap());
159
160 fn add_body(fn_def: ast::Fn) -> ast::Fn {
161 match fn_def.body() {
162 Some(_) => fn_def,
163 None => {
164 let body = make::block_expr(None, Some(make::ext::expr_todo())) 152 let body = make::block_expr(None, Some(make::ext::expr_todo()))
165 .indent(edit::IndentLevel(1)); 153 .indent(edit::IndentLevel(1));
166 fn_def.with_body(body) 154 ted::replace(fn_.get_or_create_body().syntax(), body.clone_for_update().syntax())
167 } 155 }
156 ast::AssocItem::TypeAlias(type_alias) => {
157 if let Some(type_bound_list) = type_alias.type_bound_list() {
158 type_bound_list.remove()
159 }
160 }
161 _ => {}
168 } 162 }
163
164 assoc_item_list.add_item(item)
169 } 165 }
166
167 (res, first_item.unwrap())
170} 168}
171 169
172#[derive(Clone, Copy, Debug)] 170#[derive(Clone, Copy, Debug)]
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs
index 7e4b8252e..4b5f5c571 100644
--- a/crates/syntax/src/ast/edit.rs
+++ b/crates/syntax/src/ast/edit.rs
@@ -13,7 +13,7 @@ use crate::{
13 ast::{ 13 ast::{
14 self, 14 self,
15 make::{self, tokens}, 15 make::{self, tokens},
16 AstNode, TypeBoundsOwner, 16 AstNode,
17 }, 17 },
18 ted, AstToken, Direction, InsertPosition, NodeOrToken, SmolStr, SyntaxElement, SyntaxKind, 18 ted, AstToken, Direction, InsertPosition, NodeOrToken, SmolStr, SyntaxElement, SyntaxKind,
19 SyntaxKind::{ATTR, COMMENT, WHITESPACE}, 19 SyntaxKind::{ATTR, COMMENT, WHITESPACE},
@@ -29,25 +29,6 @@ impl ast::BinExpr {
29 } 29 }
30} 30}
31 31
32impl ast::Fn {
33 #[must_use]
34 pub fn with_body(&self, body: ast::BlockExpr) -> ast::Fn {
35 let mut to_insert: ArrayVec<SyntaxElement, 2> = ArrayVec::new();
36 let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() {
37 old_body.syntax().clone().into()
38 } else if let Some(semi) = self.semicolon_token() {
39 to_insert.push(make::tokens::single_space().into());
40 semi.into()
41 } else {
42 to_insert.push(make::tokens::single_space().into());
43 to_insert.push(body.syntax().clone().into());
44 return self.insert_children(InsertPosition::Last, to_insert);
45 };
46 to_insert.push(body.syntax().clone().into());
47 self.replace_children(single_node(old_body_or_semi), to_insert)
48 }
49}
50
51fn make_multiline<N>(node: N) -> N 32fn make_multiline<N>(node: N) -> N
52where 33where
53 N: AstNode + Clone, 34 N: AstNode + Clone,
@@ -156,21 +137,6 @@ impl ast::RecordExprFieldList {
156 } 137 }
157} 138}
158 139
159impl ast::TypeAlias {
160 #[must_use]
161 pub fn remove_bounds(&self) -> ast::TypeAlias {
162 let colon = match self.colon_token() {
163 Some(it) => it,
164 None => return self.clone(),
165 };
166 let end = match self.type_bound_list() {
167 Some(it) => it.syntax().clone().into(),
168 None => colon.clone().into(),
169 };
170 self.replace_children(colon.into()..=end, iter::empty())
171 }
172}
173
174impl ast::Path { 140impl ast::Path {
175 #[must_use] 141 #[must_use]
176 pub fn with_segment(&self, segment: ast::PathSegment) -> ast::Path { 142 pub fn with_segment(&self, segment: ast::PathSegment) -> ast::Path {
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs
index 9812e00c9..ca777d057 100644
--- a/crates/syntax/src/ast/edit_in_place.rs
+++ b/crates/syntax/src/ast/edit_in_place.rs
@@ -330,6 +330,22 @@ impl ast::AssocItemList {
330 } 330 }
331} 331}
332 332
333impl ast::Fn {
334 pub fn get_or_create_body(&self) -> ast::BlockExpr {
335 if self.body().is_none() {
336 let body = make::ext::empty_block_expr().clone_for_update();
337 match self.semicolon_token() {
338 Some(semi) => {
339 ted::replace(semi, body.syntax());
340 ted::insert(Position::before(body.syntax), make::tokens::single_space());
341 }
342 None => ted::append_child(self.syntax(), body.syntax()),
343 }
344 }
345 self.body().unwrap()
346 }
347}
348
333#[cfg(test)] 349#[cfg(test)]
334mod tests { 350mod tests {
335 use std::fmt; 351 use std::fmt;