diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index ee89d986705..5696c014fb6 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs @@ -476,7 +476,8 @@ pub fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode { if self.f.is_none() && self.replacements.is_empty() && self.insertions.is_empty() { return node.clone(); } - self.rewrite_children(node) + let green = self.rewrite_children(node); + with_green(node, green) } pub fn rewrite_ast(self, node: &N) -> N { @@ -523,7 +524,7 @@ fn insertions(&self, pos: &InsertPos) -> Option SyntaxNode { + fn rewrite_children(&self, node: &SyntaxNode) -> rowan::GreenNode { let _p = profile::span("rewrite_children"); // FIXME: this could be made much faster. @@ -534,7 +535,8 @@ fn rewrite_children(&self, node: &SyntaxNode) -> SyntaxNode { for child in node.children_with_tokens() { self.rewrite_self(&mut new_children, &child); } - with_children(node, new_children) + + rowan::GreenNode::new(rowan::SyntaxKind(node.kind() as u16), new_children) } fn rewrite_self( @@ -556,7 +558,7 @@ fn rewrite_self( match element { NodeOrToken::Token(it) => acc.push(NodeOrToken::Token(it.green().clone())), NodeOrToken::Node(it) => { - acc.push(NodeOrToken::Node(self.rewrite_children(it).green().clone())); + acc.push(NodeOrToken::Node(self.rewrite_children(it))); } } } @@ -601,14 +603,18 @@ fn with_children( ) -> SyntaxNode { let _p = profile::span("with_children"); - let len = new_children.iter().map(|it| it.text_len()).sum::(); - let new_node = rowan::GreenNode::new(rowan::SyntaxKind(parent.kind() as u16), new_children); - let new_root_node = parent.replace_with(new_node); + let new_green = rowan::GreenNode::new(rowan::SyntaxKind(parent.kind() as u16), new_children); + with_green(parent, new_green) +} + +fn with_green(syntax_node: &SyntaxNode, green: rowan::GreenNode) -> SyntaxNode { + let len = green.children().map(|it| it.text_len()).sum::(); + let new_root_node = syntax_node.replace_with(green); let new_root_node = SyntaxNode::new_root(new_root_node); // FIXME: use a more elegant way to re-fetch the node (#1185), make // `range` private afterwards - let mut ptr = SyntaxNodePtr::new(parent); + let mut ptr = SyntaxNodePtr::new(syntax_node); ptr.range = TextRange::at(ptr.range.start(), len); ptr.to_node(&new_root_node) }