aboutsummaryrefslogtreecommitdiff
path: root/libeditor/src
diff options
context:
space:
mode:
Diffstat (limited to 'libeditor/src')
-rw-r--r--libeditor/src/lib.rs47
1 files changed, 46 insertions, 1 deletions
diff --git a/libeditor/src/lib.rs b/libeditor/src/lib.rs
index 119bdb2d6..091aed125 100644
--- a/libeditor/src/lib.rs
+++ b/libeditor/src/lib.rs
@@ -2,6 +2,7 @@ extern crate libsyntax2;
2extern crate text_unit; 2extern crate text_unit;
3 3
4use libsyntax2::{ 4use libsyntax2::{
5 SyntaxNodeRef,
5 algo::walk, 6 algo::walk,
6 SyntaxKind::*, 7 SyntaxKind::*,
7}; 8};
@@ -16,6 +17,13 @@ pub struct HighlightedRange {
16 pub tag: &'static str, 17 pub tag: &'static str,
17} 18}
18 19
20#[derive(Debug)]
21pub struct Symbol {
22 // pub parent: ???,
23 pub name: String,
24 pub range: TextRange,
25}
26
19impl File { 27impl File {
20 pub fn new(text: &str) -> File { 28 pub fn new(text: &str) -> File {
21 File { 29 File {
@@ -41,7 +49,7 @@ impl File {
41 }; 49 };
42 res.push(HighlightedRange { 50 res.push(HighlightedRange {
43 range: node.range(), 51 range: node.range(),
44 tag 52 tag,
45 }) 53 })
46 } 54 }
47 res 55 res
@@ -50,4 +58,41 @@ impl File {
50 pub fn syntax_tree(&self) -> String { 58 pub fn syntax_tree(&self) -> String {
51 ::libsyntax2::utils::dump_tree(&self.inner.syntax()) 59 ::libsyntax2::utils::dump_tree(&self.inner.syntax())
52 } 60 }
61
62 pub fn symbols(&self) -> Vec<Symbol> {
63 let syntax = self.inner.syntax();
64 let res: Vec<Symbol> = walk::preorder(syntax.as_ref())
65 .filter_map(Declaration::cast)
66 .filter_map(|decl| {
67 let name = decl.name()?;
68 let range = decl.range();
69 Some(Symbol { name, range })
70 })
71 .collect();
72 res // NLL :-(
73 }
74}
75
76
77struct Declaration<'f>(SyntaxNodeRef<'f>);
78
79impl<'f> Declaration<'f> {
80 fn cast(node: SyntaxNodeRef<'f>) -> Option<Declaration<'f>> {
81 match node.kind() {
82 | STRUCT_ITEM | ENUM_ITEM | FN_ITEM | TRAIT_ITEM
83 | CONST_ITEM | STATIC_ITEM | MOD_ITEM | NAMED_FIELD
84 | TYPE_ITEM => Some(Declaration(node)),
85 _ => None
86 }
87 }
88
89 fn name(&self) -> Option<String> {
90 let name = self.0.children()
91 .find(|child| child.kind() == NAME)?;
92 Some(name.text())
93 }
94
95 fn range(&self) -> TextRange {
96 self.0.range()
97 }
53} 98}