diff options
author | Aleksey Kladov <[email protected]> | 2018-09-03 17:46:30 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-09-03 17:46:30 +0100 |
commit | b04c14d4ad51433b0055e2e5799f98da20d15d58 (patch) | |
tree | 18bd67e27c515d48be6725230b274b2eb55c740d /crates/libanalysis/src/imp.rs | |
parent | 2f2feef9afe8f1c75f743a56f945a1560ca85af4 (diff) |
dispatch acros roots
Diffstat (limited to 'crates/libanalysis/src/imp.rs')
-rw-r--r-- | crates/libanalysis/src/imp.rs | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/crates/libanalysis/src/imp.rs b/crates/libanalysis/src/imp.rs index 73a6f4306..c1e144025 100644 --- a/crates/libanalysis/src/imp.rs +++ b/crates/libanalysis/src/imp.rs | |||
@@ -17,8 +17,8 @@ use libsyntax2::{ | |||
17 | use { | 17 | use { |
18 | FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit, | 18 | FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit, |
19 | JobToken, CrateGraph, CrateId, | 19 | JobToken, CrateGraph, CrateId, |
20 | module_map::Problem, | 20 | module_map::{ModuleMap, Problem}, |
21 | roots::SourceRoot, | 21 | roots::{SourceRoot, ReadonlySourceRoot, WritableSourceRoot}, |
22 | }; | 22 | }; |
23 | 23 | ||
24 | #[derive(Debug)] | 24 | #[derive(Debug)] |
@@ -57,6 +57,10 @@ impl AnalysisHostImpl { | |||
57 | } | 57 | } |
58 | self.data_mut().crate_graph = graph; | 58 | self.data_mut().crate_graph = graph; |
59 | } | 59 | } |
60 | pub fn set_libraries(&mut self, libs: impl Iterator<Item=impl Iterator<Item=(FileId, String)>>) { | ||
61 | let libs = libs.map(ReadonlySourceRoot::new).collect::<Vec<_>>(); | ||
62 | self.data_mut().libs = Arc::new(libs); | ||
63 | } | ||
60 | fn data_mut(&mut self) -> &mut WorldData { | 64 | fn data_mut(&mut self) -> &mut WorldData { |
61 | Arc::make_mut(&mut self.data) | 65 | Arc::make_mut(&mut self.data) |
62 | } | 66 | } |
@@ -85,19 +89,33 @@ impl Clone for AnalysisImpl { | |||
85 | } | 89 | } |
86 | 90 | ||
87 | impl AnalysisImpl { | 91 | impl AnalysisImpl { |
92 | fn root(&self, file_id: FileId) -> &SourceRoot { | ||
93 | if self.data.root.contains(file_id) { | ||
94 | return &self.data.root; | ||
95 | } | ||
96 | self.data.libs.iter().find(|it| it.contains(file_id)).unwrap() | ||
97 | } | ||
88 | pub fn file_syntax(&self, file_id: FileId) -> &File { | 98 | pub fn file_syntax(&self, file_id: FileId) -> &File { |
89 | self.data.root.syntax(file_id) | 99 | self.root(file_id).syntax(file_id) |
90 | } | 100 | } |
91 | pub fn file_line_index(&self, file_id: FileId) -> &LineIndex { | 101 | pub fn file_line_index(&self, file_id: FileId) -> &LineIndex { |
92 | self.data.root.lines(file_id) | 102 | self.root(file_id).lines(file_id) |
93 | } | 103 | } |
94 | pub fn world_symbols(&self, query: Query, token: &JobToken) -> Vec<(FileId, FileSymbol)> { | 104 | pub fn world_symbols(&self, query: Query, token: &JobToken) -> Vec<(FileId, FileSymbol)> { |
95 | self.reindex(); | 105 | self.reindex(); |
96 | query.search(&self.data.root.symbols(), token) | 106 | let mut buf = Vec::new(); |
107 | if query.libs { | ||
108 | self.data.libs.iter() | ||
109 | .for_each(|it| it.symbols(&mut buf)); | ||
110 | } else { | ||
111 | self.data.root.symbols(&mut buf); | ||
112 | } | ||
113 | query.search(&buf, token) | ||
114 | |||
97 | } | 115 | } |
98 | pub fn parent_module(&self, id: FileId) -> Vec<(FileId, FileSymbol)> { | 116 | pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { |
99 | let module_map = self.data.root.module_map(); | 117 | let module_map = self.root(file_id).module_map(); |
100 | let id = module_map.file2module(id); | 118 | let id = module_map.file2module(file_id); |
101 | module_map | 119 | module_map |
102 | .parent_modules( | 120 | .parent_modules( |
103 | id, | 121 | id, |
@@ -117,12 +135,12 @@ impl AnalysisImpl { | |||
117 | .collect() | 135 | .collect() |
118 | } | 136 | } |
119 | 137 | ||
120 | pub fn crate_for(&self, id: FileId) -> Vec<CrateId> { | 138 | pub fn crate_for(&self, file_id: FileId) -> Vec<CrateId> { |
121 | let module_map = self.data.root.module_map(); | 139 | let module_map = self.root(file_id).module_map(); |
122 | let crate_graph = &self.data.crate_graph; | 140 | let crate_graph = &self.data.crate_graph; |
123 | let mut res = Vec::new(); | 141 | let mut res = Vec::new(); |
124 | let mut work = VecDeque::new(); | 142 | let mut work = VecDeque::new(); |
125 | work.push_back(id); | 143 | work.push_back(file_id); |
126 | let mut visited = HashSet::new(); | 144 | let mut visited = HashSet::new(); |
127 | while let Some(id) = work.pop_front() { | 145 | while let Some(id) = work.pop_front() { |
128 | if let Some(crate_id) = crate_graph.crate_id_for_crate_root(id) { | 146 | if let Some(crate_id) = crate_graph.crate_id_for_crate_root(id) { |
@@ -148,11 +166,13 @@ impl AnalysisImpl { | |||
148 | } | 166 | } |
149 | pub fn approximately_resolve_symbol( | 167 | pub fn approximately_resolve_symbol( |
150 | &self, | 168 | &self, |
151 | id: FileId, | 169 | file_id: FileId, |
152 | offset: TextUnit, | 170 | offset: TextUnit, |
153 | token: &JobToken, | 171 | token: &JobToken, |
154 | ) -> Vec<(FileId, FileSymbol)> { | 172 | ) -> Vec<(FileId, FileSymbol)> { |
155 | let file = self.file_syntax(id); | 173 | let root = self.root(file_id); |
174 | let module_map = root.module_map(); | ||
175 | let file = root.syntax(file_id); | ||
156 | let syntax = file.syntax(); | 176 | let syntax = file.syntax(); |
157 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { | 177 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { |
158 | return self.index_resolve(name_ref, token); | 178 | return self.index_resolve(name_ref, token); |
@@ -160,7 +180,7 @@ impl AnalysisImpl { | |||
160 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) { | 180 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) { |
161 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { | 181 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { |
162 | if module.has_semi() { | 182 | if module.has_semi() { |
163 | let file_ids = self.resolve_module(id, module); | 183 | let file_ids = self.resolve_module(module_map, file_id, module); |
164 | 184 | ||
165 | let res = file_ids.into_iter().map(|id| { | 185 | let res = file_ids.into_iter().map(|id| { |
166 | let name = module.name() | 186 | let name = module.name() |
@@ -182,13 +202,16 @@ impl AnalysisImpl { | |||
182 | } | 202 | } |
183 | 203 | ||
184 | pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { | 204 | pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { |
185 | let syntax = self.file_syntax(file_id); | 205 | let root = self.root(file_id); |
206 | let module_map = root.module_map(); | ||
207 | let syntax = root.syntax(file_id); | ||
208 | |||
186 | let mut res = libeditor::diagnostics(&syntax) | 209 | let mut res = libeditor::diagnostics(&syntax) |
187 | .into_iter() | 210 | .into_iter() |
188 | .map(|d| Diagnostic { range: d.range, message: d.msg, fix: None }) | 211 | .map(|d| Diagnostic { range: d.range, message: d.msg, fix: None }) |
189 | .collect::<Vec<_>>(); | 212 | .collect::<Vec<_>>(); |
190 | 213 | ||
191 | self.data.root.module_map().problems( | 214 | module_map.problems( |
192 | file_id, | 215 | file_id, |
193 | &*self.file_resolver, | 216 | &*self.file_resolver, |
194 | &|file_id| self.file_syntax(file_id), | 217 | &|file_id| self.file_syntax(file_id), |
@@ -257,13 +280,12 @@ impl AnalysisImpl { | |||
257 | self.world_symbols(query, token) | 280 | self.world_symbols(query, token) |
258 | } | 281 | } |
259 | 282 | ||
260 | fn resolve_module(&self, id: FileId, module: ast::Module) -> Vec<FileId> { | 283 | fn resolve_module(&self, module_map: &ModuleMap, file_id: FileId, module: ast::Module) -> Vec<FileId> { |
261 | let name = match module.name() { | 284 | let name = match module.name() { |
262 | Some(name) => name.text(), | 285 | Some(name) => name.text(), |
263 | None => return Vec::new(), | 286 | None => return Vec::new(), |
264 | }; | 287 | }; |
265 | let module_map = self.data.root.module_map(); | 288 | let id = module_map.file2module(file_id); |
266 | let id = module_map.file2module(id); | ||
267 | module_map | 289 | module_map |
268 | .child_module_by_name( | 290 | .child_module_by_name( |
269 | id, name.as_str(), | 291 | id, name.as_str(), |
@@ -285,7 +307,8 @@ impl AnalysisImpl { | |||
285 | #[derive(Clone, Default, Debug)] | 307 | #[derive(Clone, Default, Debug)] |
286 | struct WorldData { | 308 | struct WorldData { |
287 | crate_graph: CrateGraph, | 309 | crate_graph: CrateGraph, |
288 | root: SourceRoot, | 310 | root: WritableSourceRoot, |
311 | libs: Arc<Vec<ReadonlySourceRoot>>, | ||
289 | } | 312 | } |
290 | 313 | ||
291 | impl SourceChange { | 314 | impl SourceChange { |