aboutsummaryrefslogtreecommitdiff
path: root/crates/libanalysis/src/imp.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-15 18:29:22 +0100
committerAleksey Kladov <[email protected]>2018-09-15 22:00:05 +0100
commit58674dc3c415142dbdd93b990d9f5b4fe10bef69 (patch)
treed30f60432f96e256d20e805e1f62a3084f61644a /crates/libanalysis/src/imp.rs
parentd59413c895e7b49ed2ad01be35871e417a57a43c (diff)
ModuleTreeDescriptor
Diffstat (limited to 'crates/libanalysis/src/imp.rs')
-rw-r--r--crates/libanalysis/src/imp.rs124
1 files changed, 55 insertions, 69 deletions
diff --git a/crates/libanalysis/src/imp.rs b/crates/libanalysis/src/imp.rs
index 3e65ee14a..8734813f4 100644
--- a/crates/libanalysis/src/imp.rs
+++ b/crates/libanalysis/src/imp.rs
@@ -18,8 +18,8 @@ use libsyntax2::{
18use { 18use {
19 FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit, 19 FileId, FileResolver, Query, Diagnostic, SourceChange, SourceFileEdit, Position, FileSystemEdit,
20 JobToken, CrateGraph, CrateId, 20 JobToken, CrateGraph, CrateId,
21 module_map::{ModuleMap, Problem},
22 roots::{SourceRoot, ReadonlySourceRoot, WritableSourceRoot}, 21 roots::{SourceRoot, ReadonlySourceRoot, WritableSourceRoot},
22 descriptors::{ModuleTreeDescriptor, Problem},
23}; 23};
24 24
25 25
@@ -148,25 +148,24 @@ impl AnalysisImpl {
148 } 148 }
149 pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> { 149 pub fn parent_module(&self, file_id: FileId) -> Vec<(FileId, FileSymbol)> {
150 let root = self.root(file_id); 150 let root = self.root(file_id);
151 let module_map = root.module_map(); 151 let module_tree = root.module_tree();
152 let id = module_map.file2module(file_id); 152 module_tree.parent_modules(file_id)
153 module_map 153 .iter()
154 .parent_modules(id, &|file_id| root.syntax(file_id)) 154 .map(|link| {
155 .into_iter() 155 let file_id = link.owner(&module_tree);
156 .map(|(id, name, node)| { 156 let syntax = root.syntax(file_id);
157 let id = module_map.module2file(id); 157 let decl = link.bind_source(&module_tree, syntax.ast());
158 let sym = FileSymbol { 158 let sym = FileSymbol {
159 name, 159 name: link.name(&module_tree),
160 node_range: node.range(), 160 node_range: decl.syntax().range(),
161 kind: MODULE, 161 kind: MODULE,
162 }; 162 };
163 (id, sym) 163 (file_id, sym)
164 }) 164 })
165 .collect() 165 .collect()
166 } 166 }
167
168 pub fn crate_for(&self, file_id: FileId) -> Vec<CrateId> { 167 pub fn crate_for(&self, file_id: FileId) -> Vec<CrateId> {
169 let module_map = self.root(file_id).module_map(); 168 let module_tree = self.root(file_id).module_tree();
170 let crate_graph = &self.data.crate_graph; 169 let crate_graph = &self.data.crate_graph;
171 let mut res = Vec::new(); 170 let mut res = Vec::new();
172 let mut work = VecDeque::new(); 171 let mut work = VecDeque::new();
@@ -177,11 +176,10 @@ impl AnalysisImpl {
177 res.push(crate_id); 176 res.push(crate_id);
178 continue; 177 continue;
179 } 178 }
180 let mid = module_map.file2module(id); 179 let parents = module_tree
181 let parents = module_map 180 .parent_modules(id)
182 .parent_module_ids(mid, &|file_id| self.file_syntax(file_id))
183 .into_iter() 181 .into_iter()
184 .map(|id| module_map.module2file(id)) 182 .map(|link| link.owner(&module_tree))
185 .filter(|&id| visited.insert(id)); 183 .filter(|&id| visited.insert(id));
186 work.extend(parents); 184 work.extend(parents);
187 } 185 }
@@ -197,7 +195,7 @@ impl AnalysisImpl {
197 token: &JobToken, 195 token: &JobToken,
198 ) -> Vec<(FileId, FileSymbol)> { 196 ) -> Vec<(FileId, FileSymbol)> {
199 let root = self.root(file_id); 197 let root = self.root(file_id);
200 let module_map = root.module_map(); 198 let module_tree = root.module_tree();
201 let file = root.syntax(file_id); 199 let file = root.syntax(file_id);
202 let syntax = file.syntax(); 200 let syntax = file.syntax();
203 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) { 201 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, offset) {
@@ -206,7 +204,7 @@ impl AnalysisImpl {
206 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) { 204 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, offset) {
207 if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { 205 if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) {
208 if module.has_semi() { 206 if module.has_semi() {
209 let file_ids = self.resolve_module(module_map, file_id, module); 207 let file_ids = self.resolve_module(&*module_tree, file_id, module);
210 208
211 let res = file_ids.into_iter().map(|id| { 209 let res = file_ids.into_iter().map(|id| {
212 let name = module.name() 210 let name = module.name()
@@ -229,7 +227,7 @@ impl AnalysisImpl {
229 227
230 pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> { 228 pub fn diagnostics(&self, file_id: FileId) -> Vec<Diagnostic> {
231 let root = self.root(file_id); 229 let root = self.root(file_id);
232 let module_map = root.module_map(); 230 let module_tree = root.module_tree();
233 let syntax = root.syntax(file_id); 231 let syntax = root.syntax(file_id);
234 232
235 let mut res = libeditor::diagnostics(&syntax) 233 let mut res = libeditor::diagnostics(&syntax)
@@ -237,47 +235,43 @@ impl AnalysisImpl {
237 .map(|d| Diagnostic { range: d.range, message: d.msg, fix: None }) 235 .map(|d| Diagnostic { range: d.range, message: d.msg, fix: None })
238 .collect::<Vec<_>>(); 236 .collect::<Vec<_>>();
239 237
240 module_map.problems( 238 for (name_node, problem) in module_tree.problems(file_id, syntax.ast()) {
241 file_id, 239 let diag = match problem {
242 &|file_id| self.file_syntax(file_id), 240 Problem::UnresolvedModule { candidate } => {
243 |name_node, problem| { 241 let create_file = FileSystemEdit::CreateFile {
244 let diag = match problem { 242 anchor: file_id,
245 Problem::UnresolvedModule { candidate } => { 243 path: candidate.clone(),
246 let create_file = FileSystemEdit::CreateFile { 244 };
247 anchor: file_id, 245 let fix = SourceChange {
248 path: candidate.clone(), 246 label: "create module".to_string(),
249 }; 247 source_file_edits: Vec::new(),
250 let fix = SourceChange { 248 file_system_edits: vec![create_file],
251 label: "create module".to_string(), 249 cursor_position: None,
252 source_file_edits: Vec::new(), 250 };
253 file_system_edits: vec![create_file], 251 Diagnostic {
254 cursor_position: None, 252 range: name_node.syntax().range(),
255 }; 253 message: "unresolved module".to_string(),
256 Diagnostic { 254 fix: Some(fix),
257 range: name_node.syntax().range(),
258 message: "unresolved module".to_string(),
259 fix: Some(fix),
260 }
261 } 255 }
262 Problem::NotDirOwner { move_to, candidate } => { 256 }
263 let move_file = FileSystemEdit::MoveFile { file: file_id, path: move_to.clone() }; 257 Problem::NotDirOwner { move_to, candidate } => {
264 let create_file = FileSystemEdit::CreateFile { anchor: file_id, path: move_to.join(candidate) }; 258 let move_file = FileSystemEdit::MoveFile { file: file_id, path: move_to.clone() };
265 let fix = SourceChange { 259 let create_file = FileSystemEdit::CreateFile { anchor: file_id, path: move_to.join(candidate) };
266 label: "move file and create module".to_string(), 260 let fix = SourceChange {
267 source_file_edits: Vec::new(), 261 label: "move file and create module".to_string(),
268 file_system_edits: vec![move_file, create_file], 262 source_file_edits: Vec::new(),
269 cursor_position: None, 263 file_system_edits: vec![move_file, create_file],
270 }; 264 cursor_position: None,
271 Diagnostic { 265 };
272 range: name_node.syntax().range(), 266 Diagnostic {
273 message: "can't declare module at this location".to_string(), 267 range: name_node.syntax().range(),
274 fix: Some(fix), 268 message: "can't declare module at this location".to_string(),
275 } 269 fix: Some(fix),
276 } 270 }
277 }; 271 }
278 res.push(diag) 272 };
279 } 273 res.push(diag)
280 ); 274 }
281 res 275 res
282 } 276 }
283 277
@@ -307,20 +301,12 @@ impl AnalysisImpl {
307 self.world_symbols(query, token) 301 self.world_symbols(query, token)
308 } 302 }
309 303
310 fn resolve_module(&self, module_map: &ModuleMap, file_id: FileId, module: ast::Module) -> Vec<FileId> { 304 fn resolve_module(&self, module_tree: &ModuleTreeDescriptor, file_id: FileId, module: ast::Module) -> Vec<FileId> {
311 let name = match module.name() { 305 let name = match module.name() {
312 Some(name) => name.text(), 306 Some(name) => name.text(),
313 None => return Vec::new(), 307 None => return Vec::new(),
314 }; 308 };
315 let id = module_map.file2module(file_id); 309 module_tree.child_module_by_name(file_id, name.as_str())
316 module_map
317 .child_module_by_name(
318 id, name.as_str(),
319 &|file_id| self.file_syntax(file_id),
320 )
321 .into_iter()
322 .map(|id| module_map.module2file(id))
323 .collect()
324 } 310 }
325 311
326 fn reindex(&self) { 312 fn reindex(&self) {