mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-23 11:54:25 +00:00
internal: remove one more immutable tree
This commit is contained in:
parent
ab528e85f7
commit
0650f77dd9
7 changed files with 57 additions and 56 deletions
|
@ -337,7 +337,7 @@ enum InsertPos {
|
|||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SyntaxRewriter<'a> {
|
||||
pub(crate) struct SyntaxRewriter<'a> {
|
||||
//FIXME: add debug_assertions that all elements are in fact from the same file.
|
||||
replacements: FxHashMap<SyntaxElement, Replacement>,
|
||||
insertions: IndexMap<InsertPos, Vec<SyntaxElement>>,
|
||||
|
@ -354,13 +354,13 @@ impl fmt::Debug for SyntaxRewriter<'_> {
|
|||
}
|
||||
|
||||
impl SyntaxRewriter<'_> {
|
||||
pub fn replace<T: Clone + Into<SyntaxElement>>(&mut self, what: &T, with: &T) {
|
||||
pub(crate) fn replace<T: Clone + Into<SyntaxElement>>(&mut self, what: &T, with: &T) {
|
||||
let what = what.clone().into();
|
||||
let replacement = Replacement::Single(with.clone().into());
|
||||
self.replacements.insert(what, replacement);
|
||||
}
|
||||
|
||||
pub fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode {
|
||||
pub(crate) fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode {
|
||||
let _p = profile::span("rewrite");
|
||||
|
||||
if self.replacements.is_empty() && self.insertions.is_empty() {
|
||||
|
@ -370,37 +370,10 @@ impl SyntaxRewriter<'_> {
|
|||
with_green(node, green)
|
||||
}
|
||||
|
||||
pub fn rewrite_ast<N: AstNode>(self, node: &N) -> N {
|
||||
pub(crate) fn rewrite_ast<N: AstNode>(self, node: &N) -> N {
|
||||
N::cast(self.rewrite(node.syntax())).unwrap()
|
||||
}
|
||||
|
||||
/// Returns a node that encompasses all replacements to be done by this rewriter.
|
||||
///
|
||||
/// Passing the returned node to `rewrite` will apply all replacements queued up in `self`.
|
||||
///
|
||||
/// Returns `None` when there are no replacements.
|
||||
pub fn rewrite_root(&self) -> Option<SyntaxNode> {
|
||||
let _p = profile::span("rewrite_root");
|
||||
fn element_to_node_or_parent(element: &SyntaxElement) -> Option<SyntaxNode> {
|
||||
match element {
|
||||
SyntaxElement::Node(it) => Some(it.clone()),
|
||||
SyntaxElement::Token(it) => it.parent(),
|
||||
}
|
||||
}
|
||||
|
||||
self.replacements
|
||||
.keys()
|
||||
.filter_map(element_to_node_or_parent)
|
||||
.chain(self.insertions.keys().filter_map(|pos| match pos {
|
||||
InsertPos::FirstChildOf(it) => Some(it.clone()),
|
||||
InsertPos::After(it) => element_to_node_or_parent(it),
|
||||
}))
|
||||
// If we only have one replacement/insertion, we must return its parent node, since `rewrite` does
|
||||
// not replace the node passed to it.
|
||||
.map(|it| it.parent().unwrap_or(it))
|
||||
.fold1(|a, b| least_common_ancestor(&a, &b).unwrap())
|
||||
}
|
||||
|
||||
fn replacement(&self, element: &SyntaxElement) -> Option<Replacement> {
|
||||
self.replacements.get(element).cloned()
|
||||
}
|
||||
|
|
|
@ -47,6 +47,12 @@ pub trait AstNode {
|
|||
{
|
||||
Self::cast(self.syntax().clone_for_update()).unwrap()
|
||||
}
|
||||
fn clone_subtree(&self) -> Self
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
Self::cast(self.syntax().clone_subtree()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Like `AstNode`, but wraps tokens rather than interior nodes.
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
use itertools::Itertools;
|
||||
use stdx::{format_to, never};
|
||||
|
||||
use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken};
|
||||
use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxToken};
|
||||
|
||||
/// While the parent module defines basic atomic "constructors", the `ext`
|
||||
/// module defines shortcuts for common things.
|
||||
|
@ -601,17 +601,11 @@ fn ast_from_text<N: AstNode>(text: &str) -> N {
|
|||
panic!("Failed to make ast node `{}` from text {}", std::any::type_name::<N>(), text)
|
||||
}
|
||||
};
|
||||
let node = node.syntax().clone();
|
||||
let node = unroot(node);
|
||||
let node = N::cast(node).unwrap();
|
||||
let node = node.clone_subtree();
|
||||
assert_eq!(node.syntax().text_range().start(), 0.into());
|
||||
node
|
||||
}
|
||||
|
||||
fn unroot(n: SyntaxNode) -> SyntaxNode {
|
||||
SyntaxNode::new_root(n.green().into())
|
||||
}
|
||||
|
||||
pub fn token(kind: SyntaxKind) -> SyntaxToken {
|
||||
tokens::SOURCE_FILE
|
||||
.tree()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue