Replace 'postorder' with 'reverse of preorder' to traverse the AST in path_transform

This commit is contained in:
roife 2024-01-06 20:07:38 +08:00
parent e53792b7cb
commit 872951d2d9

View file

@ -3,6 +3,7 @@
use crate::helpers::mod_path_to_ast;
use either::Either;
use hir::{AsAssocItem, HirDisplay, ModuleDef, SemanticsScope};
use itertools::Itertools;
use rustc_hash::FxHashMap;
use syntax::{
ast::{self, make, AstNode},
@ -227,11 +228,15 @@ struct Ctx<'a> {
same_self_type: bool,
}
fn postorder(item: &SyntaxNode) -> impl Iterator<Item = SyntaxNode> {
item.preorder().filter_map(|event| match event {
syntax::WalkEvent::Enter(_) => None,
syntax::WalkEvent::Leave(node) => Some(node),
})
fn preorder_rev(item: &SyntaxNode) -> impl Iterator<Item = SyntaxNode> {
let x = item
.preorder()
.filter_map(|event| match event {
syntax::WalkEvent::Enter(node) => Some(node),
syntax::WalkEvent::Leave(_) => None,
})
.collect_vec();
x.into_iter().rev()
}
impl Ctx<'_> {
@ -239,12 +244,12 @@ impl Ctx<'_> {
// `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
// 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 {
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()) {
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
// tree traversal. Thus all paths in the tree are collected into a vec
// 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 {
self.transform_path(path);
}