diff options
Diffstat (limited to 'crates/ra_editor/src/symbols.rs')
-rw-r--r-- | crates/ra_editor/src/symbols.rs | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/crates/ra_editor/src/symbols.rs b/crates/ra_editor/src/symbols.rs index d9e4b2df7..b768b34bc 100644 --- a/crates/ra_editor/src/symbols.rs +++ b/crates/ra_editor/src/symbols.rs | |||
@@ -1,12 +1,13 @@ | |||
1 | use crate::TextRange; | ||
2 | |||
1 | use ra_syntax::{ | 3 | use ra_syntax::{ |
2 | SyntaxKind, SyntaxNodeRef, AstNode, File, SmolStr, | ||
3 | ast::{self, NameOwner}, | ||
4 | algo::{ | 4 | algo::{ |
5 | visit::{visitor, Visitor}, | 5 | visit::{visitor, Visitor}, |
6 | walk::{walk, WalkEvent}, | 6 | walk::{walk, WalkEvent}, |
7 | }, | 7 | }, |
8 | ast::{self, NameOwner}, | ||
9 | AstNode, File, SmolStr, SyntaxKind, SyntaxNodeRef, | ||
8 | }; | 10 | }; |
9 | use crate::TextRange; | ||
10 | 11 | ||
11 | #[derive(Debug, Clone)] | 12 | #[derive(Debug, Clone)] |
12 | pub struct StructureNode { | 13 | pub struct StructureNode { |
@@ -25,9 +26,7 @@ pub struct FileSymbol { | |||
25 | } | 26 | } |
26 | 27 | ||
27 | pub fn file_symbols(file: &File) -> Vec<FileSymbol> { | 28 | pub fn file_symbols(file: &File) -> Vec<FileSymbol> { |
28 | file.syntax().descendants() | 29 | file.syntax().descendants().filter_map(to_symbol).collect() |
29 | .filter_map(to_symbol) | ||
30 | .collect() | ||
31 | } | 30 | } |
32 | 31 | ||
33 | fn to_symbol(node: SyntaxNodeRef) -> Option<FileSymbol> { | 32 | fn to_symbol(node: SyntaxNodeRef) -> Option<FileSymbol> { |
@@ -51,23 +50,20 @@ fn to_symbol(node: SyntaxNodeRef) -> Option<FileSymbol> { | |||
51 | .accept(node)? | 50 | .accept(node)? |
52 | } | 51 | } |
53 | 52 | ||
54 | |||
55 | pub fn file_structure(file: &File) -> Vec<StructureNode> { | 53 | pub fn file_structure(file: &File) -> Vec<StructureNode> { |
56 | let mut res = Vec::new(); | 54 | let mut res = Vec::new(); |
57 | let mut stack = Vec::new(); | 55 | let mut stack = Vec::new(); |
58 | 56 | ||
59 | for event in walk(file.syntax()) { | 57 | for event in walk(file.syntax()) { |
60 | match event { | 58 | match event { |
61 | WalkEvent::Enter(node) => { | 59 | WalkEvent::Enter(node) => match structure_node(node) { |
62 | match structure_node(node) { | 60 | Some(mut symbol) => { |
63 | Some(mut symbol) => { | 61 | symbol.parent = stack.last().map(|&n| n); |
64 | symbol.parent = stack.last().map(|&n| n); | 62 | stack.push(res.len()); |
65 | stack.push(res.len()); | 63 | res.push(symbol); |
66 | res.push(symbol); | ||
67 | } | ||
68 | None => (), | ||
69 | } | 64 | } |
70 | } | 65 | None => (), |
66 | }, | ||
71 | WalkEvent::Exit(node) => { | 67 | WalkEvent::Exit(node) => { |
72 | if structure_node(node).is_some() { | 68 | if structure_node(node).is_some() { |
73 | stack.pop().unwrap(); | 69 | stack.pop().unwrap(); |
@@ -131,7 +127,8 @@ mod tests { | |||
131 | 127 | ||
132 | #[test] | 128 | #[test] |
133 | fn test_file_structure() { | 129 | fn test_file_structure() { |
134 | let file = File::parse(r#" | 130 | let file = File::parse( |
131 | r#" | ||
135 | struct Foo { | 132 | struct Foo { |
136 | x: i32 | 133 | x: i32 |
137 | } | 134 | } |
@@ -148,7 +145,8 @@ const C: i32 = 92; | |||
148 | impl E {} | 145 | impl E {} |
149 | 146 | ||
150 | impl fmt::Debug for E {} | 147 | impl fmt::Debug for E {} |
151 | "#); | 148 | "#, |
149 | ); | ||
152 | let symbols = file_structure(&file); | 150 | let symbols = file_structure(&file); |
153 | assert_eq_dbg( | 151 | assert_eq_dbg( |
154 | r#"[StructureNode { parent: None, label: "Foo", navigation_range: [8; 11), node_range: [1; 26), kind: STRUCT_DEF }, | 152 | r#"[StructureNode { parent: None, label: "Foo", navigation_range: [8; 11), node_range: [1; 26), kind: STRUCT_DEF }, |