aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_editor/src/symbols.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_editor/src/symbols.rs')
-rw-r--r--crates/ra_editor/src/symbols.rs34
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 @@
1use crate::TextRange;
2
1use ra_syntax::{ 3use 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};
9use crate::TextRange;
10 11
11#[derive(Debug, Clone)] 12#[derive(Debug, Clone)]
12pub struct StructureNode { 13pub struct StructureNode {
@@ -25,9 +26,7 @@ pub struct FileSymbol {
25} 26}
26 27
27pub fn file_symbols(file: &File) -> Vec<FileSymbol> { 28pub 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
33fn to_symbol(node: SyntaxNodeRef) -> Option<FileSymbol> { 32fn 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
55pub fn file_structure(file: &File) -> Vec<StructureNode> { 53pub 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#"
135struct Foo { 132struct Foo {
136 x: i32 133 x: i32
137} 134}
@@ -148,7 +145,8 @@ const C: i32 = 92;
148impl E {} 145impl E {}
149 146
150impl fmt::Debug for E {} 147impl 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 },