mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 15:15:24 +00:00
organizize
This commit is contained in:
parent
26262aaf05
commit
7c67612b8a
376 changed files with 27 additions and 145 deletions
45
crates/libsyntax2/src/algo/walk.rs
Normal file
45
crates/libsyntax2/src/algo/walk.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
use SyntaxNodeRef;
|
||||
|
||||
pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
|
||||
walk(root).filter_map(|event| match event {
|
||||
WalkEvent::Enter(node) => Some(node),
|
||||
WalkEvent::Exit(_) => None,
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum WalkEvent<'a> {
|
||||
Enter(SyntaxNodeRef<'a>),
|
||||
Exit(SyntaxNodeRef<'a>),
|
||||
}
|
||||
|
||||
pub fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = WalkEvent<'a>> {
|
||||
let mut done = false;
|
||||
::itertools::unfold(WalkEvent::Enter(root), move |pos| {
|
||||
if done {
|
||||
return None;
|
||||
}
|
||||
let res = *pos;
|
||||
*pos = match *pos {
|
||||
WalkEvent::Enter(node) => match node.first_child() {
|
||||
Some(child) => WalkEvent::Enter(child),
|
||||
None => WalkEvent::Exit(node),
|
||||
},
|
||||
WalkEvent::Exit(node) => {
|
||||
if node == root {
|
||||
done = true;
|
||||
WalkEvent::Exit(node)
|
||||
} else {
|
||||
match node.next_sibling() {
|
||||
Some(sibling) => WalkEvent::Enter(sibling),
|
||||
None => match node.parent() {
|
||||
Some(node) => WalkEvent::Exit(node),
|
||||
None => WalkEvent::Exit(node),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Some(res)
|
||||
})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue