diff options
author | Aleksey Kladov <[email protected]> | 2021-05-16 13:10:18 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-05-16 13:10:18 +0100 |
commit | e4a7b44e554e183fc66474bcbd8f7ace541c5536 (patch) | |
tree | e606c6fe7990c468ce58049b3074aa70542ce906 /crates/syntax/src/ast/edit_in_place.rs | |
parent | 4e142757e167ac16ce65ba1c743e131aba83cdc4 (diff) |
internal: use mutable trees when filling match arms
Diffstat (limited to 'crates/syntax/src/ast/edit_in_place.rs')
-rw-r--r-- | crates/syntax/src/ast/edit_in_place.rs | 90 |
1 files changed, 69 insertions, 21 deletions
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs index ca777d057..abab0269a 100644 --- a/crates/syntax/src/ast/edit_in_place.rs +++ b/crates/syntax/src/ast/edit_in_place.rs | |||
@@ -13,7 +13,7 @@ use crate::{ | |||
13 | make, GenericParamsOwner, | 13 | make, GenericParamsOwner, |
14 | }, | 14 | }, |
15 | ted::{self, Position}, | 15 | ted::{self, Position}, |
16 | AstNode, AstToken, Direction, | 16 | AstNode, AstToken, Direction, SyntaxNode, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | use super::NameOwner; | 19 | use super::NameOwner; |
@@ -297,7 +297,7 @@ impl ast::AssocItemList { | |||
297 | ), | 297 | ), |
298 | None => match self.l_curly_token() { | 298 | None => match self.l_curly_token() { |
299 | Some(l_curly) => { | 299 | Some(l_curly) => { |
300 | self.normalize_ws_between_braces(); | 300 | normalize_ws_between_braces(self.syntax()); |
301 | (IndentLevel::from_token(&l_curly) + 1, Position::after(&l_curly), "\n") | 301 | (IndentLevel::from_token(&l_curly) + 1, Position::after(&l_curly), "\n") |
302 | } | 302 | } |
303 | None => (IndentLevel::single(), Position::last_child_of(self.syntax()), "\n"), | 303 | None => (IndentLevel::single(), Position::last_child_of(self.syntax()), "\n"), |
@@ -309,25 +309,6 @@ impl ast::AssocItemList { | |||
309 | ]; | 309 | ]; |
310 | ted::insert_all(position, elements); | 310 | ted::insert_all(position, elements); |
311 | } | 311 | } |
312 | |||
313 | fn normalize_ws_between_braces(&self) -> Option<()> { | ||
314 | let l = self.l_curly_token()?; | ||
315 | let r = self.r_curly_token()?; | ||
316 | let indent = IndentLevel::from_node(self.syntax()); | ||
317 | |||
318 | match l.next_sibling_or_token() { | ||
319 | Some(ws) if ws.kind() == SyntaxKind::WHITESPACE => { | ||
320 | if ws.next_sibling_or_token()?.into_token()? == r { | ||
321 | ted::replace(ws, make::tokens::whitespace(&format!("\n{}", indent))); | ||
322 | } | ||
323 | } | ||
324 | Some(ws) if ws.kind() == T!['}'] => { | ||
325 | ted::insert(Position::after(l), make::tokens::whitespace(&format!("\n{}", indent))); | ||
326 | } | ||
327 | _ => (), | ||
328 | } | ||
329 | Some(()) | ||
330 | } | ||
331 | } | 312 | } |
332 | 313 | ||
333 | impl ast::Fn { | 314 | impl ast::Fn { |
@@ -346,6 +327,73 @@ impl ast::Fn { | |||
346 | } | 327 | } |
347 | } | 328 | } |
348 | 329 | ||
330 | impl ast::MatchArm { | ||
331 | pub fn remove(&self) { | ||
332 | if let Some(sibling) = self.syntax().prev_sibling_or_token() { | ||
333 | if sibling.kind() == SyntaxKind::WHITESPACE { | ||
334 | ted::remove(sibling); | ||
335 | } | ||
336 | } | ||
337 | if let Some(sibling) = self.syntax().next_sibling_or_token() { | ||
338 | if sibling.kind() == T![,] { | ||
339 | ted::remove(sibling); | ||
340 | } | ||
341 | } | ||
342 | ted::remove(self.syntax()); | ||
343 | } | ||
344 | } | ||
345 | |||
346 | impl ast::MatchArmList { | ||
347 | pub fn add_arm(&self, arm: ast::MatchArm) { | ||
348 | normalize_ws_between_braces(self.syntax()); | ||
349 | let position = match self.arms().last() { | ||
350 | Some(last_arm) => { | ||
351 | let curly = last_arm | ||
352 | .syntax() | ||
353 | .siblings_with_tokens(Direction::Next) | ||
354 | .find(|it| it.kind() == T![,]); | ||
355 | Position::after(curly.unwrap_or_else(|| last_arm.syntax().clone().into())) | ||
356 | } | ||
357 | None => match self.l_curly_token() { | ||
358 | Some(it) => Position::after(it), | ||
359 | None => Position::last_child_of(self.syntax()), | ||
360 | }, | ||
361 | }; | ||
362 | let indent = IndentLevel::from_node(self.syntax()) + 1; | ||
363 | let elements = vec![ | ||
364 | make::tokens::whitespace(&format!("\n{}", indent)).into(), | ||
365 | arm.syntax().clone().into(), | ||
366 | ]; | ||
367 | ted::insert_all(position, elements); | ||
368 | } | ||
369 | } | ||
370 | |||
371 | fn normalize_ws_between_braces(node: &SyntaxNode) -> Option<()> { | ||
372 | let l = node | ||
373 | .children_with_tokens() | ||
374 | .filter_map(|it| it.into_token()) | ||
375 | .find(|it| it.kind() == T!['{'])?; | ||
376 | let r = node | ||
377 | .children_with_tokens() | ||
378 | .filter_map(|it| it.into_token()) | ||
379 | .find(|it| it.kind() == T!['}'])?; | ||
380 | |||
381 | let indent = IndentLevel::from_node(node); | ||
382 | |||
383 | match l.next_sibling_or_token() { | ||
384 | Some(ws) if ws.kind() == SyntaxKind::WHITESPACE => { | ||
385 | if ws.next_sibling_or_token()?.into_token()? == r { | ||
386 | ted::replace(ws, make::tokens::whitespace(&format!("\n{}", indent))); | ||
387 | } | ||
388 | } | ||
389 | Some(ws) if ws.kind() == T!['}'] => { | ||
390 | ted::insert(Position::after(l), make::tokens::whitespace(&format!("\n{}", indent))); | ||
391 | } | ||
392 | _ => (), | ||
393 | } | ||
394 | Some(()) | ||
395 | } | ||
396 | |||
349 | #[cfg(test)] | 397 | #[cfg(test)] |
350 | mod tests { | 398 | mod tests { |
351 | use std::fmt; | 399 | use std::fmt; |