diff options
author | Aleksey Kladov <[email protected]> | 2021-05-10 17:04:41 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-05-14 14:19:27 +0100 |
commit | 0650f77dd9defaf352f81c5ee4ee73a1eae942b7 (patch) | |
tree | 4758b6ea999292cf18a078dd942f51621a2d68ea /crates/syntax/src/algo.rs | |
parent | ab528e85f71da188722ae031b31a3a70bac1cadd (diff) |
internal: remove one more immutable tree
Diffstat (limited to 'crates/syntax/src/algo.rs')
-rw-r--r-- | crates/syntax/src/algo.rs | 35 |
1 files changed, 4 insertions, 31 deletions
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 3f9b84ab9..825ea3185 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs | |||
@@ -337,7 +337,7 @@ enum InsertPos { | |||
337 | } | 337 | } |
338 | 338 | ||
339 | #[derive(Default)] | 339 | #[derive(Default)] |
340 | pub struct SyntaxRewriter<'a> { | 340 | pub(crate) struct SyntaxRewriter<'a> { |
341 | //FIXME: add debug_assertions that all elements are in fact from the same file. | 341 | //FIXME: add debug_assertions that all elements are in fact from the same file. |
342 | replacements: FxHashMap<SyntaxElement, Replacement>, | 342 | replacements: FxHashMap<SyntaxElement, Replacement>, |
343 | insertions: IndexMap<InsertPos, Vec<SyntaxElement>>, | 343 | insertions: IndexMap<InsertPos, Vec<SyntaxElement>>, |
@@ -354,13 +354,13 @@ impl fmt::Debug for SyntaxRewriter<'_> { | |||
354 | } | 354 | } |
355 | 355 | ||
356 | impl SyntaxRewriter<'_> { | 356 | impl SyntaxRewriter<'_> { |
357 | pub fn replace<T: Clone + Into<SyntaxElement>>(&mut self, what: &T, with: &T) { | 357 | pub(crate) fn replace<T: Clone + Into<SyntaxElement>>(&mut self, what: &T, with: &T) { |
358 | let what = what.clone().into(); | 358 | let what = what.clone().into(); |
359 | let replacement = Replacement::Single(with.clone().into()); | 359 | let replacement = Replacement::Single(with.clone().into()); |
360 | self.replacements.insert(what, replacement); | 360 | self.replacements.insert(what, replacement); |
361 | } | 361 | } |
362 | 362 | ||
363 | pub fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode { | 363 | pub(crate) fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode { |
364 | let _p = profile::span("rewrite"); | 364 | let _p = profile::span("rewrite"); |
365 | 365 | ||
366 | if self.replacements.is_empty() && self.insertions.is_empty() { | 366 | if self.replacements.is_empty() && self.insertions.is_empty() { |
@@ -370,37 +370,10 @@ impl SyntaxRewriter<'_> { | |||
370 | with_green(node, green) | 370 | with_green(node, green) |
371 | } | 371 | } |
372 | 372 | ||
373 | pub fn rewrite_ast<N: AstNode>(self, node: &N) -> N { | 373 | pub(crate) fn rewrite_ast<N: AstNode>(self, node: &N) -> N { |
374 | N::cast(self.rewrite(node.syntax())).unwrap() | 374 | N::cast(self.rewrite(node.syntax())).unwrap() |
375 | } | 375 | } |
376 | 376 | ||
377 | /// Returns a node that encompasses all replacements to be done by this rewriter. | ||
378 | /// | ||
379 | /// Passing the returned node to `rewrite` will apply all replacements queued up in `self`. | ||
380 | /// | ||
381 | /// Returns `None` when there are no replacements. | ||
382 | pub fn rewrite_root(&self) -> Option<SyntaxNode> { | ||
383 | let _p = profile::span("rewrite_root"); | ||
384 | fn element_to_node_or_parent(element: &SyntaxElement) -> Option<SyntaxNode> { | ||
385 | match element { | ||
386 | SyntaxElement::Node(it) => Some(it.clone()), | ||
387 | SyntaxElement::Token(it) => it.parent(), | ||
388 | } | ||
389 | } | ||
390 | |||
391 | self.replacements | ||
392 | .keys() | ||
393 | .filter_map(element_to_node_or_parent) | ||
394 | .chain(self.insertions.keys().filter_map(|pos| match pos { | ||
395 | InsertPos::FirstChildOf(it) => Some(it.clone()), | ||
396 | InsertPos::After(it) => element_to_node_or_parent(it), | ||
397 | })) | ||
398 | // If we only have one replacement/insertion, we must return its parent node, since `rewrite` does | ||
399 | // not replace the node passed to it. | ||
400 | .map(|it| it.parent().unwrap_or(it)) | ||
401 | .fold1(|a, b| least_common_ancestor(&a, &b).unwrap()) | ||
402 | } | ||
403 | |||
404 | fn replacement(&self, element: &SyntaxElement) -> Option<Replacement> { | 377 | fn replacement(&self, element: &SyntaxElement) -> Option<Replacement> { |
405 | self.replacements.get(element).cloned() | 378 | self.replacements.get(element).cloned() |
406 | } | 379 | } |