aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis/src/imp.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-03 17:46:30 +0100
committerAleksey Kladov <[email protected]>2018-09-03 17:46:30 +0100
commitb04c14d4ad51433b0055e2e5799f98da20d15d58 (patch)
tree18bd67e27c515d48be6725230b274b2eb55c740d /crates/libanalysis/src/imp.rs
parent2f2feef9afe8f1c75f743a56f945a1560ca85af4 (diff)
dispatch acros roots
Diffstat (limited to 'crates/libanalysis/src/imp.rs')
-rw-r--r--crates/libanalysis/src/imp.rs65
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::{
17use { 17use {
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
87impl AnalysisImpl { 91impl 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)]
286struct WorldData { 308struct WorldData {
287 crate_graph: CrateGraph, 309 crate_graph: CrateGraph,
288 root: SourceRoot, 310 root: WritableSourceRoot,
311 libs: Arc<Vec<ReadonlySourceRoot>>,
289} 312}
290 313
291impl SourceChange { 314impl SourceChange {