diff options
Diffstat (limited to 'crates/libanalysis/src/imp.rs')
-rw-r--r-- | crates/libanalysis/src/imp.rs | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/crates/libanalysis/src/imp.rs b/crates/libanalysis/src/imp.rs index 6a6e1e933..f1d72da15 100644 --- a/crates/libanalysis/src/imp.rs +++ b/crates/libanalysis/src/imp.rs | |||
@@ -5,7 +5,7 @@ use std::{ | |||
5 | }, | 5 | }, |
6 | fmt, | 6 | fmt, |
7 | time::Instant, | 7 | time::Instant, |
8 | collections::HashMap, | 8 | collections::{HashMap, HashSet, VecDeque}, |
9 | panic, | 9 | panic, |
10 | }; | 10 | }; |
11 | 11 | ||
@@ -23,7 +23,7 @@ use { | |||
23 | module_map::Problem, | 23 | module_map::Problem, |
24 | symbol_index::FileSymbols, | 24 | symbol_index::FileSymbols, |
25 | module_map::{ModuleMap, ChangeKind}, | 25 | module_map::{ModuleMap, ChangeKind}, |
26 | JobToken, | 26 | JobToken, CrateGraph, CrateId, |
27 | }; | 27 | }; |
28 | 28 | ||
29 | #[derive(Debug)] | 29 | #[derive(Debug)] |
@@ -37,7 +37,6 @@ impl AnalysisHostImpl { | |||
37 | data: Arc::new(WorldData::default()), | 37 | data: Arc::new(WorldData::default()), |
38 | } | 38 | } |
39 | } | 39 | } |
40 | |||
41 | pub fn analysis( | 40 | pub fn analysis( |
42 | &self, | 41 | &self, |
43 | file_resolver: Arc<dyn FileResolver>, | 42 | file_resolver: Arc<dyn FileResolver>, |
@@ -48,7 +47,6 @@ impl AnalysisHostImpl { | |||
48 | data: self.data.clone(), | 47 | data: self.data.clone(), |
49 | } | 48 | } |
50 | } | 49 | } |
51 | |||
52 | pub fn change_files(&mut self, changes: &mut dyn Iterator<Item=(FileId, Option<String>)>) { | 50 | pub fn change_files(&mut self, changes: &mut dyn Iterator<Item=(FileId, Option<String>)>) { |
53 | let data = self.data_mut(); | 51 | let data = self.data_mut(); |
54 | for (file_id, text) in changes { | 52 | for (file_id, text) in changes { |
@@ -71,7 +69,15 @@ impl AnalysisHostImpl { | |||
71 | } | 69 | } |
72 | } | 70 | } |
73 | } | 71 | } |
74 | 72 | pub fn set_crate_graph(&mut self, graph: CrateGraph) { | |
73 | let mut visited = HashSet::new(); | ||
74 | for &file_id in graph.crate_roots.values() { | ||
75 | if !visited.insert(file_id) { | ||
76 | panic!("duplicate crate root: {:?}", file_id); | ||
77 | } | ||
78 | } | ||
79 | self.data_mut().crate_graph = graph; | ||
80 | } | ||
75 | fn data_mut(&mut self) -> &mut WorldData { | 81 | fn data_mut(&mut self) -> &mut WorldData { |
76 | Arc::make_mut(&mut self.data) | 82 | Arc::make_mut(&mut self.data) |
77 | } | 83 | } |
@@ -145,6 +151,33 @@ impl AnalysisImpl { | |||
145 | .collect() | 151 | .collect() |
146 | } | 152 | } |
147 | 153 | ||
154 | pub fn crate_root(&self, id: FileId) -> Vec<CrateId> { | ||
155 | let module_map = &self.data.module_map; | ||
156 | let crate_graph = &self.data.crate_graph; | ||
157 | let mut res = Vec::new(); | ||
158 | let mut work = VecDeque::new(); | ||
159 | work.push_back(id); | ||
160 | let mut visited = HashSet::new(); | ||
161 | while let Some(id) = work.pop_front() { | ||
162 | if let Some(crate_id) = crate_graph.crate_id_for_crate_root(id) { | ||
163 | res.push(crate_id); | ||
164 | continue; | ||
165 | } | ||
166 | let mid = module_map.file2module(id); | ||
167 | let parents = module_map | ||
168 | .parent_module_ids( | ||
169 | mid, | ||
170 | &*self.file_resolver, | ||
171 | &|file_id| self.file_syntax(file_id), | ||
172 | ) | ||
173 | .into_iter() | ||
174 | .map(|id| module_map.module2file(id)) | ||
175 | .filter(|&id| visited.insert(id)); | ||
176 | work.extend(parents); | ||
177 | } | ||
178 | res | ||
179 | } | ||
180 | |||
148 | pub fn approximately_resolve_symbol( | 181 | pub fn approximately_resolve_symbol( |
149 | &self, | 182 | &self, |
150 | id: FileId, | 183 | id: FileId, |
@@ -295,6 +328,7 @@ impl AnalysisImpl { | |||
295 | 328 | ||
296 | #[derive(Clone, Default, Debug)] | 329 | #[derive(Clone, Default, Debug)] |
297 | struct WorldData { | 330 | struct WorldData { |
331 | crate_graph: CrateGraph, | ||
298 | file_map: HashMap<FileId, Arc<FileData>>, | 332 | file_map: HashMap<FileId, Arc<FileData>>, |
299 | module_map: ModuleMap, | 333 | module_map: ModuleMap, |
300 | } | 334 | } |
@@ -356,3 +390,12 @@ impl SourceChange { | |||
356 | } | 390 | } |
357 | } | 391 | } |
358 | } | 392 | } |
393 | |||
394 | impl CrateGraph { | ||
395 | fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { | ||
396 | let (&crate_id, _) = self.crate_roots | ||
397 | .iter() | ||
398 | .find(|(_crate_id, &root_id)| root_id == file_id)?; | ||
399 | Some(crate_id) | ||
400 | } | ||
401 | } | ||