diff options
Diffstat (limited to 'crates/libanalysis/src/lib.rs')
-rw-r--r-- | crates/libanalysis/src/lib.rs | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/crates/libanalysis/src/lib.rs b/crates/libanalysis/src/lib.rs index e4df3de2e..f0d0cf0a4 100644 --- a/crates/libanalysis/src/lib.rs +++ b/crates/libanalysis/src/lib.rs | |||
@@ -6,6 +6,9 @@ extern crate log; | |||
6 | extern crate once_cell; | 6 | extern crate once_cell; |
7 | extern crate libsyntax2; | 7 | extern crate libsyntax2; |
8 | extern crate libeditor; | 8 | extern crate libeditor; |
9 | extern crate fst; | ||
10 | |||
11 | mod symbol_index; | ||
9 | 12 | ||
10 | use once_cell::sync::OnceCell; | 13 | use once_cell::sync::OnceCell; |
11 | 14 | ||
@@ -14,8 +17,11 @@ use std::{ | |||
14 | collections::hash_map::HashMap, | 17 | collections::hash_map::HashMap, |
15 | path::{PathBuf, Path}, | 18 | path::{PathBuf, Path}, |
16 | }; | 19 | }; |
20 | |||
17 | use libsyntax2::ast; | 21 | use libsyntax2::ast; |
18 | use libeditor::LineIndex; | 22 | use libeditor::{LineIndex, FileSymbol}; |
23 | |||
24 | use self::symbol_index::{FileSymbols, Query}; | ||
19 | 25 | ||
20 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; | 26 | pub type Result<T> = ::std::result::Result<T, ::failure::Error>; |
21 | 27 | ||
@@ -70,12 +76,7 @@ impl WorldState { | |||
70 | impl World { | 76 | impl World { |
71 | pub fn file_syntax(&self, path: &Path) -> Result<ast::File> { | 77 | pub fn file_syntax(&self, path: &Path) -> Result<ast::File> { |
72 | let data = self.file_data(path)?; | 78 | let data = self.file_data(path)?; |
73 | let syntax = data.syntax | 79 | Ok(data.syntax(path).clone()) |
74 | .get_or_init(|| { | ||
75 | trace!("parsing: {}", path.display()); | ||
76 | ast::File::parse(&data.text) | ||
77 | }).clone(); | ||
78 | Ok(syntax) | ||
79 | } | 80 | } |
80 | 81 | ||
81 | pub fn file_line_index(&self, path: &Path) -> Result<LineIndex> { | 82 | pub fn file_line_index(&self, path: &Path) -> Result<LineIndex> { |
@@ -88,6 +89,16 @@ impl World { | |||
88 | Ok(index.clone()) | 89 | Ok(index.clone()) |
89 | } | 90 | } |
90 | 91 | ||
92 | pub fn world_symbols(&self, query: &str, f: &mut FnMut(&Path, &FileSymbol) -> Search) { | ||
93 | let q = Query::new(query); | ||
94 | for (path, data) in self.data.file_map.iter() { | ||
95 | let symbols = data.symbols(path.as_path()); | ||
96 | if q.process(symbols, &mut |symbol| f(path, symbol)) == Search::Break { | ||
97 | break; | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | |||
91 | fn file_data(&self, path: &Path) -> Result<Arc<FileData>> { | 102 | fn file_data(&self, path: &Path) -> Result<Arc<FileData>> { |
92 | match self.data.file_map.get(path) { | 103 | match self.data.file_map.get(path) { |
93 | Some(data) => Ok(data.clone()), | 104 | Some(data) => Ok(data.clone()), |
@@ -96,6 +107,12 @@ impl World { | |||
96 | } | 107 | } |
97 | } | 108 | } |
98 | 109 | ||
110 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | ||
111 | pub enum Search { | ||
112 | Continue, | ||
113 | Break, | ||
114 | } | ||
115 | |||
99 | 116 | ||
100 | #[derive(Default, Debug)] | 117 | #[derive(Default, Debug)] |
101 | struct WorldData { | 118 | struct WorldData { |
@@ -105,6 +122,7 @@ struct WorldData { | |||
105 | #[derive(Debug)] | 122 | #[derive(Debug)] |
106 | struct FileData { | 123 | struct FileData { |
107 | text: String, | 124 | text: String, |
125 | symbols: OnceCell<FileSymbols>, | ||
108 | syntax: OnceCell<ast::File>, | 126 | syntax: OnceCell<ast::File>, |
109 | lines: OnceCell<LineIndex>, | 127 | lines: OnceCell<LineIndex>, |
110 | } | 128 | } |
@@ -113,8 +131,23 @@ impl FileData { | |||
113 | fn new(text: String) -> FileData { | 131 | fn new(text: String) -> FileData { |
114 | FileData { | 132 | FileData { |
115 | text, | 133 | text, |
134 | symbols: OnceCell::new(), | ||
116 | syntax: OnceCell::new(), | 135 | syntax: OnceCell::new(), |
117 | lines: OnceCell::new(), | 136 | lines: OnceCell::new(), |
118 | } | 137 | } |
119 | } | 138 | } |
139 | |||
140 | fn syntax(&self, path: &Path) -> &ast::File { | ||
141 | self.syntax | ||
142 | .get_or_init(|| { | ||
143 | trace!("parsing: {}", path.display()); | ||
144 | ast::File::parse(&self.text) | ||
145 | }) | ||
146 | } | ||
147 | |||
148 | fn symbols(&self, path: &Path) -> &FileSymbols { | ||
149 | let syntax = self.syntax(path); | ||
150 | self.symbols | ||
151 | .get_or_init(|| FileSymbols::new(syntax)) | ||
152 | } | ||
120 | } | 153 | } |