From fe3170dc344f73126cd4ff2f197d49a8b7f2fe1f Mon Sep 17 00:00:00 2001 From: Aleksei Sidorov Date: Thu, 3 Sep 2020 01:32:18 +0300 Subject: Initial implementation of the #5085 issue --- crates/syntax/src/ast/edit.rs | 66 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'crates/syntax/src/ast/edit.rs') diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs index 823475333..1ccb4de6a 100644 --- a/crates/syntax/src/ast/edit.rs +++ b/crates/syntax/src/ast/edit.rs @@ -459,6 +459,72 @@ impl ast::MatchArmList { } } +impl ast::GenericParamList { + #[must_use] + pub fn append_params(&self, params: impl IntoIterator) -> Self { + let mut res = self.clone(); + params.into_iter().for_each(|it| res = res.append_param(it)); + res + } + + #[must_use] + pub fn append_param(&self, item: ast::GenericParam) -> Self { + let is_multiline = self.syntax().text().contains_char('\n'); + let ws; + let space = if is_multiline { + ws = tokens::WsBuilder::new(&format!( + "\n{} ", + leading_indent(self.syntax()).unwrap_or_default() + )); + ws.ws() + } else { + tokens::single_space() + }; + + let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new(); + to_insert.push(space.into()); + to_insert.push(item.syntax().clone().into()); + to_insert.push(make::token(T![,]).into()); + + macro_rules! after_l_angle { + () => {{ + let anchor = match self.l_angle_token() { + Some(it) => it.into(), + None => return self.clone(), + }; + InsertPosition::After(anchor) + }}; + } + + macro_rules! after_field { + ($anchor:expr) => { + if let Some(comma) = $anchor + .syntax() + .siblings_with_tokens(Direction::Next) + .find(|it| it.kind() == T![,]) + { + InsertPosition::After(comma) + } else { + to_insert.insert(0, make::token(T![,]).into()); + InsertPosition::After($anchor.syntax().clone().into()) + } + }; + }; + + if !is_multiline { + // don't insert comma before angle + to_insert.pop(); + } + + let position = match self.generic_params().last() { + Some(it) => after_field!(it), + None => after_l_angle!(), + }; + + self.insert_children(position, to_insert) + } +} + #[must_use] pub fn remove_attrs_and_docs(node: &N) -> N { N::cast(remove_attrs_and_docs_inner(node.syntax().clone())).unwrap() -- cgit v1.2.3 From 7259cc82f362bd1cd00f47ff3ffc71be769162b6 Mon Sep 17 00:00:00 2001 From: Aleksei Sidorov Date: Thu, 3 Sep 2020 14:46:28 +0300 Subject: Resolve most of corner cases --- crates/syntax/src/ast/edit.rs | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'crates/syntax/src/ast/edit.rs') diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs index 1ccb4de6a..68987dbf6 100644 --- a/crates/syntax/src/ast/edit.rs +++ b/crates/syntax/src/ast/edit.rs @@ -13,7 +13,7 @@ use crate::{ ast::{ self, make::{self, tokens}, - AstNode, TypeBoundsOwner, + AstNode, GenericParamsOwner, NameOwner, TypeBoundsOwner, }, AstToken, Direction, InsertPosition, SmolStr, SyntaxElement, SyntaxKind, SyntaxKind::{ATTR, COMMENT, WHITESPACE}, @@ -46,6 +46,19 @@ impl ast::Fn { to_insert.push(body.syntax().clone().into()); self.replace_children(single_node(old_body_or_semi), to_insert) } + + #[must_use] + pub fn with_generic_params(&self, generic_args: ast::GenericParamList) -> ast::Fn { + if let Some(old) = self.generic_param_list() { + return self.replace_descendant(old, generic_args); + } + + let anchor = self.name().expect("The function must have a name").syntax().clone(); + + let mut to_insert: ArrayVec<[SyntaxElement; 1]> = ArrayVec::new(); + to_insert.push(generic_args.syntax().clone().into()); + self.insert_children(InsertPosition::After(anchor.into()), to_insert) + } } fn make_multiline(node: N) -> N @@ -461,14 +474,17 @@ impl ast::MatchArmList { impl ast::GenericParamList { #[must_use] - pub fn append_params(&self, params: impl IntoIterator) -> Self { + pub fn append_params( + &self, + params: impl IntoIterator, + ) -> ast::GenericParamList { let mut res = self.clone(); params.into_iter().for_each(|it| res = res.append_param(it)); res } #[must_use] - pub fn append_param(&self, item: ast::GenericParam) -> Self { + pub fn append_param(&self, item: ast::GenericParam) -> ast::GenericParamList { let is_multiline = self.syntax().text().contains_char('\n'); let ws; let space = if is_multiline { @@ -482,7 +498,9 @@ impl ast::GenericParamList { }; let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new(); - to_insert.push(space.into()); + if self.generic_params().next().is_some() { + to_insert.push(space.into()); + } to_insert.push(item.syntax().clone().into()); to_insert.push(make::token(T![,]).into()); -- cgit v1.2.3 From 477fa75cfbdc923be366c75cb03b1e352f63c8e8 Mon Sep 17 00:00:00 2001 From: Aleksei Sidorov Date: Fri, 4 Sep 2020 15:24:36 +0300 Subject: Fix nitpicks --- crates/syntax/src/ast/edit.rs | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) (limited to 'crates/syntax/src/ast/edit.rs') diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs index 68987dbf6..5b5454c72 100644 --- a/crates/syntax/src/ast/edit.rs +++ b/crates/syntax/src/ast/edit.rs @@ -48,7 +48,7 @@ impl ast::Fn { } #[must_use] - pub fn with_generic_params(&self, generic_args: ast::GenericParamList) -> ast::Fn { + pub fn with_generic_param_list(&self, generic_args: ast::GenericParamList) -> ast::Fn { if let Some(old) = self.generic_param_list() { return self.replace_descendant(old, generic_args); } @@ -485,17 +485,7 @@ impl ast::GenericParamList { #[must_use] pub fn append_param(&self, item: ast::GenericParam) -> ast::GenericParamList { - let is_multiline = self.syntax().text().contains_char('\n'); - let ws; - let space = if is_multiline { - ws = tokens::WsBuilder::new(&format!( - "\n{} ", - leading_indent(self.syntax()).unwrap_or_default() - )); - ws.ws() - } else { - tokens::single_space() - }; + let space = tokens::single_space(); let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new(); if self.generic_params().next().is_some() { @@ -529,11 +519,6 @@ impl ast::GenericParamList { }; }; - if !is_multiline { - // don't insert comma before angle - to_insert.pop(); - } - let position = match self.generic_params().last() { Some(it) => after_field!(it), None => after_l_angle!(), -- cgit v1.2.3 From e1b8d836a9b64169a8337be674c78cac20940b92 Mon Sep 17 00:00:00 2001 From: Aleksei Sidorov Date: Fri, 4 Sep 2020 22:58:50 +0300 Subject: Remove unnecessary comma --- crates/syntax/src/ast/edit.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'crates/syntax/src/ast/edit.rs') diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs index 5b5454c72..8b1c65dd6 100644 --- a/crates/syntax/src/ast/edit.rs +++ b/crates/syntax/src/ast/edit.rs @@ -492,7 +492,6 @@ impl ast::GenericParamList { to_insert.push(space.into()); } to_insert.push(item.syntax().clone().into()); - to_insert.push(make::token(T![,]).into()); macro_rules! after_l_angle { () => {{ -- cgit v1.2.3