2018-08-13 13:24:22 +02:00
|
|
|
use smol_str::SmolStr;
|
2018-08-11 11:28:59 +02:00
|
|
|
use libsyntax2::{
|
|
|
|
SyntaxKind, SyntaxNodeRef, SyntaxRoot, AstNode,
|
|
|
|
ast::{self, NameOwner},
|
|
|
|
algo::{
|
|
|
|
visit::{visitor, Visitor},
|
|
|
|
walk::{walk, WalkEvent},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
use TextRange;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct FileSymbol {
|
|
|
|
pub parent: Option<usize>,
|
2018-08-13 13:24:22 +02:00
|
|
|
pub name: SmolStr,
|
2018-08-11 11:28:59 +02:00
|
|
|
pub name_range: TextRange,
|
|
|
|
pub node_range: TextRange,
|
|
|
|
pub kind: SyntaxKind,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn file_symbols(file: &ast::File) -> Vec<FileSymbol> {
|
|
|
|
let mut res = Vec::new();
|
|
|
|
let mut stack = Vec::new();
|
|
|
|
let syntax = file.syntax();
|
|
|
|
|
|
|
|
for event in walk(syntax.as_ref()) {
|
|
|
|
match event {
|
|
|
|
WalkEvent::Enter(node) => {
|
|
|
|
match to_symbol(node) {
|
|
|
|
Some(mut symbol) => {
|
|
|
|
symbol.parent = stack.last().map(|&n| n);
|
|
|
|
stack.push(res.len());
|
|
|
|
res.push(symbol);
|
|
|
|
}
|
|
|
|
None => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
WalkEvent::Exit(node) => {
|
|
|
|
if to_symbol(node).is_some() {
|
|
|
|
stack.pop().unwrap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
res
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_symbol(node: SyntaxNodeRef) -> Option<FileSymbol> {
|
|
|
|
fn decl<'a, N: NameOwner<&'a SyntaxRoot>>(node: N) -> Option<FileSymbol> {
|
|
|
|
let name = node.name()?;
|
|
|
|
Some(FileSymbol {
|
|
|
|
parent: None,
|
|
|
|
name: name.text(),
|
|
|
|
name_range: name.syntax().range(),
|
|
|
|
node_range: node.syntax().range(),
|
|
|
|
kind: node.syntax().kind(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
visitor()
|
|
|
|
.visit(decl::<ast::Function<_>>)
|
|
|
|
.visit(decl::<ast::Struct<_>>)
|
|
|
|
.visit(decl::<ast::Enum<_>>)
|
|
|
|
.visit(decl::<ast::Trait<_>>)
|
|
|
|
.visit(decl::<ast::Module<_>>)
|
2018-08-11 15:20:37 +02:00
|
|
|
.visit(decl::<ast::TypeItem<_>>)
|
|
|
|
.visit(decl::<ast::ConstItem<_>>)
|
|
|
|
.visit(decl::<ast::StaticItem<_>>)
|
2018-08-11 11:28:59 +02:00
|
|
|
.accept(node)?
|
|
|
|
}
|