From 73123a7550a667ebc42be96651a8e36be482a828 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 14 May 2021 16:40:11 +0300 Subject: [PATCH] internal: remove SyntaxRewriter --- crates/ide_db/src/helpers/merge_imports.rs | 4 +- crates/syntax/src/algo.rs | 106 +-------------------- crates/syntax/src/ast/edit.rs | 51 +--------- 3 files changed, 7 insertions(+), 154 deletions(-) diff --git a/crates/ide_db/src/helpers/merge_imports.rs b/crates/ide_db/src/helpers/merge_imports.rs index 475ef99b573..8fb40e8371f 100644 --- a/crates/ide_db/src/helpers/merge_imports.rs +++ b/crates/ide_db/src/helpers/merge_imports.rs @@ -42,10 +42,12 @@ pub fn try_merge_imports( return None; } + let lhs = lhs.clone_subtree().clone_for_update(); let lhs_tree = lhs.use_tree()?; let rhs_tree = rhs.use_tree()?; let merged = try_merge_trees(&lhs_tree, &rhs_tree, merge_behavior)?; - Some(lhs.with_use_tree(merged).clone_for_update()) + ted::replace(lhs_tree.syntax(), merged.syntax()); + Some(lhs) } pub fn try_merge_trees( diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 825ea318589..241713c48ee 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs @@ -1,6 +1,6 @@ //! FIXME: write short doc here -use std::{fmt, hash::BuildHasherDefault, ops::RangeInclusive}; +use std::{hash::BuildHasherDefault, ops::RangeInclusive}; use indexmap::IndexMap; use itertools::Itertools; @@ -330,110 +330,6 @@ fn _replace_children( with_children(parent, new_children) } -#[derive(Debug, PartialEq, Eq, Hash)] -enum InsertPos { - FirstChildOf(SyntaxNode), - After(SyntaxElement), -} - -#[derive(Default)] -pub(crate) struct SyntaxRewriter<'a> { - //FIXME: add debug_assertions that all elements are in fact from the same file. - replacements: FxHashMap, - insertions: IndexMap>, - _pd: std::marker::PhantomData<&'a ()>, -} - -impl fmt::Debug for SyntaxRewriter<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("SyntaxRewriter") - .field("replacements", &self.replacements) - .field("insertions", &self.insertions) - .finish() - } -} - -impl SyntaxRewriter<'_> { - pub(crate) fn replace>(&mut self, what: &T, with: &T) { - let what = what.clone().into(); - let replacement = Replacement::Single(with.clone().into()); - self.replacements.insert(what, replacement); - } - - pub(crate) fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode { - let _p = profile::span("rewrite"); - - if self.replacements.is_empty() && self.insertions.is_empty() { - return node.clone(); - } - let green = self.rewrite_children(node); - with_green(node, green) - } - - pub(crate) fn rewrite_ast(self, node: &N) -> N { - N::cast(self.rewrite(node.syntax())).unwrap() - } - - fn replacement(&self, element: &SyntaxElement) -> Option { - self.replacements.get(element).cloned() - } - - fn insertions(&self, pos: &InsertPos) -> Option + '_> { - self.insertions.get(pos).map(|insertions| insertions.iter().cloned()) - } - - fn rewrite_children(&self, node: &SyntaxNode) -> rowan::GreenNode { - let _p = profile::span("rewrite_children"); - - // FIXME: this could be made much faster. - let mut new_children = Vec::new(); - if let Some(elements) = self.insertions(&InsertPos::FirstChildOf(node.clone())) { - new_children.extend(elements.map(element_to_green)); - } - for child in node.children_with_tokens() { - self.rewrite_self(&mut new_children, &child); - } - - rowan::GreenNode::new(rowan::SyntaxKind(node.kind() as u16), new_children) - } - - fn rewrite_self( - &self, - acc: &mut Vec>, - element: &SyntaxElement, - ) { - let _p = profile::span("rewrite_self"); - - if let Some(replacement) = self.replacement(&element) { - match replacement { - Replacement::Single(element) => acc.push(element_to_green(element)), - }; - } else { - match element { - NodeOrToken::Token(it) => acc.push(NodeOrToken::Token(it.green().to_owned())), - NodeOrToken::Node(it) => { - acc.push(NodeOrToken::Node(self.rewrite_children(it))); - } - } - } - if let Some(elements) = self.insertions(&InsertPos::After(element.clone())) { - acc.extend(elements.map(element_to_green)); - } - } -} - -fn element_to_green(element: SyntaxElement) -> NodeOrToken { - match element { - NodeOrToken::Node(it) => NodeOrToken::Node(it.green().into_owned()), - NodeOrToken::Token(it) => NodeOrToken::Token(it.green().to_owned()), - } -} - -#[derive(Clone, Debug)] -enum Replacement { - Single(SyntaxElement), -} - fn with_children( parent: &SyntaxNode, new_children: Vec>, diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs index 78c0dc1021b..10ec94cd2c3 100644 --- a/crates/syntax/src/ast/edit.rs +++ b/crates/syntax/src/ast/edit.rs @@ -2,18 +2,18 @@ //! immutable, all function here return a fresh copy of the tree, instead of //! doing an in-place modification. use std::{ - array, fmt, iter, + fmt, iter, ops::{self, RangeInclusive}, }; use arrayvec::ArrayVec; use crate::{ - algo::{self, SyntaxRewriter}, + algo, ast::{ self, make::{self, tokens}, - AstNode, GenericParamsOwner, NameOwner, TypeBoundsOwner, + AstNode, TypeBoundsOwner, }, ted, AstToken, Direction, InsertPosition, NodeOrToken, SmolStr, SyntaxElement, SyntaxKind, SyntaxKind::{ATTR, COMMENT, WHITESPACE}, @@ -46,18 +46,6 @@ pub fn with_body(&self, body: ast::BlockExpr) -> ast::Fn { to_insert.push(body.syntax().clone().into()); self.replace_children(single_node(old_body_or_semi), to_insert) } - - #[must_use] - pub fn with_generic_param_list(&self, generic_args: ast::GenericParamList) -> ast::Fn { - if let Some(old) = self.generic_param_list() { - return self.replace_descendant(old, generic_args); - } - - let anchor = self.name().expect("The function must have a name").syntax().clone(); - - let to_insert = [generic_args.syntax().clone().into()]; - self.insert_children(InsertPosition::After(anchor.into()), array::IntoIter::new(to_insert)) - } } fn make_multiline(node: N) -> N @@ -313,33 +301,7 @@ fn _with_generic_args(&self, type_args: ast::GenericArgList, turbo: bool) -> ast } } -impl ast::Use { - #[must_use] - pub fn with_use_tree(&self, use_tree: ast::UseTree) -> ast::Use { - if let Some(old) = self.use_tree() { - return self.replace_descendant(old, use_tree); - } - self.clone() - } -} - impl ast::UseTree { - #[must_use] - pub fn with_path(&self, path: ast::Path) -> ast::UseTree { - if let Some(old) = self.path() { - return self.replace_descendant(old, path); - } - self.clone() - } - - #[must_use] - pub fn with_use_tree_list(&self, use_tree_list: ast::UseTreeList) -> ast::UseTree { - if let Some(old) = self.use_tree_list() { - return self.replace_descendant(old, use_tree_list); - } - self.clone() - } - /// Splits off the given prefix, making it the path component of the use tree, appending the rest of the path to all UseTreeList items. #[must_use] pub fn split_prefix(&self, prefix: &ast::Path) -> ast::UseTree { @@ -664,13 +626,6 @@ fn replace_children( let new_syntax = algo::replace_children(self.syntax(), to_replace, to_insert); Self::cast(new_syntax).unwrap() } - - #[must_use] - fn replace_descendant(&self, old: D, new: D) -> Self { - let mut rewriter = SyntaxRewriter::default(); - rewriter.replace(old.syntax(), new.syntax()); - rewriter.rewrite_ast(self) - } fn indent_level(&self) -> IndentLevel { IndentLevel::from_node(self.syntax()) }