diff options
Diffstat (limited to 'crates/syntax/src/ast/edit.rs')
-rw-r--r-- | crates/syntax/src/ast/edit.rs | 100 |
1 files changed, 2 insertions, 98 deletions
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs index 5e6c1d44e..61952377f 100644 --- a/crates/syntax/src/ast/edit.rs +++ b/crates/syntax/src/ast/edit.rs | |||
@@ -10,12 +10,8 @@ use arrayvec::ArrayVec; | |||
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | algo, | 12 | algo, |
13 | ast::{ | 13 | ast::{self, make, AstNode}, |
14 | self, | 14 | ted, AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxKind, |
15 | make::{self, tokens}, | ||
16 | AstNode, | ||
17 | }, | ||
18 | ted, AstToken, Direction, InsertPosition, NodeOrToken, SmolStr, SyntaxElement, SyntaxKind, | ||
19 | SyntaxKind::{ATTR, COMMENT, WHITESPACE}, | 15 | SyntaxKind::{ATTR, COMMENT, WHITESPACE}, |
20 | SyntaxNode, SyntaxToken, T, | 16 | SyntaxNode, SyntaxToken, T, |
21 | }; | 17 | }; |
@@ -29,82 +25,6 @@ impl ast::BinExpr { | |||
29 | } | 25 | } |
30 | } | 26 | } |
31 | 27 | ||
32 | impl ast::RecordExprFieldList { | ||
33 | #[must_use] | ||
34 | pub fn append_field(&self, field: &ast::RecordExprField) -> ast::RecordExprFieldList { | ||
35 | self.insert_field(InsertPosition::Last, field) | ||
36 | } | ||
37 | |||
38 | #[must_use] | ||
39 | pub fn insert_field( | ||
40 | &self, | ||
41 | position: InsertPosition<&'_ ast::RecordExprField>, | ||
42 | field: &ast::RecordExprField, | ||
43 | ) -> ast::RecordExprFieldList { | ||
44 | let is_multiline = self.syntax().text().contains_char('\n'); | ||
45 | let ws; | ||
46 | let space = if is_multiline { | ||
47 | ws = tokens::WsBuilder::new(&format!( | ||
48 | "\n{} ", | ||
49 | leading_indent(self.syntax()).unwrap_or_default() | ||
50 | )); | ||
51 | ws.ws() | ||
52 | } else { | ||
53 | tokens::single_space() | ||
54 | }; | ||
55 | |||
56 | let mut to_insert: ArrayVec<SyntaxElement, 4> = ArrayVec::new(); | ||
57 | to_insert.push(space.into()); | ||
58 | to_insert.push(field.syntax().clone().into()); | ||
59 | to_insert.push(make::token(T![,]).into()); | ||
60 | |||
61 | macro_rules! after_l_curly { | ||
62 | () => {{ | ||
63 | let anchor = match self.l_curly_token() { | ||
64 | Some(it) => it.into(), | ||
65 | None => return self.clone(), | ||
66 | }; | ||
67 | InsertPosition::After(anchor) | ||
68 | }}; | ||
69 | } | ||
70 | |||
71 | macro_rules! after_field { | ||
72 | ($anchor:expr) => { | ||
73 | if let Some(comma) = $anchor | ||
74 | .syntax() | ||
75 | .siblings_with_tokens(Direction::Next) | ||
76 | .find(|it| it.kind() == T![,]) | ||
77 | { | ||
78 | InsertPosition::After(comma) | ||
79 | } else { | ||
80 | to_insert.insert(0, make::token(T![,]).into()); | ||
81 | InsertPosition::After($anchor.syntax().clone().into()) | ||
82 | } | ||
83 | }; | ||
84 | } | ||
85 | |||
86 | let position = match position { | ||
87 | InsertPosition::First => after_l_curly!(), | ||
88 | InsertPosition::Last => { | ||
89 | if !is_multiline { | ||
90 | // don't insert comma before curly | ||
91 | to_insert.pop(); | ||
92 | } | ||
93 | match self.fields().last() { | ||
94 | Some(it) => after_field!(it), | ||
95 | None => after_l_curly!(), | ||
96 | } | ||
97 | } | ||
98 | InsertPosition::Before(anchor) => { | ||
99 | InsertPosition::Before(anchor.syntax().clone().into()) | ||
100 | } | ||
101 | InsertPosition::After(anchor) => after_field!(anchor), | ||
102 | }; | ||
103 | |||
104 | self.insert_children(position, to_insert) | ||
105 | } | ||
106 | } | ||
107 | |||
108 | impl ast::Path { | 28 | impl ast::Path { |
109 | #[must_use] | 29 | #[must_use] |
110 | pub fn with_segment(&self, segment: ast::PathSegment) -> ast::Path { | 30 | pub fn with_segment(&self, segment: ast::PathSegment) -> ast::Path { |
@@ -308,22 +228,6 @@ impl IndentLevel { | |||
308 | } | 228 | } |
309 | } | 229 | } |
310 | 230 | ||
311 | // FIXME: replace usages with IndentLevel above | ||
312 | fn leading_indent(node: &SyntaxNode) -> Option<SmolStr> { | ||
313 | for token in prev_tokens(node.first_token()?) { | ||
314 | if let Some(ws) = ast::Whitespace::cast(token.clone()) { | ||
315 | let ws_text = ws.text(); | ||
316 | if let Some(pos) = ws_text.rfind('\n') { | ||
317 | return Some(ws_text[pos + 1..].into()); | ||
318 | } | ||
319 | } | ||
320 | if token.text().contains('\n') { | ||
321 | break; | ||
322 | } | ||
323 | } | ||
324 | None | ||
325 | } | ||
326 | |||
327 | fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> { | 231 | fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> { |
328 | iter::successors(Some(token), |token| token.prev_token()) | 232 | iter::successors(Some(token), |token| token.prev_token()) |
329 | } | 233 | } |