mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 14:13:58 +00:00
Replace 'postorder' with 'reverse of preorder' to traverse the AST in path_transform
This commit is contained in:
parent
e53792b7cb
commit
872951d2d9
1 changed files with 13 additions and 8 deletions
|
@ -3,6 +3,7 @@
|
||||||
use crate::helpers::mod_path_to_ast;
|
use crate::helpers::mod_path_to_ast;
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir::{AsAssocItem, HirDisplay, ModuleDef, SemanticsScope};
|
use hir::{AsAssocItem, HirDisplay, ModuleDef, SemanticsScope};
|
||||||
|
use itertools::Itertools;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, make, AstNode},
|
ast::{self, make, AstNode},
|
||||||
|
@ -227,11 +228,15 @@ struct Ctx<'a> {
|
||||||
same_self_type: bool,
|
same_self_type: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn postorder(item: &SyntaxNode) -> impl Iterator<Item = SyntaxNode> {
|
fn preorder_rev(item: &SyntaxNode) -> impl Iterator<Item = SyntaxNode> {
|
||||||
item.preorder().filter_map(|event| match event {
|
let x = item
|
||||||
syntax::WalkEvent::Enter(_) => None,
|
.preorder()
|
||||||
syntax::WalkEvent::Leave(node) => Some(node),
|
.filter_map(|event| match event {
|
||||||
})
|
syntax::WalkEvent::Enter(node) => Some(node),
|
||||||
|
syntax::WalkEvent::Leave(_) => None,
|
||||||
|
})
|
||||||
|
.collect_vec();
|
||||||
|
x.into_iter().rev()
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ctx<'_> {
|
impl Ctx<'_> {
|
||||||
|
@ -239,12 +244,12 @@ impl Ctx<'_> {
|
||||||
// `transform_path` may update a node's parent and that would break the
|
// `transform_path` may update a node's parent and that would break the
|
||||||
// tree traversal. Thus all paths in the tree are collected into a vec
|
// tree traversal. Thus all paths in the tree are collected into a vec
|
||||||
// so that such operation is safe.
|
// so that such operation is safe.
|
||||||
let paths = postorder(item).filter_map(ast::Path::cast).collect::<Vec<_>>();
|
let paths = preorder_rev(item).filter_map(ast::Path::cast).collect::<Vec<_>>();
|
||||||
for path in paths {
|
for path in paths {
|
||||||
self.transform_path(path);
|
self.transform_path(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
postorder(item).filter_map(ast::Lifetime::cast).for_each(|lifetime| {
|
preorder_rev(item).filter_map(ast::Lifetime::cast).for_each(|lifetime| {
|
||||||
if let Some(subst) = self.lifetime_substs.get(&lifetime.syntax().text().to_string()) {
|
if let Some(subst) = self.lifetime_substs.get(&lifetime.syntax().text().to_string()) {
|
||||||
ted::replace(lifetime.syntax(), subst.clone_subtree().clone_for_update().syntax());
|
ted::replace(lifetime.syntax(), subst.clone_subtree().clone_for_update().syntax());
|
||||||
}
|
}
|
||||||
|
@ -263,7 +268,7 @@ impl Ctx<'_> {
|
||||||
// `transform_path` may update a node's parent and that would break the
|
// `transform_path` may update a node's parent and that would break the
|
||||||
// tree traversal. Thus all paths in the tree are collected into a vec
|
// tree traversal. Thus all paths in the tree are collected into a vec
|
||||||
// so that such operation is safe.
|
// so that such operation is safe.
|
||||||
let paths = postorder(value).filter_map(ast::Path::cast).collect::<Vec<_>>();
|
let paths = preorder_rev(value).filter_map(ast::Path::cast).collect::<Vec<_>>();
|
||||||
for path in paths {
|
for path in paths {
|
||||||
self.transform_path(path);
|
self.transform_path(path);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue