From 9f548a02957314819aa0530d01f7c4a27dffdfc8 Mon Sep 17 00:00:00 2001 From: jDomantas Date: Fri, 14 Aug 2020 16:10:52 +0300 Subject: fixup whitespace when adding missing impl items --- crates/syntax/src/ast/edit.rs | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'crates/syntax') diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs index 190746e09..b295b5bc6 100644 --- a/crates/syntax/src/ast/edit.rs +++ b/crates/syntax/src/ast/edit.rs @@ -91,29 +91,56 @@ impl ast::AssocItemList { res = make_multiline(res); } items.into_iter().for_each(|it| res = res.append_item(it)); - res + res.fixup_trailing_whitespace().unwrap_or(res) } #[must_use] pub fn append_item(&self, item: ast::AssocItem) -> ast::AssocItemList { - let (indent, position) = match self.assoc_items().last() { + let (indent, position, whitespace) = match self.assoc_items().last() { Some(it) => ( leading_indent(it.syntax()).unwrap_or_default().to_string(), InsertPosition::After(it.syntax().clone().into()), + "\n\n", ), None => match self.l_curly_token() { Some(it) => ( " ".to_string() + &leading_indent(self.syntax()).unwrap_or_default(), InsertPosition::After(it.into()), + "\n", ), None => return self.clone(), }, }; - let ws = tokens::WsBuilder::new(&format!("\n{}", indent)); + let ws = tokens::WsBuilder::new(&format!("{}{}", whitespace, indent)); let to_insert: ArrayVec<[SyntaxElement; 2]> = [ws.ws().into(), item.syntax().clone().into()].into(); self.insert_children(position, to_insert) } + + /// Remove extra whitespace between last item and closing curly brace. + fn fixup_trailing_whitespace(&self) -> Option { + let first_token_after_items = self + .assoc_items() + .last()? + .syntax() + .next_sibling_or_token()?; + let last_token_before_curly = self + .r_curly_token()? + .prev_sibling_or_token()?; + if last_token_before_curly != first_token_after_items { + // there is something more between last item and + // right curly than just whitespace - bail out + return None; + } + let whitespace = last_token_before_curly + .clone() + .into_token() + .and_then(ast::Whitespace::cast)?; + let text = whitespace.syntax().text(); + let newline = text.rfind("\n")?; + let keep = tokens::WsBuilder::new(&text[newline..]); + Some(self.replace_children(first_token_after_items..=last_token_before_curly, std::iter::once(keep.ws().into()))) + } } impl ast::RecordExprFieldList { -- cgit v1.2.3