diff options
Diffstat (limited to 'crates/syntax/src')
-rw-r--r-- | crates/syntax/src/algo.rs | 19 | ||||
-rw-r--r-- | crates/syntax/src/ast/make.rs | 1 | ||||
-rw-r--r-- | crates/syntax/src/ted.rs | 17 |
3 files changed, 19 insertions, 18 deletions
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index a153a9e1c..c9229c4e0 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs | |||
@@ -342,10 +342,10 @@ enum InsertPos { | |||
342 | 342 | ||
343 | #[derive(Default)] | 343 | #[derive(Default)] |
344 | pub struct SyntaxRewriter<'a> { | 344 | pub struct SyntaxRewriter<'a> { |
345 | f: Option<Box<dyn Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a>>, | ||
346 | //FIXME: add debug_assertions that all elements are in fact from the same file. | 345 | //FIXME: add debug_assertions that all elements are in fact from the same file. |
347 | replacements: FxHashMap<SyntaxElement, Replacement>, | 346 | replacements: FxHashMap<SyntaxElement, Replacement>, |
348 | insertions: IndexMap<InsertPos, Vec<SyntaxElement>>, | 347 | insertions: IndexMap<InsertPos, Vec<SyntaxElement>>, |
348 | _pd: std::marker::PhantomData<&'a ()>, | ||
349 | } | 349 | } |
350 | 350 | ||
351 | impl fmt::Debug for SyntaxRewriter<'_> { | 351 | impl fmt::Debug for SyntaxRewriter<'_> { |
@@ -357,14 +357,7 @@ impl fmt::Debug for SyntaxRewriter<'_> { | |||
357 | } | 357 | } |
358 | } | 358 | } |
359 | 359 | ||
360 | impl<'a> SyntaxRewriter<'a> { | 360 | impl SyntaxRewriter<'_> { |
361 | pub fn from_fn(f: impl Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a) -> SyntaxRewriter<'a> { | ||
362 | SyntaxRewriter { | ||
363 | f: Some(Box::new(f)), | ||
364 | replacements: FxHashMap::default(), | ||
365 | insertions: IndexMap::default(), | ||
366 | } | ||
367 | } | ||
368 | pub fn delete<T: Clone + Into<SyntaxElement>>(&mut self, what: &T) { | 361 | pub fn delete<T: Clone + Into<SyntaxElement>>(&mut self, what: &T) { |
369 | let what = what.clone().into(); | 362 | let what = what.clone().into(); |
370 | let replacement = Replacement::Delete; | 363 | let replacement = Replacement::Delete; |
@@ -470,7 +463,7 @@ impl<'a> SyntaxRewriter<'a> { | |||
470 | pub fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode { | 463 | pub fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode { |
471 | let _p = profile::span("rewrite"); | 464 | let _p = profile::span("rewrite"); |
472 | 465 | ||
473 | if self.f.is_none() && self.replacements.is_empty() && self.insertions.is_empty() { | 466 | if self.replacements.is_empty() && self.insertions.is_empty() { |
474 | return node.clone(); | 467 | return node.clone(); |
475 | } | 468 | } |
476 | let green = self.rewrite_children(node); | 469 | let green = self.rewrite_children(node); |
@@ -495,7 +488,6 @@ impl<'a> SyntaxRewriter<'a> { | |||
495 | } | 488 | } |
496 | } | 489 | } |
497 | 490 | ||
498 | assert!(self.f.is_none()); | ||
499 | self.replacements | 491 | self.replacements |
500 | .keys() | 492 | .keys() |
501 | .filter_map(element_to_node_or_parent) | 493 | .filter_map(element_to_node_or_parent) |
@@ -510,10 +502,6 @@ impl<'a> SyntaxRewriter<'a> { | |||
510 | } | 502 | } |
511 | 503 | ||
512 | fn replacement(&self, element: &SyntaxElement) -> Option<Replacement> { | 504 | fn replacement(&self, element: &SyntaxElement) -> Option<Replacement> { |
513 | if let Some(f) = &self.f { | ||
514 | assert!(self.replacements.is_empty()); | ||
515 | return f(element).map(Replacement::Single); | ||
516 | } | ||
517 | self.replacements.get(element).cloned() | 505 | self.replacements.get(element).cloned() |
518 | } | 506 | } |
519 | 507 | ||
@@ -574,7 +562,6 @@ fn element_to_green(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, row | |||
574 | 562 | ||
575 | impl ops::AddAssign for SyntaxRewriter<'_> { | 563 | impl ops::AddAssign for SyntaxRewriter<'_> { |
576 | fn add_assign(&mut self, rhs: SyntaxRewriter) { | 564 | fn add_assign(&mut self, rhs: SyntaxRewriter) { |
577 | assert!(rhs.f.is_none()); | ||
578 | self.replacements.extend(rhs.replacements); | 565 | self.replacements.extend(rhs.replacements); |
579 | for (pos, insertions) in rhs.insertions.into_iter() { | 566 | for (pos, insertions) in rhs.insertions.into_iter() { |
580 | match self.insertions.entry(pos) { | 567 | match self.insertions.entry(pos) { |
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 222b7e212..42da09606 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs | |||
@@ -632,6 +632,7 @@ pub mod tokens { | |||
632 | SOURCE_FILE | 632 | SOURCE_FILE |
633 | .tree() | 633 | .tree() |
634 | .syntax() | 634 | .syntax() |
635 | .clone_for_update() | ||
635 | .descendants_with_tokens() | 636 | .descendants_with_tokens() |
636 | .filter_map(|it| it.into_token()) | 637 | .filter_map(|it| it.into_token()) |
637 | .find(|it| it.kind() == WHITESPACE && it.text() == "\n\n") | 638 | .find(|it| it.kind() == WHITESPACE && it.text() == "\n\n") |
diff --git a/crates/syntax/src/ted.rs b/crates/syntax/src/ted.rs index 450f2e447..91a06101f 100644 --- a/crates/syntax/src/ted.rs +++ b/crates/syntax/src/ted.rs | |||
@@ -7,7 +7,7 @@ use std::{mem, ops::RangeInclusive}; | |||
7 | use parser::T; | 7 | use parser::T; |
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | ast::{edit::IndentLevel, make}, | 10 | ast::{self, edit::IndentLevel, make, AstNode}, |
11 | SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, | 11 | SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, |
12 | }; | 12 | }; |
13 | 13 | ||
@@ -147,6 +147,16 @@ pub fn append_child_raw(node: &(impl Into<SyntaxNode> + Clone), child: impl Elem | |||
147 | fn ws_before(position: &Position, new: &SyntaxElement) -> Option<SyntaxToken> { | 147 | fn ws_before(position: &Position, new: &SyntaxElement) -> Option<SyntaxToken> { |
148 | let prev = match &position.repr { | 148 | let prev = match &position.repr { |
149 | PositionRepr::FirstChild(_) => return None, | 149 | PositionRepr::FirstChild(_) => return None, |
150 | PositionRepr::After(it) if it.kind() == SyntaxKind::L_CURLY => { | ||
151 | if new.kind() == SyntaxKind::USE { | ||
152 | if let Some(item_list) = it.parent().and_then(ast::ItemList::cast) { | ||
153 | let mut indent = IndentLevel::from_element(&item_list.syntax().clone().into()); | ||
154 | indent.0 += 1; | ||
155 | return Some(make::tokens::whitespace(&format!("\n{}", indent))); | ||
156 | } | ||
157 | } | ||
158 | it | ||
159 | } | ||
150 | PositionRepr::After(it) => it, | 160 | PositionRepr::After(it) => it, |
151 | }; | 161 | }; |
152 | ws_between(prev, new) | 162 | ws_between(prev, new) |
@@ -173,7 +183,10 @@ fn ws_between(left: &SyntaxElement, right: &SyntaxElement) -> Option<SyntaxToken | |||
173 | } | 183 | } |
174 | 184 | ||
175 | if right.kind() == SyntaxKind::USE { | 185 | if right.kind() == SyntaxKind::USE { |
176 | let indent = IndentLevel::from_element(left); | 186 | let mut indent = IndentLevel::from_element(left); |
187 | if left.kind() == SyntaxKind::USE { | ||
188 | indent.0 = IndentLevel::from_element(right).0.max(indent.0); | ||
189 | } | ||
177 | return Some(make::tokens::whitespace(&format!("\n{}", indent))); | 190 | return Some(make::tokens::whitespace(&format!("\n{}", indent))); |
178 | } | 191 | } |
179 | Some(make::tokens::single_space()) | 192 | Some(make::tokens::single_space()) |