mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 04:23:25 +00:00
Remove SyntaxRewriter::from_fn
This commit is contained in:
parent
20f82191a0
commit
e6e4417bbb
3 changed files with 24 additions and 31 deletions
|
@ -3,20 +3,27 @@ use hir::{HirDisplay, PathResolution, SemanticsScope};
|
||||||
use ide_db::helpers::mod_path_to_ast;
|
use ide_db::helpers::mod_path_to_ast;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
algo::SyntaxRewriter,
|
|
||||||
ast::{self, AstNode},
|
ast::{self, AstNode},
|
||||||
SyntaxNode,
|
ted, SyntaxNode,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N {
|
pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: &N) {
|
||||||
SyntaxRewriter::from_fn(|element| match element {
|
let mut skip_to = None;
|
||||||
syntax::SyntaxElement::Node(n) => {
|
for event in node.syntax().preorder() {
|
||||||
let replacement = transformer.get_substitution(&n, transformer)?;
|
match event {
|
||||||
Some(replacement.into())
|
syntax::WalkEvent::Enter(node) if skip_to.is_none() => {
|
||||||
|
skip_to = transformer.get_substitution(&node, transformer).zip(Some(node));
|
||||||
|
}
|
||||||
|
syntax::WalkEvent::Enter(_) => (),
|
||||||
|
syntax::WalkEvent::Leave(node) => match &skip_to {
|
||||||
|
Some((replacement, skip_target)) if *skip_target == node => {
|
||||||
|
ted::replace(node, replacement.clone_for_update());
|
||||||
|
skip_to.take();
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
_ => None,
|
}
|
||||||
})
|
|
||||||
.rewrite_ast(&node)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `AstTransform` helps with applying bulk transformations to syntax nodes.
|
/// `AstTransform` helps with applying bulk transformations to syntax nodes.
|
||||||
|
@ -191,11 +198,9 @@ impl<'a> AstTransform<'a> for QualifyPaths<'a> {
|
||||||
let found_path = from.find_use_path(self.source_scope.db.upcast(), def)?;
|
let found_path = from.find_use_path(self.source_scope.db.upcast(), def)?;
|
||||||
let mut path = mod_path_to_ast(&found_path);
|
let mut path = mod_path_to_ast(&found_path);
|
||||||
|
|
||||||
let type_args = p
|
let type_args = p.segment().and_then(|s| s.generic_arg_list());
|
||||||
.segment()
|
|
||||||
.and_then(|s| s.generic_arg_list())
|
|
||||||
.map(|arg_list| apply(recur, arg_list));
|
|
||||||
if let Some(type_args) = type_args {
|
if let Some(type_args) = type_args {
|
||||||
|
apply(recur, &type_args);
|
||||||
let last_segment = path.segment().unwrap();
|
let last_segment = path.segment().unwrap();
|
||||||
path = path.with_segment(last_segment.with_generic_args(type_args))
|
path = path.with_segment(last_segment.with_generic_args(type_args))
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,8 @@ pub fn add_trait_assoc_items_to_impl(
|
||||||
|
|
||||||
let items = items
|
let items = items
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|it| ast_transform::apply(&*ast_transform, it))
|
.map(|it| it.clone_for_update())
|
||||||
|
.inspect(|it| ast_transform::apply(&*ast_transform, it))
|
||||||
.map(|it| match it {
|
.map(|it| match it {
|
||||||
ast::AssocItem::Fn(def) => ast::AssocItem::Fn(add_body(def)),
|
ast::AssocItem::Fn(def) => ast::AssocItem::Fn(add_body(def)),
|
||||||
ast::AssocItem::TypeAlias(def) => ast::AssocItem::TypeAlias(def.remove_bounds()),
|
ast::AssocItem::TypeAlias(def) => ast::AssocItem::TypeAlias(def.remove_bounds()),
|
||||||
|
|
|
@ -342,10 +342,10 @@ enum InsertPos {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct SyntaxRewriter<'a> {
|
pub struct SyntaxRewriter<'a> {
|
||||||
f: Option<Box<dyn Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a>>,
|
|
||||||
//FIXME: add debug_assertions that all elements are in fact from the same file.
|
//FIXME: add debug_assertions that all elements are in fact from the same file.
|
||||||
replacements: FxHashMap<SyntaxElement, Replacement>,
|
replacements: FxHashMap<SyntaxElement, Replacement>,
|
||||||
insertions: IndexMap<InsertPos, Vec<SyntaxElement>>,
|
insertions: IndexMap<InsertPos, Vec<SyntaxElement>>,
|
||||||
|
_pd: std::marker::PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for SyntaxRewriter<'_> {
|
impl fmt::Debug for SyntaxRewriter<'_> {
|
||||||
|
@ -357,14 +357,7 @@ impl fmt::Debug for SyntaxRewriter<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> SyntaxRewriter<'a> {
|
impl SyntaxRewriter<'_> {
|
||||||
pub fn from_fn(f: impl Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a) -> SyntaxRewriter<'a> {
|
|
||||||
SyntaxRewriter {
|
|
||||||
f: Some(Box::new(f)),
|
|
||||||
replacements: FxHashMap::default(),
|
|
||||||
insertions: IndexMap::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn delete<T: Clone + Into<SyntaxElement>>(&mut self, what: &T) {
|
pub fn delete<T: Clone + Into<SyntaxElement>>(&mut self, what: &T) {
|
||||||
let what = what.clone().into();
|
let what = what.clone().into();
|
||||||
let replacement = Replacement::Delete;
|
let replacement = Replacement::Delete;
|
||||||
|
@ -470,7 +463,7 @@ impl<'a> SyntaxRewriter<'a> {
|
||||||
pub fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode {
|
pub fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode {
|
||||||
let _p = profile::span("rewrite");
|
let _p = profile::span("rewrite");
|
||||||
|
|
||||||
if self.f.is_none() && self.replacements.is_empty() && self.insertions.is_empty() {
|
if self.replacements.is_empty() && self.insertions.is_empty() {
|
||||||
return node.clone();
|
return node.clone();
|
||||||
}
|
}
|
||||||
let green = self.rewrite_children(node);
|
let green = self.rewrite_children(node);
|
||||||
|
@ -495,7 +488,6 @@ impl<'a> SyntaxRewriter<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert!(self.f.is_none());
|
|
||||||
self.replacements
|
self.replacements
|
||||||
.keys()
|
.keys()
|
||||||
.filter_map(element_to_node_or_parent)
|
.filter_map(element_to_node_or_parent)
|
||||||
|
@ -510,10 +502,6 @@ impl<'a> SyntaxRewriter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replacement(&self, element: &SyntaxElement) -> Option<Replacement> {
|
fn replacement(&self, element: &SyntaxElement) -> Option<Replacement> {
|
||||||
if let Some(f) = &self.f {
|
|
||||||
assert!(self.replacements.is_empty());
|
|
||||||
return f(element).map(Replacement::Single);
|
|
||||||
}
|
|
||||||
self.replacements.get(element).cloned()
|
self.replacements.get(element).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,7 +562,6 @@ fn element_to_green(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, row
|
||||||
|
|
||||||
impl ops::AddAssign for SyntaxRewriter<'_> {
|
impl ops::AddAssign for SyntaxRewriter<'_> {
|
||||||
fn add_assign(&mut self, rhs: SyntaxRewriter) {
|
fn add_assign(&mut self, rhs: SyntaxRewriter) {
|
||||||
assert!(rhs.f.is_none());
|
|
||||||
self.replacements.extend(rhs.replacements);
|
self.replacements.extend(rhs.replacements);
|
||||||
for (pos, insertions) in rhs.insertions.into_iter() {
|
for (pos, insertions) in rhs.insertions.into_iter() {
|
||||||
match self.insertions.entry(pos) {
|
match self.insertions.entry(pos) {
|
||||||
|
|
Loading…
Reference in a new issue