aboutsummaryrefslogtreecommitdiff
path: root/crates/libeditor/src/symbols.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-11 10:28:59 +0100
committerAleksey Kladov <[email protected]>2018-08-11 10:28:59 +0100
commit7afd84febc76a75a3ed1be75c57ff35d7b8b3de6 (patch)
tree76eb2de7efc569c39cc721b7be298490b9647e0b /crates/libeditor/src/symbols.rs
parentd5119133fc03694c6644cac9e307d1d496fc9bf2 (diff)
visitor
Diffstat (limited to 'crates/libeditor/src/symbols.rs')
-rw-r--r--crates/libeditor/src/symbols.rs67
1 files changed, 67 insertions, 0 deletions
diff --git a/crates/libeditor/src/symbols.rs b/crates/libeditor/src/symbols.rs
new file mode 100644
index 000000000..3faf96868
--- /dev/null
+++ b/crates/libeditor/src/symbols.rs
@@ -0,0 +1,67 @@
1use libsyntax2::{
2 SyntaxKind, SyntaxNodeRef, SyntaxRoot, AstNode,
3 ast::{self, NameOwner},
4 algo::{
5 visit::{visitor, Visitor},
6 walk::{walk, WalkEvent},
7 },
8};
9use TextRange;
10
11#[derive(Debug)]
12pub struct FileSymbol {
13 pub parent: Option<usize>,
14 pub name: String,
15 pub name_range: TextRange,
16 pub node_range: TextRange,
17 pub kind: SyntaxKind,
18}
19
20
21pub fn file_symbols(file: &ast::File) -> Vec<FileSymbol> {
22 let mut res = Vec::new();
23 let mut stack = Vec::new();
24 let syntax = file.syntax();
25
26 for event in walk(syntax.as_ref()) {
27 match event {
28 WalkEvent::Enter(node) => {
29 match to_symbol(node) {
30 Some(mut symbol) => {
31 symbol.parent = stack.last().map(|&n| n);
32 stack.push(res.len());
33 res.push(symbol);
34 }
35 None => (),
36 }
37 }
38 WalkEvent::Exit(node) => {
39 if to_symbol(node).is_some() {
40 stack.pop().unwrap();
41 }
42 }
43 }
44 }
45 res
46}
47
48fn to_symbol(node: SyntaxNodeRef) -> Option<FileSymbol> {
49 fn decl<'a, N: NameOwner<&'a SyntaxRoot>>(node: N) -> Option<FileSymbol> {
50 let name = node.name()?;
51 Some(FileSymbol {
52 parent: None,
53 name: name.text(),
54 name_range: name.syntax().range(),
55 node_range: node.syntax().range(),
56 kind: node.syntax().kind(),
57 })
58 }
59
60 visitor()
61 .visit(decl::<ast::Function<_>>)
62 .visit(decl::<ast::Struct<_>>)
63 .visit(decl::<ast::Enum<_>>)
64 .visit(decl::<ast::Trait<_>>)
65 .visit(decl::<ast::Module<_>>)
66 .accept(node)?
67}