diff options
author | Aleksey Kladov <[email protected]> | 2018-08-05 17:06:14 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-08-05 17:06:14 +0100 |
commit | 80366e90f5c1b809c8902e42dced42c0dc9d92ac (patch) | |
tree | d0c7c97a47bdb9375325569020290738e859eff7 /libeditor/src/lib.rs | |
parent | 60ba52b3e022aa88b011295b38fcf50fe440d1f9 (diff) |
File symnols
Diffstat (limited to 'libeditor/src/lib.rs')
-rw-r--r-- | libeditor/src/lib.rs | 47 |
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; | |||
2 | extern crate text_unit; | 2 | extern crate text_unit; |
3 | 3 | ||
4 | use libsyntax2::{ | 4 | use 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)] | ||
21 | pub struct Symbol { | ||
22 | // pub parent: ???, | ||
23 | pub name: String, | ||
24 | pub range: TextRange, | ||
25 | } | ||
26 | |||
19 | impl File { | 27 | impl 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 | |||
77 | struct Declaration<'f>(SyntaxNodeRef<'f>); | ||
78 | |||
79 | impl<'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 | } |